summaryrefslogtreecommitdiffstats
path: root/BaseTools/Source/Python/Common/MigrationUtilities.py
diff options
context:
space:
mode:
Diffstat (limited to 'BaseTools/Source/Python/Common/MigrationUtilities.py')
-rw-r--r--BaseTools/Source/Python/Common/MigrationUtilities.py567
1 files changed, 567 insertions, 0 deletions
diff --git a/BaseTools/Source/Python/Common/MigrationUtilities.py b/BaseTools/Source/Python/Common/MigrationUtilities.py
new file mode 100644
index 0000000000..b15daa8448
--- /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.<BR>
+# 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<Specification>\w+)\s+(?P<Value>\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 <output_file>] <input_file>" % 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