From 30fdf1140b8d1ce93f3821d986fa165552023440 Mon Sep 17 00:00:00 2001 From: lgao4 Date: Fri, 17 Jul 2009 09:10:31 +0000 Subject: Check In tool source code based on Build tool project revision r1655. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8964 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Source/Python/Common/MigrationUtilities.py | 567 +++++++++++++++++++++ 1 file changed, 567 insertions(+) create mode 100644 BaseTools/Source/Python/Common/MigrationUtilities.py (limited to 'BaseTools/Source/Python/Common/MigrationUtilities.py') diff --git a/BaseTools/Source/Python/Common/MigrationUtilities.py b/BaseTools/Source/Python/Common/MigrationUtilities.py new file mode 100644 index 0000000000..8573f0b692 --- /dev/null +++ b/BaseTools/Source/Python/Common/MigrationUtilities.py @@ -0,0 +1,567 @@ +## @file +# Contains several utilitities shared by migration tools. +# +# Copyright (c) 2007, 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 os +import re +import EdkLogger +from optparse import OptionParser +from Common.BuildToolError import * +from XmlRoutines import * +from CommonDataClass.CommonClass import * + +## Set all fields of CommonClass object. +# +# Set all attributes of CommonClass object from XML Dom object of XmlCommon. +# +# @param Common The destine CommonClass object. +# @param XmlCommon The source XML Dom object. +# +def SetCommon(Common, XmlCommon): + XmlTag = "Usage" + Common.Usage = XmlAttribute(XmlCommon, XmlTag).split() + + XmlTag = "FeatureFlag" + Common.FeatureFlag = XmlAttribute(XmlCommon, XmlTag) + + XmlTag = "SupArchList" + Common.SupArchList = XmlAttribute(XmlCommon, XmlTag).split() + + XmlTag = XmlNodeName(XmlCommon) + "/" + "HelpText" + Common.HelpText = XmlElement(XmlCommon, XmlTag) + + +## Set some fields of CommonHeaderClass object. +# +# Set Name, Guid, FileName and FullPath fields of CommonHeaderClass object from +# XML Dom object of XmlCommonHeader, NameTag and FileName. +# +# @param CommonHeader The destine CommonClass object. +# @param XmlCommonHeader The source XML Dom object. +# @param NameTag The name tag in XML Dom object. +# @param FileName The file name of the XML file. +# +def SetIdentification(CommonHeader, XmlCommonHeader, NameTag, FileName): + XmlParentTag = XmlNodeName(XmlCommonHeader) + + XmlTag = XmlParentTag + "/" + NameTag + CommonHeader.Name = XmlElement(XmlCommonHeader, XmlTag) + + XmlTag = XmlParentTag + "/" + "GuidValue" + CommonHeader.Guid = XmlElement(XmlCommonHeader, XmlTag) + + XmlTag = XmlParentTag + "/" + "Version" + CommonHeader.Version = XmlElement(XmlCommonHeader, XmlTag) + + CommonHeader.FileName = os.path.basename(FileName) + CommonHeader.FullPath = os.path.abspath(FileName) + + +## Regular expression to match specification and value. +mReSpecification = re.compile(r"(?P\w+)\s+(?P\w*)") + +## Add specification to specification dictionary. +# +# Abstract specification name, value pair from Specification String and add them +# to specification dictionary. +# +# @param SpecificationDict The destine Specification dictionary. +# @param SpecificationString The source Specification String from which the +# specification name and value pair is abstracted. +# +def AddToSpecificationDict(SpecificationDict, SpecificationString): + """Abstract specification name, value pair from Specification String""" + for SpecificationMatch in mReSpecification.finditer(SpecificationString): + Specification = SpecificationMatch.group("Specification") + Value = SpecificationMatch.group("Value") + SpecificationDict[Specification] = Value + +## Set all fields of CommonHeaderClass object. +# +# Set all attributes of CommonHeaderClass object from XML Dom object of +# XmlCommonHeader, NameTag and FileName. +# +# @param CommonHeader The destine CommonClass object. +# @param XmlCommonHeader The source XML Dom object. +# @param NameTag The name tag in XML Dom object. +# @param FileName The file name of the XML file. +# +def SetCommonHeader(CommonHeader, XmlCommonHeader): + """Set all attributes of CommonHeaderClass object from XmlCommonHeader""" + XmlParent = XmlNodeName(XmlCommonHeader) + + XmlTag = XmlParent + "/" + "Abstract" + CommonHeader.Abstract = XmlElement(XmlCommonHeader, XmlTag) + + XmlTag = XmlParent + "/" + "Description" + CommonHeader.Description = XmlElement(XmlCommonHeader, XmlTag) + + XmlTag = XmlParent + "/" + "Copyright" + CommonHeader.Copyright = XmlElement(XmlCommonHeader, XmlTag) + + XmlTag = XmlParent + "/" + "License" + CommonHeader.License = XmlElement(XmlCommonHeader, XmlTag) + + XmlTag = XmlParent + "/" + "Specification" + Specification = XmlElement(XmlCommonHeader, XmlTag) + + AddToSpecificationDict(CommonHeader.Specification, Specification) + + XmlTag = XmlParent + "/" + "ModuleType" + CommonHeader.ModuleType = XmlElement(XmlCommonHeader, XmlTag) + + +## Load a new Cloned Record class object. +# +# Read an input XML ClonedRecord DOM object and return an object of Cloned Record +# contained in the DOM object. +# +# @param XmlCloned A child XML DOM object in a Common XML DOM. +# +# @retvel ClonedRecord A new Cloned Record object created by XmlCloned. +# +def LoadClonedRecord(XmlCloned): + ClonedRecord = ClonedRecordClass() + + XmlTag = "Id" + ClonedRecord.Id = int(XmlAttribute(XmlCloned, XmlTag)) + + XmlTag = "FarGuid" + ClonedRecord.FarGuid = XmlAttribute(XmlCloned, XmlTag) + + XmlTag = "Cloned/PackageGuid" + ClonedRecord.PackageGuid = XmlElement(XmlCloned, XmlTag) + + XmlTag = "Cloned/PackageVersion" + ClonedRecord.PackageVersion = XmlElement(XmlCloned, XmlTag) + + XmlTag = "Cloned/ModuleGuid" + ClonedRecord.ModuleGuid = XmlElement(XmlCloned, XmlTag) + + XmlTag = "Cloned/ModuleVersion" + ClonedRecord.ModuleVersion = XmlElement(XmlCloned, XmlTag) + + return ClonedRecord + + +## Load a new Guid/Protocol/Ppi common class object. +# +# Read an input XML Guid/Protocol/Ppi DOM object and return an object of +# Guid/Protocol/Ppi contained in the DOM object. +# +# @param XmlGuidProtocolPpiCommon A child XML DOM object in a Common XML DOM. +# +# @retvel GuidProtocolPpiCommon A new GuidProtocolPpiCommon class object +# created by XmlGuidProtocolPpiCommon. +# +def LoadGuidProtocolPpiCommon(XmlGuidProtocolPpiCommon): + GuidProtocolPpiCommon = GuidProtocolPpiCommonClass() + + XmlTag = "Name" + GuidProtocolPpiCommon.Name = XmlAttribute(XmlGuidProtocolPpiCommon, XmlTag) + + XmlParent = XmlNodeName(XmlGuidProtocolPpiCommon) + if XmlParent == "Entry": + XmlTag = "%s/C_Name" % XmlParent + elif XmlParent == "GuidCNames": + XmlTag = "%s/GuidCName" % XmlParent + else: + XmlTag = "%s/%sCName" % (XmlParent, XmlParent) + + GuidProtocolPpiCommon.CName = XmlElement(XmlGuidProtocolPpiCommon, XmlTag) + + XmlTag = XmlParent + "/" + "GuidValue" + GuidProtocolPpiCommon.Guid = XmlElement(XmlGuidProtocolPpiCommon, XmlTag) + + if XmlParent.endswith("Notify"): + GuidProtocolPpiCommon.Notify = True + + XmlTag = "GuidTypeList" + GuidTypes = XmlAttribute(XmlGuidProtocolPpiCommon, XmlTag) + GuidProtocolPpiCommon.GuidTypeList = GuidTypes.split() + + XmlTag = "SupModuleList" + SupModules = XmlAttribute(XmlGuidProtocolPpiCommon, XmlTag) + GuidProtocolPpiCommon.SupModuleList = SupModules.split() + + SetCommon(GuidProtocolPpiCommon, XmlGuidProtocolPpiCommon) + + return GuidProtocolPpiCommon + + +## Load a new Pcd class object. +# +# Read an input XML Pcd DOM object and return an object of Pcd +# contained in the DOM object. +# +# @param XmlPcd A child XML DOM object in a Common XML DOM. +# +# @retvel Pcd A new Pcd object created by XmlPcd. +# +def LoadPcd(XmlPcd): + """Return a new PcdClass object equivalent to XmlPcd""" + Pcd = PcdClass() + + XmlTag = "PcdEntry/C_Name" + Pcd.CName = XmlElement(XmlPcd, XmlTag) + + XmlTag = "PcdEntry/Token" + Pcd.Token = XmlElement(XmlPcd, XmlTag) + + XmlTag = "PcdEntry/TokenSpaceGuidCName" + Pcd.TokenSpaceGuidCName = XmlElement(XmlPcd, XmlTag) + + XmlTag = "PcdEntry/DatumType" + Pcd.DatumType = XmlElement(XmlPcd, XmlTag) + + XmlTag = "PcdEntry/MaxDatumSize" + Pcd.MaxDatumSize = XmlElement(XmlPcd, XmlTag) + + XmlTag = "PcdEntry/DefaultValue" + Pcd.DefaultValue = XmlElement(XmlPcd, XmlTag) + + XmlTag = "PcdItemType" + Pcd.ItemType = XmlAttribute(XmlPcd, XmlTag) + + XmlTag = "PcdEntry/ValidUsage" + Pcd.ValidUsage = XmlElement(XmlPcd, XmlTag).split() + + XmlTag = "SupModuleList" + Pcd.SupModuleList = XmlAttribute(XmlPcd, XmlTag).split() + + SetCommon(Pcd, XmlPcd) + + return Pcd + + +## Load a new LibraryClass class object. +# +# Read an input XML LibraryClass DOM object and return an object of LibraryClass +# contained in the DOM object. +# +# @param XmlLibraryClass A child XML DOM object in a Common XML DOM. +# +# @retvel LibraryClass A new LibraryClass object created by XmlLibraryClass. +# +def LoadLibraryClass(XmlLibraryClass): + LibraryClass = LibraryClassClass() + + XmlTag = "LibraryClass/Keyword" + LibraryClass.LibraryClass = XmlElement(XmlLibraryClass, XmlTag) + if LibraryClass.LibraryClass == "": + XmlTag = "Name" + LibraryClass.LibraryClass = XmlAttribute(XmlLibraryClass, XmlTag) + + XmlTag = "LibraryClass/IncludeHeader" + LibraryClass.IncludeHeader = XmlElement(XmlLibraryClass, XmlTag) + + XmlTag = "RecommendedInstanceVersion" + RecommendedInstanceVersion = XmlAttribute(XmlLibraryClass, XmlTag) + LibraryClass.RecommendedInstanceVersion = RecommendedInstanceVersion + + XmlTag = "RecommendedInstanceGuid" + RecommendedInstanceGuid = XmlAttribute(XmlLibraryClass, XmlTag) + LibraryClass.RecommendedInstanceGuid = RecommendedInstanceGuid + + XmlTag = "SupModuleList" + SupModules = XmlAttribute(XmlLibraryClass, XmlTag) + LibraryClass.SupModuleList = SupModules.split() + + SetCommon(LibraryClass, XmlLibraryClass) + + return LibraryClass + + +## Load a new Build Option class object. +# +# Read an input XML BuildOption DOM object and return an object of Build Option +# contained in the DOM object. +# +# @param XmlBuildOption A child XML DOM object in a Common XML DOM. +# +# @retvel BuildOption A new Build Option object created by XmlBuildOption. +# +def LoadBuildOption(XmlBuildOption): + """Return a new BuildOptionClass object equivalent to XmlBuildOption""" + BuildOption = BuildOptionClass() + + BuildOption.Option = XmlElementData(XmlBuildOption) + + XmlTag = "BuildTargets" + BuildOption.BuildTargetList = XmlAttribute(XmlBuildOption, XmlTag).split() + + XmlTag = "ToolChainFamily" + BuildOption.ToolChainFamily = XmlAttribute(XmlBuildOption, XmlTag) + + XmlTag = "TagName" + BuildOption.TagName = XmlAttribute(XmlBuildOption, XmlTag) + + XmlTag = "ToolCode" + BuildOption.ToolCode = XmlAttribute(XmlBuildOption, XmlTag) + + XmlTag = "SupArchList" + BuildOption.SupArchList = XmlAttribute(XmlBuildOption, XmlTag).split() + + return BuildOption + + +## Load a new User Extensions class object. +# +# Read an input XML UserExtensions DOM object and return an object of User +# Extensions contained in the DOM object. +# +# @param XmlUserExtensions A child XML DOM object in a Common XML DOM. +# +# @retvel UserExtensions A new User Extensions object created by +# XmlUserExtensions. +# +def LoadUserExtensions(XmlUserExtensions): + UserExtensions = UserExtensionsClass() + + XmlTag = "UserID" + UserExtensions.UserID = XmlAttribute(XmlUserExtensions, XmlTag) + + XmlTag = "Identifier" + UserExtensions.Identifier = XmlAttribute(XmlUserExtensions, XmlTag) + + UserExtensions.Content = XmlElementData(XmlUserExtensions) + + return UserExtensions + + +## Store content to a text file object. +# +# Write some text file content to a text file object. The contents may echo +# in screen in a verbose way. +# +# @param TextFile The text file object. +# @param Content The string object to be written to a text file. +# +def StoreTextFile(TextFile, Content): + EdkLogger.verbose(Content) + TextFile.write(Content) + + +## Add item to a section. +# +# Add an Item with specific CPU architecture to section dictionary. +# The possible duplication is ensured to be removed. +# +# @param Section Section dictionary indexed by CPU architecture. +# @param Arch CPU architecture: Ia32, X64, Ipf, ARM, Ebc or Common. +# @param Item The Item to be added to section dictionary. +# +def AddToSection(Section, Arch, Item): + SectionArch = Section.get(Arch, []) + if Item not in SectionArch: + SectionArch.append(Item) + Section[Arch] = SectionArch + + +## Get section contents. +# +# Return the content of section named SectionName. +# the contents is based on Methods and ObjectLists. +# +# @param SectionName The name of the section. +# @param Method A function returning a string item of an object. +# @param ObjectList The list of object. +# +# @retval Section The string content of a section. +# +def GetSection(SectionName, Method, ObjectList): + SupportedArches = ["common", "Ia32", "X64", "Ipf", "Ebc", "ARM"] + SectionDict = {} + for Object in ObjectList: + Item = Method(Object) + if Item == "": + continue + Item = " %s" % Item + Arches = Object.SupArchList + if len(Arches) == 0: + AddToSection(SectionDict, "common", Item) + else: + for Arch in SupportedArches: + if Arch.upper() in Arches: + AddToSection(SectionDict, Arch, Item) + + Section = "" + for Arch in SupportedArches: + SectionArch = "\n".join(SectionDict.get(Arch, [])) + if SectionArch != "": + Section += "[%s.%s]\n%s\n" % (SectionName, Arch, SectionArch) + Section += "\n" + if Section != "": + Section += "\n" + return Section + + +## Store file header to a text file. +# +# Write standard file header to a text file. The content includes copyright, +# abstract, description and license extracted from CommonHeader class object. +# +# @param TextFile The text file object. +# @param CommonHeader The source CommonHeader class object. +# +def StoreHeader(TextFile, CommonHeader): + CopyRight = CommonHeader.Copyright + Abstract = CommonHeader.Abstract + Description = CommonHeader.Description + License = CommonHeader.License + + Header = "#/** @file\n#\n" + Header += "# " + Abstract + "\n#\n" + Header += "# " + Description.strip().replace("\n", "\n# ") + "\n" + Header += "# " + CopyRight + "\n#\n" + Header += "# " + License.replace("\n", "\n# ").replace(" ", " ") + Header += "\n#\n#**/\n\n" + + StoreTextFile(TextFile, Header) + +## Store file header to a text file. +# +# Write Defines section to a text file. DefinesTupleList determines the content. +# +# @param TextFile The text file object. +# @param DefinesTupleList The list of (Tag, Value) to be added as one item. +# +def StoreDefinesSection(TextFile, DefinesTupleList): + Section = "[Defines]\n" + for DefineItem in DefinesTupleList: + Section += " %-30s = %s\n" % DefineItem + + Section += "\n\n" + StoreTextFile(TextFile, Section) + + +## Return one User Extension section. +# +# Read the input UserExtentsions class object and return one section. +# +# @param UserExtensions An input UserExtensions class object. +# +# @retval UserExtensionSection A section representing UserExtensions object. +# +def GetUserExtensions(UserExtensions): + UserId = UserExtensions.UserID + Identifier = UserExtensions.Identifier + Content = UserExtensions.Content + + return "[UserExtensions.%s.%s]\n %s\n\n" % (UserId, Identifier, Content) + +## Regular expression to match an equation. +mReEquation = re.compile(r"\s*(\S+)\s*=\s*(\S*)\s*") + +## Return a value tuple matching information in a text fle. +# +# Parse the text file and return a value tuple corresponding to an input tag +# tuple. In case of any error, an tuple of empty strings is returned. +# +# @param FileName The file name of the text file. +# @param TagTuple A tuple of tags as the key to the value. +# +# @param ValueTupe The returned tuple corresponding to the tag tuple. +# +def GetTextFileInfo(FileName, TagTuple): + ValueTuple = [""] * len(TagTuple) + try: + for Line in open(FileName): + Line = Line.split("#", 1)[0] + MatchEquation = mReEquation.match(Line) + if MatchEquation: + Tag = MatchEquation.group(1).upper() + Value = MatchEquation.group(2) + for Index in range(len(TagTuple)): + if TagTuple[Index] == Tag: + ValueTuple[Index] = Value + except: + EdkLogger.info("IO Error in reading file %s" % FileName) + + return ValueTuple + + +## Return a value tuple matching information in an XML fle. +# +# Parse the XML file and return a value tuple corresponding to an input tag +# tuple. In case of any error, an tuple of empty strings is returned. +# +# @param FileName The file name of the XML file. +# @param TagTuple A tuple of tags as the key to the value. +# +# @param ValueTupe The returned tuple corresponding to the tag tuple. +# +def GetXmlFileInfo(FileName, TagTuple): + XmlDom = XmlParseFile(FileName) + return tuple([XmlElement(XmlDom, XmlTag) for XmlTag in TagTuple]) + + +## Parse migration command line options +# +# Use standard Python module optparse to parse command line option of this tool. +# +# @param Source The source file type. +# @param Destinate The destinate file type. +# +# @retval Options A optparse object containing the parsed options. +# @retval InputFile Path of an source file to be migrated. +# +def MigrationOptionParser(Source, Destinate, ToolName, VersionNumber = 1.0): + # use clearer usage to override default usage message + UsageString = "%s [-a] [-v|-q] [-o ] " % ToolName + Version = "%s Version %.2f" % (ToolName, VersionNumber) + Copyright = "Copyright (c) 2007, Intel Corporation. All rights reserved." + + Parser = OptionParser(description=Copyright, version=Version, usage=UsageString) + Parser.add_option("-o", "--output", dest="OutputFile", help="The name of the %s file to be created." % Destinate) + Parser.add_option("-a", "--auto", dest="AutoWrite", action="store_true", default=False, help="Automatically create the %s file using the name of the %s file and replacing file extension" % (Source, Destinate)) + Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.") + Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed.") + + Options, Args = Parser.parse_args() + + # Set logging level + if Options.verbose: + EdkLogger.setLevel(EdkLogger.VERBOSE) + elif Options.quiet: + EdkLogger.setLevel(EdkLogger.QUIET) + else: + EdkLogger.setLevel(EdkLogger.INFO) + + # error check + if len(Args) == 0: + raise MigrationError(PARAMETER_MISSING, name="Input file", usage=Parser.get_usage()) + if len(Args) > 1: + raise MigrationError(PARAMETER_INVALID, name="Too many input files", usage=Parser.get_usage()) + + InputFile = Args[0] + if not os.path.exists(InputFile): + raise MigrationError(FILE_NOT_FOUND, name=InputFile) + + if Options.OutputFile: + if Options.AutoWrite: + raise MigrationError(OPTION_CONFLICT, arg1="-o", arg2="-a", usage=Parser.get_usage()) + else: + if Options.AutoWrite: + Options.OutputFile = os.path.splitext(InputFile)[0] + "." + Destinate.lower() + else: + raise MigrationError(OPTION_MISSING, name="-o", usage=Parser.get_usage()) + + return Options, InputFile + +# This acts like the main() function for the script, unless it is 'import'ed +# into another script. +if __name__ == '__main__': + pass -- cgit v1.2.3