From 421ccda3079077dd613308526e02d797f5cc356a Mon Sep 17 00:00:00 2001 From: Hess Chen Date: Tue, 26 Aug 2014 05:58:02 +0000 Subject: [PATCH] This patch is going to: 1. Add a recovery mode for UPT failure 2. Add UNI file support 3. Add binary file header support 4. Add support for PCD error message 5. Add support for replace 6. Format generated INF/DEC files 7. Update dependency check 8. Other minor fixes Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Hess Chen Reviewed-by: Gao, Liming git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15896 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Source/Python/UPT/Core/DependencyRules.py | 267 +++-- .../UPT/Core/DistributionPackageClass.py | 49 +- BaseTools/Source/Python/UPT/Core/FileHook.py | 199 ++++ BaseTools/Source/Python/UPT/Core/IpiDb.py | 59 +- .../Source/Python/UPT/Core/PackageFile.py | 11 +- .../Python/UPT/GenMetaFile/GenDecFile.py | 396 ++++++- .../Python/UPT/GenMetaFile/GenInfFile.py | 542 +++++---- .../Python/UPT/GenMetaFile/GenMetaFileMisc.py | 76 +- BaseTools/Source/Python/UPT/InstallPkg.py | 396 +++++-- BaseTools/Source/Python/UPT/InventoryWs.py | 117 ++ .../Python/UPT/Library/CommentGenerating.py | 149 ++- .../Python/UPT/Library/CommentParsing.py | 226 +++- .../Source/Python/UPT/Library/DataType.py | 59 +- .../Python/UPT/Library/ExpressionValidate.py | 167 ++- .../Source/Python/UPT/Library/GlobalData.py | 13 +- BaseTools/Source/Python/UPT/Library/Misc.py | 210 +++- .../Python/UPT/Library/ParserValidate.py | 8 +- .../Source/Python/UPT/Library/Parsing.py | 115 +- BaseTools/Source/Python/UPT/Library/String.py | 174 ++- .../Python/UPT/Library/UniClassObject.py | 1042 +++++++++++++++++ .../Python/UPT/Library/Xml/XmlRoutines.py | 5 +- .../Source/Python/UPT/Logger/StringTable.py | 130 +- BaseTools/Source/Python/UPT/MkPkg.py | 4 +- .../Python/UPT/Object/POM/CommonObject.py | 208 +++- .../Python/UPT/Object/POM/ModuleObject.py | 15 +- .../Python/UPT/Object/POM/PackageObject.py | 14 +- .../UPT/Object/Parser/InfBinaryObject.py | 147 ++- .../UPT/Object/Parser/InfBuildOptionObject.py | 4 +- .../UPT/Object/Parser/InfDefineObject.py | 62 +- .../Python/UPT/Object/Parser/InfGuidObject.py | 9 +- .../Object/Parser/InfLibraryClassesObject.py | 3 +- .../Python/UPT/Object/Parser/InfPcdObject.py | 405 ++++--- .../Source/Python/UPT/Parser/DecParser.py | 117 +- .../Source/Python/UPT/Parser/DecParserMisc.py | 57 +- .../Python/UPT/Parser/InfAsBuiltProcess.py | 75 +- .../UPT/Parser/InfBinarySectionParser.py | 23 +- .../UPT/Parser/InfLibrarySectionParser.py | 83 +- .../Source/Python/UPT/Parser/InfParser.py | 46 +- .../Source/Python/UPT/Parser/InfParserMisc.py | 6 +- .../Python/UPT/Parser/InfPcdSectionParser.py | 6 +- .../Python/UPT/Parser/InfSectionParser.py | 15 +- .../Python/UPT/PomAdapter/DecPomAlignment.py | 446 ++++++- .../Python/UPT/PomAdapter/InfPomAlignment.py | 243 ++-- .../UPT/PomAdapter/InfPomAlignmentMisc.py | 45 +- BaseTools/Source/Python/UPT/ReplacePkg.py | 148 +++ BaseTools/Source/Python/UPT/RmPkg.py | 172 +-- BaseTools/Source/Python/UPT/UPT.py | 147 ++- .../UPT/UnitTest/CommentGeneratingUnitTest.py | 17 +- .../UPT/UnitTest/CommentParsingUnitTest.py | 10 +- BaseTools/Source/Python/UPT/Xml/CommonXml.py | 366 ++++-- BaseTools/Source/Python/UPT/Xml/IniToXml.py | 13 +- .../Python/UPT/Xml/ModuleSurfaceAreaXml.py | 83 +- .../Python/UPT/Xml/PackageSurfaceAreaXml.py | 12 +- BaseTools/Source/Python/UPT/Xml/PcdXml.py | 168 ++- BaseTools/Source/Python/UPT/Xml/XmlParser.py | 30 +- .../Source/Python/UPT/Xml/XmlParserMisc.py | 16 +- 56 files changed, 5930 insertions(+), 1695 deletions(-) create mode 100644 BaseTools/Source/Python/UPT/Core/FileHook.py create mode 100644 BaseTools/Source/Python/UPT/InventoryWs.py create mode 100644 BaseTools/Source/Python/UPT/Library/UniClassObject.py create mode 100644 BaseTools/Source/Python/UPT/ReplacePkg.py diff --git a/BaseTools/Source/Python/UPT/Core/DependencyRules.py b/BaseTools/Source/Python/UPT/Core/DependencyRules.py index 752d8e8f41..4608ed6030 100644 --- a/BaseTools/Source/Python/UPT/Core/DependencyRules.py +++ b/BaseTools/Source/Python/UPT/Core/DependencyRules.py @@ -1,7 +1,7 @@ ## @file # This file is for installed package information database operations # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -20,14 +20,14 @@ Dependency ## # Import Modules # -from os import getenv -from os import environ from os.path import dirname import Logger.Log as Logger from Logger import StringTable as ST from Library.Parsing import GetWorkspacePackage from Library.Parsing import GetWorkspaceModule +from Library.Misc import GetRelativePath +from Library import GlobalData from PomAdapter.InfPomAlignment import InfPomAlignment from Logger.ToolError import FatalError from Logger.ToolError import EDK1_INF_ERROR @@ -36,11 +36,9 @@ from Logger.ToolError import UNKNOWN_ERROR DEPEX_CHECK_PACKAGE_NOT_FOUND, DEPEX_CHECK_DP_NOT_FOUND) = (0, 1, 2, 3) -## IpiDb +## DependencyRules # -# This class represents the installed package information database -# Add/Remove/Get installed distribution package information here. -# +# This class represents the dependency rule check mechanism # # @param object: Inherited from object class # @@ -49,15 +47,17 @@ class DependencyRules(object): self.IpiDb = Datab self.WsPkgList = GetWorkspacePackage() self.WsModuleList = GetWorkspaceModule() - - ## Check whether a module exists in current workspace. + self.PkgsToBeDepend = [] + + ## Check whether a module exists by checking the Guid+Version+Name+Path combination # # @param Guid: Guid of a module # @param Version: Version of a module + # @param Name: Name of a module + # @param Path: Path of a module + # @return: True if module existed, else False # - def CheckModuleExists(self, Guid, Version, Name, Path, ReturnCode=DEPEX_CHECK_SUCCESS): - if ReturnCode: - pass + def CheckModuleExists(self, Guid, Version, Name, Path): Logger.Verbose(ST.MSG_CHECK_MODULE_EXIST) ModuleList = self.IpiDb.GetModInPackage(Guid, Version, Name, Path) ModuleList.extend(self.IpiDb.GetStandaloneModule(Guid, Version, Name, Path)) @@ -67,15 +67,14 @@ class DependencyRules(object): else: return False - ## Check whether a module depex satisfied by current workspace or dist. + ## Check whether a module depex satisfied. # # @param ModuleObj: A module object - # @param DpObj: A depex object + # @param DpObj: A distribution object + # @return: True if module depex satisfied + # False else # - def CheckModuleDepexSatisfied(self, ModuleObj, DpObj=None, \ - ReturnCode=DEPEX_CHECK_SUCCESS): - if ReturnCode: - pass + def CheckModuleDepexSatisfied(self, ModuleObj, DpObj=None): Logger.Verbose(ST.MSG_CHECK_MODULE_DEPEX_START) Result = True Dep = None @@ -114,97 +113,122 @@ class DependencyRules(object): Dep.GetVersion())) return Result - ## Check whether a package exists in current workspace. + ## Check whether a package exists in a package list specified by PkgsToBeDepend. # # @param Guid: Guid of a package # @param Version: Version of a package + # @return: True if package exist + # False else # def CheckPackageExists(self, Guid, Version): Logger.Verbose(ST.MSG_CHECK_PACKAGE_START) - for (PkgName, PkgGuid, PkgVer, PkgPath) in self.WsPkgList: - if PkgName or PkgPath: - pass + Found = False + for (PkgGuid, PkgVer) in self.PkgsToBeDepend: if (PkgGuid == Guid): # # if version is not empty and not equal, then not match # if Version and (PkgVer != Version): - return False + Found = False + break else: - return True + Found = True + break else: - return False - + Found = False + Logger.Verbose(ST.MSG_CHECK_PACKAGE_FINISH) + return Found - ## Check whether a package depex satisfied by current workspace. + ## Check whether a package depex satisfied. # # @param PkgObj: A package object - # @param DpObj: A package depex object + # @param DpObj: A distribution object + # @return: True if package depex satisified + # False else # - def CheckPackageDepexSatisfied(self, PkgObj, DpObj=None, \ - ReturnCode=DEPEX_CHECK_SUCCESS): - + def CheckPackageDepexSatisfied(self, PkgObj, DpObj=None): ModuleDict = PkgObj.GetModuleDict() for ModKey in ModuleDict.keys(): ModObj = ModuleDict[ModKey] - if self.CheckModuleDepexSatisfied(ModObj, DpObj, ReturnCode): + if self.CheckModuleDepexSatisfied(ModObj, DpObj): continue else: return False return True - ## Check whether a DP exists in current workspace. + ## Check whether a DP exists. # - # @param Guid: Guid of a module - # @param Version: Version of a module - # - def CheckDpExists(self, Guid, Version, ReturnCode=DEPEX_CHECK_SUCCESS): - if ReturnCode: - pass + # @param Guid: Guid of a Distribution + # @param Version: Version of a Distribution + # @return: True if Distribution exist + # False else + def CheckDpExists(self, Guid, Version): Logger.Verbose(ST.MSG_CHECK_DP_START) DpList = self.IpiDb.GetDp(Guid, Version) if len(DpList) > 0: - return True + Found = True else: - return False - - Logger.Verbose(ST.MSG_CHECK_DP_FINISH) - + Found = False + + Logger.Verbose(ST.MSG_CHECK_DP_FINISH) + return Found + + ## Check whether a DP depex satisfied by current workspace for Install + # + # @param DpObj: A distribution object + # @return: True if distribution depex satisfied + # False else + # + def CheckInstallDpDepexSatisfied(self, DpObj): + self.PkgsToBeDepend = [(PkgInfo[1], PkgInfo[2]) for PkgInfo in self.WsPkgList] + return self.CheckDpDepexSatisfied(DpObj) + + ## Check whether a DP depex satisfied by current workspace + # (excluding the original distribution's packages to be replaced) for Replace + # + # @param DpObj: A distribution object + # @param OrigDpGuid: The original distribution's Guid + # @param OrigDpVersion: The original distribution's Version + # + def ReplaceCheckNewDpDepex(self, DpObj, OrigDpGuid, OrigDpVersion): + self.PkgsToBeDepend = [(PkgInfo[1], PkgInfo[2]) for PkgInfo in self.WsPkgList] + OrigDpPackageList = self.IpiDb.GetPackageListFromDp(OrigDpGuid, OrigDpVersion) + for OrigPkgInfo in OrigDpPackageList: + Guid, Version = OrigPkgInfo[0], OrigPkgInfo[1] + if (Guid, Version) in self.PkgsToBeDepend: + self.PkgsToBeDepend.remove((Guid, Version)) + return self.CheckDpDepexSatisfied(DpObj) + ## Check whether a DP depex satisfied by current workspace. # - # @param DpObj: Depex object - # @param ReturnCode: ReturnCode + # @param DpObj: A distribution object # - def CheckDpDepexSatisfied(self, DpObj, ReturnCode=DEPEX_CHECK_SUCCESS): - + def CheckDpDepexSatisfied(self, DpObj): for PkgKey in DpObj.PackageSurfaceArea.keys(): PkgObj = DpObj.PackageSurfaceArea[PkgKey] - if self.CheckPackageDepexSatisfied(PkgObj, DpObj, ReturnCode): + if self.CheckPackageDepexSatisfied(PkgObj, DpObj): continue else: return False for ModKey in DpObj.ModuleSurfaceArea.keys(): ModObj = DpObj.ModuleSurfaceArea[ModKey] - if self.CheckModuleDepexSatisfied(ModObj, DpObj, ReturnCode): + if self.CheckModuleDepexSatisfied(ModObj, DpObj): continue else: return False return True - ## Check whether a DP depex satisfied by current workspace. Return False - # if Can not remove (there is dependency), True else + ## Check whether a DP could be removed from current workspace. # # @param DpGuid: File's guid # @param DpVersion: File's version - # @param ReturnCode: ReturnCode - # - def CheckDpDepexForRemove(self, DpGuid, DpVersion, \ - ReturnCode=DEPEX_CHECK_SUCCESS): - if ReturnCode: - pass + # @retval Removable: True if distribution could be removed, False Else + # @retval DependModuleList: the list of modules that make distribution can not be removed + # + def CheckDpDepexForRemove(self, DpGuid, DpVersion): Removable = True DependModuleList = [] WsModuleList = self.WsModuleList @@ -223,15 +247,14 @@ class DependencyRules(object): # List of item (PkgGuid, PkgVersion, InstallPath) DpPackageList = self.IpiDb.GetPackageListFromDp(DpGuid, DpVersion) DpPackagePathList = [] - WorkSP = environ["WORKSPACE"] + WorkSP = GlobalData.gWORKSPACE for (PkgName, PkgGuid, PkgVersion, DecFile) in self.WsPkgList: if PkgName: pass DecPath = dirname(DecFile) if DecPath.find(WorkSP) > -1: - InstallPath = DecPath[DecPath.find(WorkSP) + len(WorkSP) + 1:] - DecFileRelaPath = \ - DecFile[DecFile.find(WorkSP) + len(WorkSP) + 1:] + InstallPath = GetRelativePath(DecPath,WorkSP) + DecFileRelaPath = GetRelativePath(DecFile,WorkSP) else: InstallPath = DecPath DecFileRelaPath = DecFile @@ -251,26 +274,87 @@ class DependencyRules(object): # check modules to see if has dependency on package of current DP # for Module in WsModuleList: - if (CheckModuleDependFromInf(Module, DpPackagePathList)): + if (not VerifyRemoveModuleDep(Module, DpPackagePathList)): Removable = False DependModuleList.append(Module) return (Removable, DependModuleList) + ## Check whether a DP could be replaced by a distribution containing NewDpPkgList + # from current workspace. + # + # @param OrigDpGuid: original Dp's Guid + # @param OrigDpVersion: original Dp's version + # @param NewDpPkgList: a list of package information (Guid, Version) in new Dp + # @retval Replaceable: True if distribution could be replaced, False Else + # @retval DependModuleList: the list of modules that make distribution can not be replaced + # + def CheckDpDepexForReplace(self, OrigDpGuid, OrigDpVersion, NewDpPkgList): + Replaceable = True + DependModuleList = [] + WsModuleList = self.WsModuleList + # + # remove modules that included in current DP + # List of item (FilePath) + DpModuleList = self.IpiDb.GetDpModuleList(OrigDpGuid, OrigDpVersion) + for Module in DpModuleList: + if Module in WsModuleList: + WsModuleList.remove(Module) + else: + Logger.Warn("UPT\n", + ST.ERR_MODULE_NOT_INSTALLED % Module) + + OtherPkgList = NewDpPkgList + # + # get packages in current Dp and find the install path + # List of item (PkgGuid, PkgVersion, InstallPath) + DpPackageList = self.IpiDb.GetPackageListFromDp(OrigDpGuid, OrigDpVersion) + DpPackagePathList = [] + WorkSP = GlobalData.gWORKSPACE + for (PkgName, PkgGuid, PkgVersion, DecFile) in self.WsPkgList: + if PkgName: + pass + DecPath = dirname(DecFile) + if DecPath.find(WorkSP) > -1: + InstallPath = GetRelativePath(DecPath,WorkSP) + DecFileRelaPath = GetRelativePath(DecFile,WorkSP) + else: + InstallPath = DecPath + DecFileRelaPath = DecFile + + if (PkgGuid, PkgVersion, InstallPath) in DpPackageList: + DpPackagePathList.append(DecFileRelaPath) + DpPackageList.remove((PkgGuid, PkgVersion, InstallPath)) + else: + OtherPkgList.append((PkgGuid, PkgVersion)) + + # + # the left items in DpPackageList are the packages that installed but not found anymore + # + for (PkgGuid, PkgVersion, InstallPath) in DpPackageList: + Logger.Warn("UPT", + ST.WARN_INSTALLED_PACKAGE_NOT_FOUND%(PkgGuid, PkgVersion, InstallPath)) + + # + # check modules to see if it can be satisfied by package not belong to removed DP + # + for Module in WsModuleList: + if (not VerifyReplaceModuleDep(Module, DpPackagePathList, OtherPkgList)): + Replaceable = False + DependModuleList.append(Module) + return (Replaceable, DependModuleList) + + ## check whether module depends on packages in DpPackagePathList, return True # if found, False else # # @param Path: a module path # @param DpPackagePathList: a list of Package Paths +# @retval: False: module depends on package in DpPackagePathList +# True: module doesn't depend on package in DpPackagePathList # -def CheckModuleDependFromInf(Path, DpPackagePathList): - - # - # use InfParser to parse inf, then get the information for now, - # later on, may consider only parse to get the package dependency info - # (Need to take care how to deal wit Macros) - # - WorkSP = getenv('WORKSPACE') +def VerifyRemoveModuleDep(Path, DpPackagePathList): + WorkSP = GlobalData.gWORKSPACE try: PomAli = InfPomAlignment(Path, WorkSP, Skip=True) @@ -278,16 +362,47 @@ def CheckModuleDependFromInf(Path, DpPackagePathList): for Item in PomAli.GetPackageDependencyList(): if Item.GetPackageFilePath() in DpPackagePathList: Logger.Info(ST.MSG_MODULE_DEPEND_ON % (Path, Item.GetPackageFilePath())) - return True + return False else: - return False + return True except FatalError, ErrCode: if ErrCode.message == EDK1_INF_ERROR: Logger.Warn("UPT", ST.WRN_EDK1_INF_FOUND%Path) - return False + return True else: - return False - + return True + +## check whether module depends on packages in DpPackagePathList and can not be satisfied by OtherPkgList +# +# @param Path: a module path +# @param DpPackagePathList: a list of Package Paths +# @param OtherPkgList: a list of Package Information (Guid, Version) +# @retval: False: module depends on package in DpPackagePathList and can not be satisfied by OtherPkgList +# True: either module doesn't depend on DpPackagePathList or module depends on DpPackagePathList +# but can be satisfied by OtherPkgList +# +def VerifyReplaceModuleDep(Path, DpPackagePathList, OtherPkgList): + WorkSP = GlobalData.gWORKSPACE + + try: + PomAli = InfPomAlignment(Path, WorkSP, Skip=True) + + for Item in PomAli.GetPackageDependencyList(): + if Item.GetPackageFilePath() in DpPackagePathList: + Guid, Version = Item.GetGuid(), Item.GetVersion() + if (Guid, Version) not in OtherPkgList: + Logger.Info(ST.MSG_MODULE_DEPEND_ON % (Path, Item.GetPackageFilePath())) + return False + else: + return True + except FatalError, ErrCode: + if ErrCode.message == EDK1_INF_ERROR: + Logger.Warn("UPT", + ST.WRN_EDK1_INF_FOUND%Path) + return True + else: + return True + diff --git a/BaseTools/Source/Python/UPT/Core/DistributionPackageClass.py b/BaseTools/Source/Python/UPT/Core/DistributionPackageClass.py index 8ac8d4ed52..6db13b06b6 100644 --- a/BaseTools/Source/Python/UPT/Core/DistributionPackageClass.py +++ b/BaseTools/Source/Python/UPT/Core/DistributionPackageClass.py @@ -1,7 +1,7 @@ ## @file # This file is used to define a class object to describe a distribution package # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -195,6 +195,7 @@ class DistributionPackageClass(object): # def GetDistributionFileList(self): MetaDataFileList = [] + SkipModulesUniList = [] for Guid, Version, Path in self.PackageSurfaceArea: Package = self.PackageSurfaceArea[Guid, Version, Path] @@ -206,7 +207,15 @@ class DistributionPackageClass(object): SearchPath = os.path.normpath(os.path.join(os.path.dirname(FullPath), IncludePath)) AddPath = os.path.normpath(os.path.join(PackagePath, IncludePath)) self.FileList += GetNonMetaDataFiles(SearchPath, ['CVS', '.svn'], False, AddPath) - + # + # Add the miscellaneous files on DEC file + # + for MiscFileObj in Package.GetMiscFileList(): + for FileObj in MiscFileObj.GetFileList(): + MiscFileFullPath = os.path.normpath(os.path.join(os.path.dirname(FullPath), FileObj.GetURI())) + if MiscFileFullPath not in self.FileList: + self.FileList.append(MiscFileFullPath) + Module = None ModuleDict = Package.GetModuleDict() for Guid, Version, Name, Path in ModuleDict: @@ -215,15 +224,43 @@ class DistributionPackageClass(object): FullPath = Module.GetFullPath() PkgRelPath = os.path.normpath(os.path.join(PackagePath, ModulePath)) MetaDataFileList.append(Path) - self.FileList += GetNonMetaDataFiles(os.path.dirname(FullPath), ['CVS', '.svn'], False, PkgRelPath) - + SkipList = ['CVS', '.svn'] + NonMetaDataFileList = [] + if Module.UniFileClassObject: + for UniFile in Module.UniFileClassObject.IncFileList: + OriPath = os.path.normpath(os.path.dirname(FullPath)) + UniFilePath = os.path.normpath(os.path.join(PkgRelPath, UniFile.Path[len(OriPath) + 1:])) + if UniFilePath not in SkipModulesUniList: + SkipModulesUniList.append(UniFilePath) + for IncludeFile in Module.UniFileClassObject.IncludePathList: + if IncludeFile not in SkipModulesUniList: + SkipModulesUniList.append(IncludeFile) + NonMetaDataFileList = GetNonMetaDataFiles(os.path.dirname(FullPath), SkipList, False, PkgRelPath) + for NonMetaDataFile in NonMetaDataFileList: + if NonMetaDataFile not in self.FileList: + self.FileList.append(NonMetaDataFile) for Guid, Version, Name, Path in self.ModuleSurfaceArea: Module = self.ModuleSurfaceArea[Guid, Version, Name, Path] ModulePath = Module.GetModulePath() FullPath = Module.GetFullPath() MetaDataFileList.append(Path) - self.FileList += GetNonMetaDataFiles(os.path.dirname(FullPath), ['CVS', '.svn'], False, ModulePath) - + SkipList = ['CVS', '.svn'] + NonMetaDataFileList = [] + if Module.UniFileClassObject: + for UniFile in Module.UniFileClassObject.IncFileList: + OriPath = os.path.normpath(os.path.dirname(FullPath)) + UniFilePath = os.path.normpath(os.path.join(ModulePath, UniFile.Path[len(OriPath) + 1:])) + if UniFilePath not in SkipModulesUniList: + SkipModulesUniList.append(UniFilePath) + NonMetaDataFileList = GetNonMetaDataFiles(os.path.dirname(FullPath), SkipList, False, ModulePath) + for NonMetaDataFile in NonMetaDataFileList: + if NonMetaDataFile not in self.FileList: + self.FileList.append(NonMetaDataFile) + + for SkipModuleUni in SkipModulesUniList: + if SkipModuleUni in self.FileList: + self.FileList.remove(SkipModuleUni) + return self.FileList, MetaDataFileList diff --git a/BaseTools/Source/Python/UPT/Core/FileHook.py b/BaseTools/Source/Python/UPT/Core/FileHook.py new file mode 100644 index 0000000000..d8736a8723 --- /dev/null +++ b/BaseTools/Source/Python/UPT/Core/FileHook.py @@ -0,0 +1,199 @@ +## @file +# This file hooks file and directory creation and removal +# +# Copyright (c) 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. +# + +''' +File hook +''' + +import os +import stat +import time +import zipfile +from time import sleep +from Library import GlobalData + +__built_in_remove__ = os.remove +__built_in_mkdir__ = os.mkdir +__built_in_rmdir__ = os.rmdir +__built_in_chmod__ = os.chmod +__built_in_open__ = open + +_RMFILE = 0 +_MKFILE = 1 +_RMDIR = 2 +_MKDIR = 3 +_CHMOD = 4 + +gBACKUPFILE = 'file.backup' +gEXCEPTION_LIST = ['Conf'+os.sep+'DistributionPackageDatabase.db', '.tmp', gBACKUPFILE] + +class _PathInfo: + def __init__(self, action, path, mode=-1): + self.action = action + self.path = path + self.mode = mode + +class RecoverMgr: + def __init__(self, workspace): + self.rlist = [] + self.zip = None + self.workspace = os.path.normpath(workspace) + self.backupfile = gBACKUPFILE + self.zipfile = os.path.join(self.workspace, gBACKUPFILE) + + def _createzip(self): + if self.zip: + return + self.zip = zipfile.ZipFile(self.zipfile, 'w', zipfile.ZIP_DEFLATED) + + def _save(self, tmp, path): + if not self._tryhook(path): + return + self.rlist.append(_PathInfo(tmp, path)) + + def bkrmfile(self, path): + arc = self._tryhook(path) + if arc and os.path.isfile(path): + self._createzip() + self.zip.write(path, arc.encode('utf_8')) + sta = os.stat(path) + oldmode = stat.S_IMODE(sta.st_mode) + self.rlist.append(_PathInfo(_CHMOD, path, oldmode)) + self.rlist.append(_PathInfo(_RMFILE, path)) + __built_in_remove__(path) + + def bkmkfile(self, path, mode, bufsize): + if not os.path.exists(path): + self._save(_MKFILE, path) + return __built_in_open__(path, mode, bufsize) + + def bkrmdir(self, path): + if os.path.exists(path): + sta = os.stat(path) + oldmode = stat.S_IMODE(sta.st_mode) + self.rlist.append(_PathInfo(_CHMOD, path, oldmode)) + self._save(_RMDIR, path) + __built_in_rmdir__(path) + + def bkmkdir(self, path, mode): + if not os.path.exists(path): + self._save(_MKDIR, path) + __built_in_mkdir__(path, mode) + + def bkchmod(self, path, mode): + if self._tryhook(path) and os.path.exists(path): + sta = os.stat(path) + oldmode = stat.S_IMODE(sta.st_mode) + self.rlist.append(_PathInfo(_CHMOD, path, oldmode)) + __built_in_chmod__(path, mode) + + def rollback(self): + if self.zip: + self.zip.close() + self.zip = None + index = len(self.rlist) - 1 + while index >= 0: + item = self.rlist[index] + exist = os.path.exists(item.path) + if item.action == _MKFILE and exist: + #if not os.access(item.path, os.W_OK): + # os.chmod(item.path, S_IWUSR) + __built_in_remove__(item.path) + elif item.action == _RMFILE and not exist: + if not self.zip: + self.zip = zipfile.ZipFile(self.zipfile, 'r', zipfile.ZIP_DEFLATED) + arcname = os.path.normpath(item.path) + arcname = arcname[len(self.workspace)+1:].encode('utf_8') + if os.sep != "/" and os.sep in arcname: + arcname = arcname.replace(os.sep, '/') + mtime = self.zip.getinfo(arcname).date_time + content = self.zip.read(arcname) + filep = __built_in_open__(item.path, "wb") + filep.write(content) + filep.close() + intime = time.mktime(mtime + (0, 0, 0)) + os.utime(item.path, (intime, intime)) + elif item.action == _MKDIR and exist: + while True: + try: + __built_in_rmdir__(item.path) + break + except IOError: + # Sleep a short time and try again + # The anti-virus software may delay the file removal in this directory + sleep(0.1) + elif item.action == _RMDIR and not exist: + __built_in_mkdir__(item.path) + elif item.action == _CHMOD and exist: + try: + __built_in_chmod__(item.path, item.mode) + except EnvironmentError: + pass + index -= 1 + self.commit() + + def commit(self): + if self.zip: + self.zip.close() + __built_in_remove__(self.zipfile) + + # Check if path needs to be hooked + def _tryhook(self, path): + path = os.path.normpath(path) + works = self.workspace if str(self.workspace).endswith(os.sep) else (self.workspace + os.sep) + if not path.startswith(works): + return '' + for exceptdir in gEXCEPTION_LIST: + full = os.path.join(self.workspace, exceptdir) + if full == path or path.startswith(full + os.sep) or os.path.split(full)[0] == path: + return '' + return path[len(self.workspace)+1:] + +def _hookrm(path): + if GlobalData.gRECOVERMGR: + GlobalData.gRECOVERMGR.bkrmfile(path) + else: + __built_in_remove__(path) + +def _hookmkdir(path, mode=0777): + if GlobalData.gRECOVERMGR: + GlobalData.gRECOVERMGR.bkmkdir(path, mode) + else: + __built_in_mkdir__(path, mode) + +def _hookrmdir(path): + if GlobalData.gRECOVERMGR: + GlobalData.gRECOVERMGR.bkrmdir(path) + else: + __built_in_rmdir__(path) + +def _hookmkfile(path, mode='r', bufsize=-1): + if GlobalData.gRECOVERMGR: + return GlobalData.gRECOVERMGR.bkmkfile(path, mode, bufsize) + return __built_in_open__(path, mode, bufsize) + +def _hookchmod(path, mode): + if GlobalData.gRECOVERMGR: + GlobalData.gRECOVERMGR.bkchmod(path, mode) + else: + __built_in_chmod__(path, mode) + +def SetRecoverMgr(mgr): + GlobalData.gRECOVERMGR = mgr + +os.remove = _hookrm +os.mkdir = _hookmkdir +os.rmdir = _hookrmdir +os.chmod = _hookchmod +__FileHookOpen__ = _hookmkfile diff --git a/BaseTools/Source/Python/UPT/Core/IpiDb.py b/BaseTools/Source/Python/UPT/Core/IpiDb.py index e45acb7d48..2c444f903c 100644 --- a/BaseTools/Source/Python/UPT/Core/IpiDb.py +++ b/BaseTools/Source/Python/UPT/Core/IpiDb.py @@ -1,7 +1,7 @@ ## @file # This file is for installed package information database operations # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -27,6 +27,7 @@ import Logger.Log as Logger from Logger import StringTable as ST from Logger.ToolError import UPT_ALREADY_RUNNING_ERROR from Logger.ToolError import UPT_DB_UPDATE_ERROR +import platform as pf ## IpiDb # @@ -39,7 +40,7 @@ from Logger.ToolError import UPT_DB_UPDATE_ERROR # # class IpiDatabase(object): - def __init__(self, DbPath): + def __init__(self, DbPath, Workspace): Dir = os.path.dirname(DbPath) if not os.path.isdir(Dir): os.mkdir(Dir) @@ -54,6 +55,7 @@ class IpiDatabase(object): self.ModDepexTable = 'ModDepexInfo' self.DpFileListTable = 'DpFileListInfo' self.DummyTable = 'Dummy' + self.Workspace = os.path.normpath(Workspace) ## Initialize build database # @@ -156,6 +158,12 @@ class IpiDatabase(object): Logger.Verbose(ST.MSG_INIT_IPI_FINISH) + def RollBack(self): + self.Conn.rollback() + + def Commit(self): + self.Conn.commit() + ## Add a distribution install information from DpObj # # @param DpObj: @@ -222,7 +230,6 @@ class IpiDatabase(object): self._AddDp(DpObj.Header.GetGuid(), DpObj.Header.GetVersion(), \ NewDpPkgFileName, DpPkgFileName, RePackage) - self.Conn.commit() except sqlite3.IntegrityError, DetailMsg: Logger.Error("UPT", UPT_DB_UPDATE_ERROR, @@ -266,7 +273,13 @@ class IpiDatabase(object): # @param Path: A Md5Sum # def _AddDpFilePathList(self, DpGuid, DpVersion, Path, Md5Sum): - + Path = os.path.normpath(Path) + if pf.system() == 'Windows': + if Path.startswith(self.Workspace): + Path = Path[len(self.Workspace):] + else: + if Path.startswith(self.Workspace + os.sep): + Path = Path[len(self.Workspace)+1:] SqlCommand = """insert into %s values('%s', '%s', '%s', '%s')""" % \ (self.DpFileListTable, Path, DpGuid, DpVersion, Md5Sum) @@ -320,6 +333,11 @@ class IpiDatabase(object): if PkgVersion == None or len(PkgVersion.strip()) == 0: PkgVersion = 'N/A' + + if os.name == 'posix': + Path = Path.replace('\\', os.sep) + else: + Path = Path.replace('/', os.sep) # # Add module from package information to DB. @@ -378,6 +396,11 @@ class IpiDatabase(object): if DepexVersion == None or len(DepexVersion.strip()) == 0: DepexVersion = 'N/A' + + if os.name == 'posix': + Path = Path.replace('\\', os.sep) + else: + Path = Path.replace('/', os.sep) # # Add module depex information to DB. @@ -478,7 +501,7 @@ class IpiDatabase(object): (self.DpTable, DpGuid, DpVersion) self.Cur.execute(SqlCommand) - self.Conn.commit() + #self.Conn.commit() ## Get a list of distribution install information. # @@ -554,7 +577,7 @@ class IpiDatabase(object): for Result in self.Cur: Path = Result[0] Md5Sum = Result[3] - PathList.append((Path, Md5Sum)) + PathList.append((os.path.join(self.Workspace, Path), Md5Sum)) return PathList @@ -824,7 +847,7 @@ class IpiDatabase(object): self.Cur.execute(SqlCommand) for ModuleInfo in self.Cur: FilePath = ModuleInfo[0] - ModList.append(FilePath) + ModList.append(os.path.join(self.Workspace, FilePath)) return ModList @@ -844,7 +867,7 @@ class IpiDatabase(object): ModuleVersion = '%s' and InstallPath ='%s' """ % (self.ModDepexTable, Guid, Version, Path) self.Cur.execute(SqlCommand) - self.Conn.commit() + DepexList = [] for DepInfo in self.Cur: @@ -853,7 +876,25 @@ class IpiDatabase(object): DepexList.append((DepexGuid, DepexVersion)) return DepexList - + + ## Inventory the distribution installed to current workspace + # + # Inventory the distribution installed to current workspace + # + def InventoryDistInstalled(self): + SqlCommand = """select * from %s """ % (self.DpTable) + self.Cur.execute(SqlCommand) + + DpInfoList = [] + for Result in self.Cur: + DpGuid = Result[0] + DpVersion = Result[1] + DpAliasName = Result[3] + DpFileName = Result[4] + DpInfoList.append((DpGuid, DpVersion, DpFileName, DpAliasName)) + + return DpInfoList + ## Close entire database # # Close the connection and cursor diff --git a/BaseTools/Source/Python/UPT/Core/PackageFile.py b/BaseTools/Source/Python/UPT/Core/PackageFile.py index 04c5d4e8d0..47ea0bc0a9 100644 --- a/BaseTools/Source/Python/UPT/Core/PackageFile.py +++ b/BaseTools/Source/Python/UPT/Core/PackageFile.py @@ -2,7 +2,7 @@ # # PackageFile class represents the zip file of a distribution package. # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -36,7 +36,7 @@ import Logger.Log as Logger from Logger import StringTable as ST from Library.Misc import CreateDirectory from Library.Misc import RemoveDirectory - +from Core.FileHook import __FileHookOpen__ class PackageFile: @@ -96,7 +96,7 @@ class PackageFile: ## Extract the file # # @param Which: the source path - # @param To: the destination path + # @param ToDest: the destination path # def Extract(self, Which, ToDest): Which = os.path.normpath(Which) @@ -116,7 +116,8 @@ class PackageFile: Logger.Warn("PackagingTool", \ ST.WRN_FILE_NOT_OVERWRITTEN % ToDest) return - ToFile = open(ToDest, "wb") + else: + ToFile = __FileHookOpen__(ToDest, 'wb') except BaseException, Xstr: Logger.Error("PackagingTool", FILE_OPEN_FAILURE, ExtraData="%s (%s)" % (ToDest, str(Xstr))) @@ -234,6 +235,8 @@ class PackageFile: # def PackData(self, Data, ArcName): try: + if os.path.splitext(ArcName)[1].lower() == '.pkg': + Data = Data.encode('utf_8') self._ZipFile.writestr(ArcName, Data) except BaseException, Xstr: Logger.Error("PackagingTool", FILE_COMPRESS_FAILURE, diff --git a/BaseTools/Source/Python/UPT/GenMetaFile/GenDecFile.py b/BaseTools/Source/Python/UPT/GenMetaFile/GenDecFile.py index 575c216e58..d886958f97 100644 --- a/BaseTools/Source/Python/UPT/GenMetaFile/GenDecFile.py +++ b/BaseTools/Source/Python/UPT/GenMetaFile/GenDecFile.py @@ -2,7 +2,7 @@ # # This file contained the logical of transfer package object to DEC files. # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -16,7 +16,11 @@ ''' GenDEC ''' - +import os +import stat +import codecs +import md5 +from Core.FileHook import __FileHookOpen__ from Library.Parsing import GenSection from Library.CommentGenerating import GenHeaderCommentSection from Library.CommentGenerating import GenGenericCommentF @@ -25,14 +29,41 @@ from Library.CommentGenerating import _GetHelpStr from Library.Misc import GuidStringToGuidStructureString from Library.Misc import SaveFileOnChange from Library.Misc import ConvertPath +from Library.Misc import GetLocalValue from Library.DataType import TAB_SPACE_SPLIT from Library.DataType import TAB_COMMA_SPLIT +from Library.DataType import END_OF_LINE from Library.DataType import TAB_ARCH_COMMON +from Library.DataType import TAB_VALUE_SPLIT +from Library.DataType import TAB_COMMENT_SPLIT +from Library.DataType import TAB_PCD_VALIDRANGE +from Library.DataType import TAB_PCD_VALIDLIST +from Library.DataType import TAB_PCD_EXPRESSION from Library.DataType import TAB_DEC_DEFINES_DEC_SPECIFICATION from Library.DataType import TAB_DEC_DEFINES_PACKAGE_NAME from Library.DataType import TAB_DEC_DEFINES_PACKAGE_GUID from Library.DataType import TAB_DEC_DEFINES_PACKAGE_VERSION - +from Library.DataType import TAB_DEC_DEFINES_PKG_UNI_FILE +from Library.DataType import TAB_DEC_PACKAGE_ABSTRACT +from Library.DataType import TAB_DEC_PACKAGE_DESCRIPTION +from Library.DataType import TAB_DEC_BINARY_ABSTRACT +from Library.DataType import TAB_DEC_BINARY_DESCRIPTION +from Library.DataType import TAB_LANGUAGE_EN_X +from Library.DataType import TAB_BINARY_HEADER_USERID +from Library.DataType import TAB_BINARY_HEADER_IDENTIFIER +from Library.DataType import TAB_COMMENT_EDK1_SPLIT +from Library.DataType import TAB_ENCODING_UTF16LE +from Library.DataType import TAB_CAPHEX_START +from Library.DataType import TAB_HEX_START +from Library.DataType import TAB_UNDERLINE_SPLIT +from Library.DataType import TAB_STR_TOKENERR +from Library.DataType import TAB_STR_TOKENCNAME +from Library.DataType import TAB_PCD_ERROR_SECTION_COMMENT +from Library.DataType import TAB_PCD_ERROR +from Library.DataType import TAB_SECTION_START +from Library.DataType import TAB_SECTION_END +from Library.DataType import TAB_SPLIT +from Library.UniClassObject import FormatUniEntry def GenPcd(Package, Content): # @@ -47,12 +78,16 @@ def GenPcd(Package, Content): HelpTextList = Pcd.GetHelpTextList() HelpStr = _GetHelpStr(HelpTextList) CommentStr = GenGenericCommentF(HelpStr, 2) - + + PromptList = Pcd.GetPromptList() + PromptStr = _GetHelpStr(PromptList) + CommentStr += GenGenericCommentF(PromptStr.strip(), 1, True) + PcdErrList = Pcd.GetPcdErrorsList() - if PcdErrList: - CommentStr += GenPcdErrComment(PcdErrList[0]) + for PcdErr in PcdErrList: + CommentStr += GenPcdErrComment(PcdErr) Statement = CommentStr - + CName = Pcd.GetCName() TokenSpaceGuidCName = Pcd.GetTokenSpaceGuidCName() DefaultValue = Pcd.GetDefaultValue() @@ -96,15 +131,61 @@ def GenPcd(Package, Content): NewSectionDict[SortedArch] = [Statement] for ValidUsage in ValidUsageDict: - Content += GenSection(ValidUsage, ValidUsageDict[ValidUsage]) + Content += GenSection(ValidUsage, ValidUsageDict[ValidUsage], True, True) return Content +def GenPcdErrorMsgSection(Package, Content): + if not Package.PcdErrorCommentDict: + return Content + + # + # Generate '# [Error.]' section + # + Content += END_OF_LINE + END_OF_LINE + SectionComment = TAB_COMMENT_SPLIT + END_OF_LINE + SectionComment += TAB_COMMENT_SPLIT + TAB_SPACE_SPLIT + TAB_PCD_ERROR_SECTION_COMMENT + END_OF_LINE + SectionComment += TAB_COMMENT_SPLIT + END_OF_LINE + TokenSpcCNameList = [] + + # + # Get TokenSpcCName list in PcdErrorCommentDict in Package object + # + for (TokenSpcCName, ErrorNumber) in Package.PcdErrorCommentDict: + if TokenSpcCName not in TokenSpcCNameList: + TokenSpcCNameList.append(TokenSpcCName) + + for TokenSpcCNameItem in TokenSpcCNameList: + SectionName = TAB_COMMENT_SPLIT + TAB_SPACE_SPLIT + TAB_SECTION_START + TAB_PCD_ERROR + \ + TAB_SPLIT + TokenSpcCNameItem + TAB_SECTION_END + END_OF_LINE + Content += SectionComment + Content += SectionName + for (TokenSpcCName, ErrorNumber) in Package.PcdErrorCommentDict: + if TokenSpcCNameItem == TokenSpcCName: + PcdErrorMsg = GetLocalValue(Package.PcdErrorCommentDict[(TokenSpcCName, ErrorNumber)]) + SectionItem = TAB_COMMENT_SPLIT + TAB_SPACE_SPLIT + TAB_SPACE_SPLIT + \ + ErrorNumber + TAB_SPACE_SPLIT + TAB_VALUE_SPLIT + TAB_SPACE_SPLIT + \ + PcdErrorMsg + END_OF_LINE + Content += SectionItem + + Content += TAB_COMMENT_SPLIT + return Content + def GenGuidProtocolPpi(Package, Content): # # generate [Guids] section # NewSectionDict = {} + + LeftOffset = 46 + # Get the line offset need + # If the real one < the min one, use the min one + # else use the real one + for Guid in Package.GetGuidList(): + if len(Guid.GetCName()) > LeftOffset: + LeftOffset = len(Guid.GetCName()) + + # Generate for Guid in Package.GetGuidList(): # # Generate generic comment @@ -116,7 +197,7 @@ def GenGuidProtocolPpi(Package, Content): Statement = CommentStr CName = Guid.GetCName() Value = GuidStringToGuidStructureString(Guid.GetGuid()) - Statement += CName + ' = ' + Value + Statement += CName.ljust(LeftOffset) + ' = ' + Value # # generate tail comment # @@ -131,12 +212,20 @@ def GenGuidProtocolPpi(Package, Content): else: NewSectionDict[SortedArch] = [Statement] - Content += GenSection('Guids', NewSectionDict) + Content += GenSection('Guids', NewSectionDict, True, True) # # generate [Protocols] section # NewSectionDict = {} + LeftOffset = 46 + # Get the line offset need + # If the real one < the min one, use the min one + # else use the real one + for Protocol in Package.GetProtocolList(): + if len(Protocol.GetCName()) > LeftOffset: + LeftOffset = len(Protocol.GetCName()) + for Protocol in Package.GetProtocolList(): # # Generate generic comment @@ -148,7 +237,7 @@ def GenGuidProtocolPpi(Package, Content): Statement = CommentStr CName = Protocol.GetCName() Value = GuidStringToGuidStructureString(Protocol.GetGuid()) - Statement += CName + ' = ' + Value + Statement += CName.ljust(LeftOffset) + ' = ' + Value # # generate tail comment @@ -164,12 +253,20 @@ def GenGuidProtocolPpi(Package, Content): else: NewSectionDict[SortedArch] = [Statement] - Content += GenSection('Protocols', NewSectionDict) + Content += GenSection('Protocols', NewSectionDict, True, True) # # generate [Ppis] section # NewSectionDict = {} + LeftOffset = 46 + # Get the line offset need + # If the real one < the min one, use the min one + # else use the real one + for Ppi in Package.GetPpiList(): + if len(Ppi.GetCName()) > LeftOffset: + LeftOffset = len(Ppi.GetCName()) + for Ppi in Package.GetPpiList(): # # Generate generic comment @@ -181,7 +278,7 @@ def GenGuidProtocolPpi(Package, Content): Statement = CommentStr CName = Ppi.GetCName() Value = GuidStringToGuidStructureString(Ppi.GetGuid()) - Statement += CName + ' = ' + Value + Statement += CName.ljust(LeftOffset) + ' = ' + Value # # generate tail comment @@ -197,7 +294,7 @@ def GenGuidProtocolPpi(Package, Content): else: NewSectionDict[SortedArch] = [Statement] - Content += GenSection('Ppis', NewSectionDict) + Content += GenSection('Ppis', NewSectionDict, True, True) return Content @@ -207,21 +304,77 @@ def GenGuidProtocolPpi(Package, Content): # # @param Package: A Package # -def PackageToDec(Package): +def PackageToDec(Package, DistHeader = None): # # Init global information for the file # ContainerFile = Package.GetFullPath() Content = '' + # - # generate header comment section + # Generate file header # - Content += GenHeaderCommentSection(Package.GetAbstract(), \ - Package.GetDescription(), \ - Package.GetCopyright(), \ - Package.GetLicense()) - + PackageAbstract = GetLocalValue(Package.GetAbstract()) + PackageDescription = GetLocalValue(Package.GetDescription()) + PackageCopyright = '' + PackageLicense = '' + for (Lang, Copyright) in Package.GetCopyright(): + if Lang: + pass + PackageCopyright = Copyright + for (Lang, License) in Package.GetLicense(): + if Lang: + pass + PackageLicense = License + if not PackageAbstract and DistHeader: + PackageAbstract = GetLocalValue(DistHeader.GetAbstract()) + if not PackageDescription and DistHeader: + PackageDescription = GetLocalValue(DistHeader.GetDescription()) + if not PackageCopyright and DistHeader: + for (Lang, Copyright) in DistHeader.GetCopyright(): + PackageCopyright = Copyright + if not PackageLicense and DistHeader: + for (Lang, License) in DistHeader.GetLicense(): + PackageLicense = License + + # + # Generate header comment section of DEC file + # + Content += GenHeaderCommentSection(PackageAbstract, \ + PackageDescription, \ + PackageCopyright, \ + PackageLicense) + + # + # Generate Binary header + # + for UserExtension in Package.GetUserExtensionList(): + if UserExtension.GetUserID() == TAB_BINARY_HEADER_USERID \ + and UserExtension.GetIdentifier() == TAB_BINARY_HEADER_IDENTIFIER: + PackageBinaryAbstract = GetLocalValue(UserExtension.GetBinaryAbstract()) + PackageBinaryDescription = GetLocalValue(UserExtension.GetBinaryDescription()) + PackageBinaryCopyright = '' + PackageBinaryLicense = '' + for (Lang, Copyright) in UserExtension.GetBinaryCopyright(): + PackageBinaryCopyright = Copyright + for (Lang, License) in UserExtension.GetBinaryLicense(): + PackageBinaryLicense = License + if PackageBinaryAbstract and PackageBinaryDescription and \ + PackageBinaryCopyright and PackageBinaryLicense: + Content += GenHeaderCommentSection(PackageBinaryAbstract, + PackageBinaryDescription, + PackageBinaryCopyright, + PackageBinaryLicense, + True) + + # + # Generate PACKAGE_UNI_FILE for the Package + # + FileHeader = GenHeaderCommentSection(PackageAbstract, PackageDescription, PackageCopyright, PackageLicense, False, \ + TAB_COMMENT_EDK1_SPLIT) + GenPackageUNIEncodeFile(Package, FileHeader) + # # for each section, maintain a dict, sorted arch will be its key, #statement list will be its data @@ -233,21 +386,29 @@ def PackageToDec(Package): # # generate [Defines] section # + LeftOffset = 31 NewSectionDict = {TAB_ARCH_COMMON : []} SpecialItemList = [] - Statement = '%s = %s' % (TAB_DEC_DEFINES_DEC_SPECIFICATION, '0x00010017') + Statement = (u'%s ' % TAB_DEC_DEFINES_DEC_SPECIFICATION).ljust(LeftOffset) + u'= %s' % '0x00010017' SpecialItemList.append(Statement) BaseName = Package.GetBaseName() if BaseName.startswith('.') or BaseName.startswith('-'): BaseName = '_' + BaseName - Statement = '%s = %s' % (TAB_DEC_DEFINES_PACKAGE_NAME, BaseName) + Statement = (u'%s ' % TAB_DEC_DEFINES_PACKAGE_NAME).ljust(LeftOffset) + u'= %s' % BaseName SpecialItemList.append(Statement) - Statement = '%s = %s' % (TAB_DEC_DEFINES_PACKAGE_VERSION, Package.GetVersion()) + + Statement = (u'%s ' % TAB_DEC_DEFINES_PACKAGE_VERSION).ljust(LeftOffset) + u'= %s' % Package.GetVersion() SpecialItemList.append(Statement) - Statement = '%s = %s' % (TAB_DEC_DEFINES_PACKAGE_GUID, Package.GetGuid()) - SpecialItemList.append(Statement) + + Statement = (u'%s ' % TAB_DEC_DEFINES_PACKAGE_GUID).ljust(LeftOffset) + u'= %s' % Package.GetGuid() + SpecialItemList.append(Statement) + + if Package.UNIFlag: + Statement = (u'%s ' % TAB_DEC_DEFINES_PKG_UNI_FILE).ljust(LeftOffset) + u'= %s' % Package.GetBaseName() + '.uni' + SpecialItemList.append(Statement) + for SortedArch in NewSectionDict: NewSectionDict[SortedArch] = \ NewSectionDict[SortedArch] + SpecialItemList @@ -269,8 +430,11 @@ def PackageToDec(Package): else: NewSectionDict[SortedArch] = [ConvertPath(Statement)] - Content += GenSection('Includes', NewSectionDict) + Content += GenSection('Includes', NewSectionDict) + # + # generate [guids][protocols][ppis] sections + # Content = GenGuidProtocolPpi(Package, Content) # @@ -284,8 +448,8 @@ def PackageToDec(Package): HelpTextList = LibraryClass.GetHelpTextList() HelpStr = _GetHelpStr(HelpTextList) if HelpStr: - HelpStr = '@libraryclass ' + HelpStr - CommentStr = GenGenericCommentF(HelpStr, 2) + HelpStr = '@libraryclass' + HelpStr + CommentStr = GenGenericCommentF(HelpStr, 2, False, True) Statement = CommentStr Name = LibraryClass.GetLibraryClass() @@ -306,18 +470,31 @@ def PackageToDec(Package): else: NewSectionDict[SortedArch] = [Statement] - Content += GenSection('LibraryClasses', NewSectionDict) + Content += GenSection('LibraryClasses', NewSectionDict, True, True) - Content = GenPcd(Package, Content) + # + # Generate '# [Error.]' section + # + Content = GenPcdErrorMsgSection(Package, Content) + Content = GenPcd(Package, Content) + # # generate [UserExtensions] section # NewSectionDict = {} for UserExtension in Package.GetUserExtensionList(): + if UserExtension.GetUserID() == TAB_BINARY_HEADER_USERID and \ + UserExtension.GetIdentifier() == TAB_BINARY_HEADER_IDENTIFIER: + continue Statement = UserExtension.GetStatement() if not Statement: continue + else: + LineList = Statement.split('\n') + NewStatement = "" + for Line in LineList: + NewStatement += " %s\n" % Line SectionList = [] SectionName = 'UserExtensions' @@ -335,11 +512,147 @@ def PackageToDec(Package): SectionList.append(SectionName + '.' + Arch) SectionName = ', '.join(SectionList) SectionName = ''.join(['[', SectionName, ']\n']) - Content += '\n\n' + SectionName + Statement + Content += '\n' + SectionName + NewStatement SaveFileOnChange(ContainerFile, Content, False) + if DistHeader.ReadOnly: + os.chmod(ContainerFile, stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH) + else: + os.chmod(ContainerFile, stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH|stat.S_IWUSR|stat.S_IWGRP|stat.S_IWOTH) return ContainerFile +## GenPackageUNIEncodeFile +# GenPackageUNIEncodeFile, default is a UCS-2LE encode file +# +def GenPackageUNIEncodeFile(PackageObject, UniFileHeader = '', Encoding=TAB_ENCODING_UTF16LE): + GenUNIFlag = False + OnlyLANGUAGE_EN_X = True + BinaryAbstract = [] + BinaryDescription = [] + # + # If more than one language code is used for any element that would be present in the PACKAGE_UNI_FILE, + # then the PACKAGE_UNI_FILE must be created. + # + for (Key, Value) in PackageObject.GetAbstract() + PackageObject.GetDescription(): + if Key == TAB_LANGUAGE_EN_X: + GenUNIFlag = True + else: + OnlyLANGUAGE_EN_X = False + + for UserExtension in PackageObject.GetUserExtensionList(): + if UserExtension.GetUserID() == TAB_BINARY_HEADER_USERID \ + and UserExtension.GetIdentifier() == TAB_BINARY_HEADER_IDENTIFIER: + for (Key, Value) in UserExtension.GetBinaryAbstract(): + if Key == TAB_LANGUAGE_EN_X: + GenUNIFlag = True + else: + OnlyLANGUAGE_EN_X = False + BinaryAbstract.append((Key, Value)) + + for (Key, Value) in UserExtension.GetBinaryDescription(): + if Key == TAB_LANGUAGE_EN_X: + GenUNIFlag = True + else: + OnlyLANGUAGE_EN_X = False + BinaryDescription.append((Key, Value)) + + for Pcd in PackageObject.GetPcdList(): + for TxtObj in Pcd.GetPromptList() + Pcd.GetHelpTextList(): + if TxtObj.GetLang() == TAB_LANGUAGE_EN_X: + GenUNIFlag = True + else: + OnlyLANGUAGE_EN_X = False + + for PcdError in Pcd.GetPcdErrorsList(): + if PcdError.GetErrorNumber().startswith('0x') or PcdError.GetErrorNumber().startswith('0X'): + for (Key, Value) in PcdError.GetErrorMessageList(): + if Key == TAB_LANGUAGE_EN_X: + GenUNIFlag = True + else: + OnlyLANGUAGE_EN_X = False + if not GenUNIFlag: + return + elif OnlyLANGUAGE_EN_X: + return + else: + PackageObject.UNIFlag = True + + if not os.path.exists(os.path.dirname(PackageObject.GetFullPath())): + os.makedirs(os.path.dirname(PackageObject.GetFullPath())) + ContainerFile = os.path.normpath(os.path.join(os.path.dirname(PackageObject.GetFullPath()), + (PackageObject.GetBaseName() + '.uni'))) + + Content = UniFileHeader + os.linesep + Content += os.linesep + + Content += FormatUniEntry('#string ' + TAB_DEC_PACKAGE_ABSTRACT, PackageObject.GetAbstract(), ContainerFile) \ + + os.linesep + + Content += FormatUniEntry('#string ' + TAB_DEC_PACKAGE_DESCRIPTION, PackageObject.GetDescription(), ContainerFile) \ + + os.linesep + + Content += FormatUniEntry('#string ' + TAB_DEC_BINARY_ABSTRACT, BinaryAbstract, ContainerFile) \ + + os.linesep + + Content += FormatUniEntry('#string ' + TAB_DEC_BINARY_DESCRIPTION, BinaryDescription, ContainerFile) \ + + os.linesep + + PromptGenList = [] + HelpTextGenList = [] + for Pcd in PackageObject.GetPcdList(): + # Generate Prompt for each Pcd + PcdPromptStrName = '#string ' + 'STR_' + Pcd.GetTokenSpaceGuidCName() + '_' + Pcd.GetCName() + '_PROMPT ' + TokenValueList = [] + for TxtObj in Pcd.GetPromptList(): + Lang = TxtObj.GetLang() + PromptStr = TxtObj.GetString() + # + # Avoid generating the same PROMPT entry more than one time. + # + if (PcdPromptStrName, Lang) not in PromptGenList: + TokenValueList.append((Lang, PromptStr)) + PromptGenList.append((PcdPromptStrName, Lang)) + PromptString = FormatUniEntry(PcdPromptStrName, TokenValueList, ContainerFile) + os.linesep + if PromptString not in Content: + Content += PromptString + + # Generate Help String for each Pcd + PcdHelpStrName = '#string ' + 'STR_' + Pcd.GetTokenSpaceGuidCName() + '_' + Pcd.GetCName() + '_HELP ' + TokenValueList = [] + for TxtObj in Pcd.GetHelpTextList(): + Lang = TxtObj.GetLang() + HelpStr = TxtObj.GetString() + # + # Avoid generating the same HELP entry more than one time. + # + if (PcdHelpStrName, Lang) not in HelpTextGenList: + TokenValueList.append((Lang, HelpStr)) + HelpTextGenList.append((PcdHelpStrName, Lang)) + HelpTextString = FormatUniEntry(PcdHelpStrName, TokenValueList, ContainerFile) + os.linesep + if HelpTextString not in Content: + Content += HelpTextString + + # Generate PcdError for each Pcd if ErrorNo exist. + for PcdError in Pcd.GetPcdErrorsList(): + ErrorNo = PcdError.GetErrorNumber() + if ErrorNo.startswith(TAB_HEX_START) or ErrorNo.startswith(TAB_CAPHEX_START): + PcdErrStrName = '#string ' + TAB_STR_TOKENCNAME + TAB_UNDERLINE_SPLIT + Pcd.GetTokenSpaceGuidCName() \ + + TAB_UNDERLINE_SPLIT + TAB_STR_TOKENERR \ + + TAB_UNDERLINE_SPLIT + ErrorNo[2:] + PcdErrString = FormatUniEntry(PcdErrStrName, PcdError.GetErrorMessageList(), ContainerFile) + os.linesep + if PcdErrString not in Content: + Content += PcdErrString + + File = codecs.open(ContainerFile, 'w', Encoding) + File.write(u'\uFEFF' + Content) + File.stream.close() + Md5Sigature = md5.new(__FileHookOpen__(str(ContainerFile), 'rb').read()) + Md5Sum = Md5Sigature.hexdigest() + if (ContainerFile, Md5Sum) not in PackageObject.FileList: + PackageObject.FileList.append((ContainerFile, Md5Sum)) + + return ContainerFile + ## GenPcdErrComment # # @param PcdErrObject: PcdErrorObject @@ -347,21 +660,30 @@ def PackageToDec(Package): # @retval CommentStr: Generated comment lines, with prefix "#" # def GenPcdErrComment (PcdErrObject): - EndOfLine = "\n" + CommentStr = '' + ErrorCode = PcdErrObject.GetErrorNumber() ValidValueRange = PcdErrObject.GetValidValueRange() if ValidValueRange: - CommentStr = "# @ValidRange " + ValidValueRange + EndOfLine + CommentStr = TAB_COMMENT_SPLIT + TAB_SPACE_SPLIT + TAB_PCD_VALIDRANGE + TAB_SPACE_SPLIT + if ErrorCode: + CommentStr += ErrorCode + TAB_SPACE_SPLIT + TAB_VALUE_SPLIT + TAB_SPACE_SPLIT + CommentStr += ValidValueRange + END_OF_LINE ValidValue = PcdErrObject.GetValidValue() if ValidValue: ValidValueList = \ [Value for Value in ValidValue.split(TAB_SPACE_SPLIT) if Value] - CommentStr = \ - "# @ValidList " + TAB_COMMA_SPLIT.join(ValidValueList) + EndOfLine + CommentStr = TAB_COMMENT_SPLIT + TAB_SPACE_SPLIT + TAB_PCD_VALIDLIST + TAB_SPACE_SPLIT + if ErrorCode: + CommentStr += ErrorCode + TAB_SPACE_SPLIT + TAB_VALUE_SPLIT + TAB_SPACE_SPLIT + CommentStr += TAB_COMMA_SPLIT.join(ValidValueList) + END_OF_LINE Expression = PcdErrObject.GetExpression() if Expression: - CommentStr = "# @Expression " + Expression + EndOfLine + CommentStr = TAB_COMMENT_SPLIT + TAB_SPACE_SPLIT + TAB_PCD_EXPRESSION + TAB_SPACE_SPLIT + if ErrorCode: + CommentStr += ErrorCode + TAB_SPACE_SPLIT + TAB_VALUE_SPLIT + TAB_SPACE_SPLIT + CommentStr += Expression + END_OF_LINE return CommentStr diff --git a/BaseTools/Source/Python/UPT/GenMetaFile/GenInfFile.py b/BaseTools/Source/Python/UPT/GenMetaFile/GenInfFile.py index 78bb6ea4f1..0daa96af25 100644 --- a/BaseTools/Source/Python/UPT/GenMetaFile/GenInfFile.py +++ b/BaseTools/Source/Python/UPT/GenMetaFile/GenInfFile.py @@ -2,7 +2,7 @@ # # This file contained the logical of transfer package object to INF files. # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -15,16 +15,22 @@ ''' GenInf ''' -from os import getenv +import os +import stat +import codecs +import md5 +from Core.FileHook import __FileHookOpen__ from Library.String import GetSplitValueList from Library.Parsing import GenSection from Library.Parsing import GetWorkspacePackage -from Library.Parsing import ConvertArchForInstall +from Library.Parsing import ConvertArchForInstall from Library.Misc import SaveFileOnChange from Library.Misc import IsAllModuleList from Library.Misc import Sdict from Library.Misc import ConvertPath from Library.Misc import ConvertSpec +from Library.Misc import GetRelativePath +from Library.Misc import GetLocalValue from Library.CommentGenerating import GenHeaderCommentSection from Library.CommentGenerating import GenGenericCommentF from Library.CommentGenerating import _GetHelpStr @@ -34,29 +40,107 @@ from Logger import ToolError import Logger.Log as Logger from Library import DataType as DT from GenMetaFile import GenMetaFileMisc +from Library.UniClassObject import FormatUniEntry + ## Transfer Module Object to Inf files # # Transfer all contents of a standard Module Object to an Inf file # @param ModuleObject: A Module Object # -def ModuleToInf(ModuleObject): - if not GlobalData.gWSPKG_LIST: +def ModuleToInf(ModuleObject, PackageObject=None, DistHeader=None): + if not GlobalData.gWSPKG_LIST: GlobalData.gWSPKG_LIST = GetWorkspacePackage() - # # Init global information for the file # ContainerFile = ModuleObject.GetFullPath() + Content = '' # - # generate header comment section + # Generate file header, If any Abstract, Description, Copyright or License XML elements are missing, + # should 1) use the Abstract, Description, Copyright or License from the PackageSurfaceArea.Header elements + # that the module belongs to, or 2) if this is a stand-alone module that is not included in a PackageSurfaceArea, + # use the abstract, description, copyright or license from the DistributionPackage.Header elements. + # + ModuleAbstract = GetLocalValue(ModuleObject.GetAbstract()) + if not ModuleAbstract and PackageObject: + ModuleAbstract = GetLocalValue(PackageObject.GetAbstract()) + if not ModuleAbstract and DistHeader: + ModuleAbstract = GetLocalValue(DistHeader.GetAbstract()) + ModuleDescription = GetLocalValue(ModuleObject.GetDescription()) + if not ModuleDescription and PackageObject: + ModuleDescription = GetLocalValue(PackageObject.GetDescription()) + if not ModuleDescription and DistHeader: + ModuleDescription = GetLocalValue(DistHeader.GetDescription()) + ModuleCopyright = '' + for (Lang, Copyright) in ModuleObject.GetCopyright(): + if Lang: + pass + ModuleCopyright = Copyright + if not ModuleCopyright and PackageObject: + for (Lang, Copyright) in PackageObject.GetCopyright(): + if Lang: + pass + ModuleCopyright = Copyright + if not ModuleCopyright and DistHeader: + for (Lang, Copyright) in DistHeader.GetCopyright(): + if Lang: + pass + ModuleCopyright = Copyright + ModuleLicense = '' + for (Lang, License) in ModuleObject.GetLicense(): + if Lang: + pass + ModuleLicense = License + if not ModuleLicense and PackageObject: + for (Lang, License) in PackageObject.GetLicense(): + if Lang: + pass + ModuleLicense = License + if not ModuleLicense and DistHeader: + for (Lang, License) in DistHeader.GetLicense(): + if Lang: + pass + ModuleLicense = License + + # + # Generate header comment section of INF file # - Content += GenHeaderCommentSection(ModuleObject.GetAbstract(), - ModuleObject.GetDescription(), - ModuleObject.GetCopyright(), - ModuleObject.GetLicense()) - + Content += GenHeaderCommentSection(ModuleAbstract, + ModuleDescription, + ModuleCopyright, + ModuleLicense) + + # + # Generate Binary Header + # + for UserExtension in ModuleObject.GetUserExtensionList(): + if UserExtension.GetUserID() == DT.TAB_BINARY_HEADER_USERID \ + and UserExtension.GetIdentifier() == DT.TAB_BINARY_HEADER_IDENTIFIER: + ModuleBinaryAbstract = GetLocalValue(UserExtension.GetBinaryAbstract()) + ModuleBinaryDescription = GetLocalValue(UserExtension.GetBinaryDescription()) + ModuleBinaryCopyright = '' + ModuleBinaryLicense = '' + for (Lang, Copyright) in UserExtension.GetBinaryCopyright(): + ModuleBinaryCopyright = Copyright + for (Lang, License) in UserExtension.GetBinaryLicense(): + ModuleBinaryLicense = License + if ModuleBinaryAbstract and ModuleBinaryDescription and \ + ModuleBinaryCopyright and ModuleBinaryLicense: + Content += GenHeaderCommentSection(ModuleBinaryAbstract, + ModuleBinaryDescription, + ModuleBinaryCopyright, + ModuleBinaryLicense, + True) + + # + # Generate MODULE_UNI_FILE for module + # + FileHeader = GenHeaderCommentSection(ModuleAbstract, ModuleDescription, ModuleCopyright, ModuleLicense, False, \ + DT.TAB_COMMENT_EDK1_SPLIT) + GenModuleUNIEncodeFile(ModuleObject, FileHeader) + # # Judge whether the INF file is an AsBuild INF. # @@ -64,15 +148,12 @@ def ModuleToInf(ModuleObject): GlobalData.gIS_BINARY_INF = True else: GlobalData.gIS_BINARY_INF = False - # # for each section, maintain a dict, sorted arch will be its key, # statement list will be its data # { 'Arch1 Arch2 Arch3': [statement1, statement2], # 'Arch1' : [statement1, statement3] # } - # - # # Gen section contents # @@ -82,36 +163,110 @@ def ModuleToInf(ModuleObject): Content += GenPackages(ModuleObject) Content += GenPcdSections(ModuleObject) Content += GenSources(ModuleObject) - Content += GenProtocolPPiSections(ModuleObject.GetProtocolList(), True) - Content += GenProtocolPPiSections(ModuleObject.GetPpiList(), False) - Content += GenGuidSections(ModuleObject.GetGuidList()) + Content += GenProtocolPPiSections(ModuleObject.GetProtocolList(), True) + Content += GenProtocolPPiSections(ModuleObject.GetPpiList(), False) + Content += GenGuidSections(ModuleObject.GetGuidList()) Content += GenBinaries(ModuleObject) Content += GenDepex(ModuleObject) - Content += GenUserExtensions(ModuleObject) - + Content += GenUserExtensions(ModuleObject) if ModuleObject.GetEventList() or ModuleObject.GetBootModeList() or ModuleObject.GetHobList(): - Content += '\n\n' + Content += '\n' # # generate [Event], [BootMode], [Hob] section # - Content += GenSpecialSections(ModuleObject.GetEventList(), 'Event') + Content += GenSpecialSections(ModuleObject.GetEventList(), 'Event') Content += GenSpecialSections(ModuleObject.GetBootModeList(), 'BootMode') Content += GenSpecialSections(ModuleObject.GetHobList(), 'Hob') - SaveFileOnChange(ContainerFile, Content, False) + if DistHeader.ReadOnly: + os.chmod(ContainerFile, stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH) + else: + os.chmod(ContainerFile, stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH|stat.S_IWUSR|stat.S_IWGRP|stat.S_IWOTH) return ContainerFile +## GenModuleUNIEncodeFile +# GenModuleUNIEncodeFile, default is a UCS-2LE encode file +# +def GenModuleUNIEncodeFile(ModuleObject, UniFileHeader='', Encoding=DT.TAB_ENCODING_UTF16LE): + GenUNIFlag = False + OnlyLANGUAGE_EN_X = True + BinaryAbstract = [] + BinaryDescription = [] + # + # If more than one language code is used for any element that would be present in the MODULE_UNI_FILE, + # then the MODULE_UNI_FILE must be created. + # + for (Key, Value) in ModuleObject.GetAbstract() + ModuleObject.GetDescription(): + if Key == DT.TAB_LANGUAGE_EN_X: + GenUNIFlag = True + else: + OnlyLANGUAGE_EN_X = False + + for UserExtension in ModuleObject.GetUserExtensionList(): + if UserExtension.GetUserID() == DT.TAB_BINARY_HEADER_USERID \ + and UserExtension.GetIdentifier() == DT.TAB_BINARY_HEADER_IDENTIFIER: + for (Key, Value) in UserExtension.GetBinaryAbstract(): + if Key == DT.TAB_LANGUAGE_EN_X: + GenUNIFlag = True + else: + OnlyLANGUAGE_EN_X = False + BinaryAbstract.append((Key, Value)) + for (Key, Value) in UserExtension.GetBinaryDescription(): + if Key == DT.TAB_LANGUAGE_EN_X: + GenUNIFlag = True + else: + OnlyLANGUAGE_EN_X = False + BinaryDescription.append((Key, Value)) + + + if not GenUNIFlag: + return + elif OnlyLANGUAGE_EN_X: + return + else: + ModuleObject.UNIFlag = True + ContainerFile = os.path.normpath(os.path.join(os.path.dirname(ModuleObject.GetFullPath()), + (ModuleObject.GetBaseName() + '.uni'))) + if not os.path.exists(os.path.dirname(ModuleObject.GetFullPath())): + os.makedirs(os.path.dirname(ModuleObject.GetFullPath())) + + Content = UniFileHeader + os.linesep + Content += DT.END_OF_LINE + + Content += FormatUniEntry('#string ' + DT.TAB_INF_ABSTRACT, ModuleObject.GetAbstract(), ContainerFile) + os.linesep + + Content += FormatUniEntry('#string ' + DT.TAB_INF_DESCRIPTION, ModuleObject.GetDescription(), ContainerFile) \ + + os.linesep + + BinaryAbstractString = FormatUniEntry('#string ' + DT.TAB_INF_BINARY_ABSTRACT, BinaryAbstract, ContainerFile) + if BinaryAbstractString: + Content += BinaryAbstractString + os.linesep + + BinaryDescriptionString = FormatUniEntry('#string ' + DT.TAB_INF_BINARY_DESCRIPTION, BinaryDescription, \ + ContainerFile) + if BinaryDescriptionString: + Content += BinaryDescriptionString + os.linesep + + if not os.path.exists(ContainerFile): + File = codecs.open(ContainerFile, 'wb', Encoding) + File.write(u'\uFEFF' + Content) + File.stream.close() + Md5Sigature = md5.new(__FileHookOpen__(str(ContainerFile), 'rb').read()) + Md5Sum = Md5Sigature.hexdigest() + if (ContainerFile, Md5Sum) not in ModuleObject.FileList: + ModuleObject.FileList.append((ContainerFile, Md5Sum)) + + return ContainerFile def GenDefines(ModuleObject): # # generate [Defines] section # - Content = '' - NewSectionDict = {} + Content = '' + NewSectionDict = {} for UserExtension in ModuleObject.GetUserExtensionList(): DefinesDict = UserExtension.GetDefinesDict() if not DefinesDict: continue - for Statement in DefinesDict: SortedArch = DT.TAB_ARCH_COMMON if Statement.strip().startswith(DT.TAB_INF_DEFINES_CUSTOM_MAKEFILE): @@ -123,52 +278,79 @@ def GenDefines(ModuleObject): if SortedArch in NewSectionDict: NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement] else: - NewSectionDict[SortedArch] = [Statement] - + NewSectionDict[SortedArch] = [Statement] SpecialStatementList = [] - # # Add INF_VERSION statement firstly # - Statement = 'INF_VERSION = 0x00010017' + + LeftOffset = 31 + # TAB_INF_DEFINES_INF_VERSION + Statement = (u'%s ' % DT.TAB_INF_DEFINES_INF_VERSION).ljust(LeftOffset) + u'= %s' % '0x00010017' SpecialStatementList.append(Statement) + # BaseName BaseName = ModuleObject.GetBaseName() if BaseName.startswith('.') or BaseName.startswith('-'): BaseName = '_' + BaseName - Statement = '%s = %s' % (DT.TAB_INF_DEFINES_BASE_NAME, BaseName) + Statement = (u'%s ' % DT.TAB_INF_DEFINES_BASE_NAME).ljust(LeftOffset) + u'= %s' % BaseName SpecialStatementList.append(Statement) - Statement = '%s = %s' % (DT.TAB_INF_DEFINES_FILE_GUID, ModuleObject.GetGuid()) - SpecialStatementList.append(Statement) - Statement = '%s = %s' % (DT.TAB_INF_DEFINES_VERSION_STRING, ModuleObject.GetVersion()) + + # TAB_INF_DEFINES_FILE_GUID + Statement = (u'%s ' % DT.TAB_INF_DEFINES_FILE_GUID).ljust(LeftOffset) + u'= %s' % ModuleObject.GetGuid() SpecialStatementList.append(Statement) + # TAB_INF_DEFINES_VERSION_STRING + Statement = (u'%s ' % DT.TAB_INF_DEFINES_VERSION_STRING).ljust(LeftOffset) + u'= %s' % ModuleObject.GetVersion() + SpecialStatementList.append(Statement) + + # TAB_INF_DEFINES_VERSION_STRING + if ModuleObject.UNIFlag: + Statement = (u'%s ' % DT.TAB_INF_DEFINES_MODULE_UNI_FILE).ljust(LeftOffset) + \ + u'= %s' % ModuleObject.GetBaseName() + '.uni' + SpecialStatementList.append(Statement) + + # TAB_INF_DEFINES_MODULE_TYPE if ModuleObject.GetModuleType(): - Statement = '%s = %s' % (DT.TAB_INF_DEFINES_MODULE_TYPE, ModuleObject.GetModuleType()) + Statement = (u'%s ' % DT.TAB_INF_DEFINES_MODULE_TYPE).ljust(LeftOffset) + u'= %s' % ModuleObject.GetModuleType() SpecialStatementList.append(Statement) + + # TAB_INF_DEFINES_PCD_IS_DRIVER if ModuleObject.GetPcdIsDriver(): - Statement = '%s = %s' % (DT.TAB_INF_DEFINES_PCD_IS_DRIVER, ModuleObject.GetPcdIsDriver()) + Statement = (u'%s ' % DT.TAB_INF_DEFINES_PCD_IS_DRIVER).ljust(LeftOffset) + \ + u'= %s' % ModuleObject.GetPcdIsDriver() SpecialStatementList.append(Statement) + + # TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION if ModuleObject.GetUefiSpecificationVersion(): - Statement = '%s = %s' % (DT.TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION, \ - ModuleObject.GetUefiSpecificationVersion()) + Statement = (u'%s ' % DT.TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION).ljust(LeftOffset) + \ + u'= %s' % ModuleObject.GetUefiSpecificationVersion() SpecialStatementList.append(Statement) + + # TAB_INF_DEFINES_PI_SPECIFICATION_VERSION if ModuleObject.GetPiSpecificationVersion(): - Statement = '%s = %s' % (DT.TAB_INF_DEFINES_PI_SPECIFICATION_VERSION, ModuleObject.GetPiSpecificationVersion()) - SpecialStatementList.append(Statement) + Statement = (u'%s ' % DT.TAB_INF_DEFINES_PI_SPECIFICATION_VERSION).ljust(LeftOffset) + \ + u'= %s' % ModuleObject.GetPiSpecificationVersion() + SpecialStatementList.append(Statement) + + # LibraryClass for LibraryClass in ModuleObject.GetLibraryClassList(): if LibraryClass.GetUsage() == DT.USAGE_ITEM_PRODUCES or \ LibraryClass.GetUsage() == DT.USAGE_ITEM_SOMETIMES_PRODUCES: - Statement = '%s = %s' % (DT.TAB_INF_DEFINES_LIBRARY_CLASS, LibraryClass.GetLibraryClass()) + Statement = (u'%s ' % DT.TAB_INF_DEFINES_LIBRARY_CLASS).ljust(LeftOffset) + \ + u'= %s' % LibraryClass.GetLibraryClass() if LibraryClass.GetSupModuleList(): Statement += '|' + DT.TAB_SPACE_SPLIT.join(l for l in LibraryClass.GetSupModuleList()) SpecialStatementList.append(Statement) + + # Spec Item for SpecItem in ModuleObject.GetSpecList(): Spec, Version = SpecItem Spec = ConvertSpec(Spec) Statement = '%s %s = %s' % (DT.TAB_INF_DEFINES_SPEC, Spec, Version) SpecialStatementList.append(Statement) - + + # Extern ExternList = [] for Extern in ModuleObject.GetExternList(): ArchList = Extern.GetSupArchList() @@ -179,27 +361,23 @@ def GenDefines(ModuleObject): HelpStringList = Extern.GetHelpTextList() FFE = Extern.GetFeatureFlag() ExternList.append([ArchList, EntryPoint, UnloadImage, Constructor, Destructor, FFE, HelpStringList]) - # # Add VALID_ARCHITECTURES information # ValidArchStatement = None if ModuleObject.SupArchList: - ValidArchStatement = '# ' + '\n' + ValidArchStatement = '\n' + '# ' + '\n' ValidArchStatement += '# The following information is for reference only and not required by the build tools.\n' ValidArchStatement += '# ' + '\n' ValidArchStatement += '# VALID_ARCHITECTURES = %s' % (' '.join(ModuleObject.SupArchList)) + '\n' - ValidArchStatement += '# ' + '\n' - + ValidArchStatement += '# ' if DT.TAB_ARCH_COMMON not in NewSectionDict: NewSectionDict[DT.TAB_ARCH_COMMON] = [] NewSectionDict[DT.TAB_ARCH_COMMON] = NewSectionDict[DT.TAB_ARCH_COMMON] + SpecialStatementList GenMetaFileMisc.AddExternToDefineSec(NewSectionDict, DT.TAB_ARCH_COMMON, ExternList) if ValidArchStatement is not None: NewSectionDict[DT.TAB_ARCH_COMMON] = NewSectionDict[DT.TAB_ARCH_COMMON] + [ValidArchStatement] - Content += GenSection('Defines', NewSectionDict) - return Content def GenLibraryClasses(ModuleObject): @@ -223,17 +401,16 @@ def GenLibraryClasses(ModuleObject): FFE = LibraryClass.GetFeatureFlag() Statement += Name if FFE: - Statement += '|' + FFE + Statement += '|' + FFE ModuleList = LibraryClass.GetSupModuleList() ArchList = LibraryClass.GetSupArchList() for Index in xrange(0, len(ArchList)): ArchList[Index] = ConvertArchForInstall(ArchList[Index]) ArchList.sort() SortedArch = ' '.join(ArchList) - KeyList = [] if not ModuleList or IsAllModuleList(ModuleList): - KeyList = [SortedArch] + KeyList = [SortedArch] else: ModuleString = DT.TAB_VALUE_SPLIT.join(l for l in ModuleList) if not ArchList: @@ -241,7 +418,6 @@ def GenLibraryClasses(ModuleObject): KeyList = [SortedArch + '.' + ModuleString] else: KeyList = [Arch + '.' + ModuleString for Arch in ArchList] - for Key in KeyList: if Key in NewSectionDict: NewSectionDict[Key] = NewSectionDict[Key] + [Statement] @@ -254,9 +430,10 @@ def GenLibraryClasses(ModuleObject): if not BinaryFile.AsBuiltList: continue for LibraryItem in BinaryFile.AsBuiltList[0].LibraryInstancesList: - Statement = '# Guid: ' + LibraryItem.Guid + ' Version: ' + LibraryItem.Version + Statement = '# Guid: ' + LibraryItem.Guid + ' Version: ' + LibraryItem.Version + if len(BinaryFile.SupArchList) == 0: - if LibraryClassDict.has_key('COMMON'): + if LibraryClassDict.has_key('COMMON') and Statement not in LibraryClassDict['COMMON']: LibraryClassDict['COMMON'].append(Statement) else: LibraryClassDict['COMMON'] = ['## @LIB_INSTANCES'] @@ -264,13 +441,15 @@ def GenLibraryClasses(ModuleObject): else: for Arch in BinaryFile.SupArchList: if LibraryClassDict.has_key(Arch): - LibraryClassDict[Arch].append(Statement) + if Statement not in LibraryClassDict[Arch]: + LibraryClassDict[Arch].append(Statement) + else: + continue else: LibraryClassDict[Arch] = ['## @LIB_INSTANCES'] LibraryClassDict[Arch].append(Statement) - Content += GenSection('LibraryClasses', LibraryClassDict) - + return Content def GenPackages(ModuleObject): @@ -279,7 +458,7 @@ def GenPackages(ModuleObject): # generate [Packages] section # NewSectionDict = Sdict() - WorkspaceDir = getenv('WORKSPACE') + WorkspaceDir = GlobalData.gWORKSPACE for PackageDependency in ModuleObject.GetPackageDependencyList(): # # Generate generic comment @@ -288,11 +467,12 @@ def GenPackages(ModuleObject): HelpText = PackageDependency.GetHelpText() if HelpText: HelpStr = HelpText.GetString() - CommentStr = GenGenericCommentF(HelpStr) + CommentStr = GenGenericCommentF(HelpStr) Statement = CommentStr Guid = PackageDependency.GetGuid() Version = PackageDependency.GetVersion() FFE = PackageDependency.GetFeatureFlag() + Path = '' # # find package path/name # @@ -304,20 +484,18 @@ def GenPackages(ModuleObject): # # get relative path # - RelaPath = Path[Path.upper().find(WorkspaceDir.upper()) + len(WorkspaceDir) + 1:] + RelaPath = GetRelativePath(Path, WorkspaceDir) Statement += RelaPath.replace('\\', '/') if FFE: - Statement += '|' + FFE + Statement += '|' + FFE ArchList = PackageDependency.GetSupArchList() ArchList.sort() SortedArch = ' '.join(ArchList) if SortedArch in NewSectionDict: NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement] else: - NewSectionDict[SortedArch] = [Statement] - + NewSectionDict[SortedArch] = [Statement] Content += GenSection('Packages', NewSectionDict) - return Content def GenSources(ModuleObject): @@ -326,23 +504,20 @@ def GenSources(ModuleObject): # Content = '' NewSectionDict = {} - - for Source in ModuleObject.GetSourceFileList(): + for Source in ModuleObject.GetSourceFileList(): SourceFile = Source.GetSourceFile() Family = Source.GetFamily() FeatureFlag = Source.GetFeatureFlag() SupArchList = Source.GetSupArchList() SupArchList.sort() - SortedArch = ' '.join(SupArchList) - + SortedArch = ' '.join(SupArchList) Statement = GenSourceStatement(ConvertPath(SourceFile), Family, FeatureFlag) if SortedArch in NewSectionDict: NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement] else: NewSectionDict[SortedArch] = [Statement] - Content += GenSection('Sources', NewSectionDict) - + return Content def GenDepex(ModuleObject): @@ -359,7 +534,6 @@ def GenDepex(ModuleObject): SupModList = Depex.GetModuleType() Expression = Depex.GetDepex() Statement = CommentStr + Expression - SupArchList.sort() KeyList = [] if not SupArchList: @@ -370,17 +544,14 @@ def GenDepex(ModuleObject): for ModuleType in SupModList: for Arch in SupArchList: KeyList.append(ConvertArchForInstall(Arch) + '.' + ModuleType) - for Key in KeyList: if Key in NewSectionDict: NewSectionDict[Key] = NewSectionDict[Key] + [Statement] else: NewSectionDict[Key] = [Statement] - Content += GenSection('Depex', NewSectionDict, False) return Content - ## GenUserExtensions # # GenUserExtensions @@ -388,17 +559,18 @@ def GenDepex(ModuleObject): def GenUserExtensions(ModuleObject): NewSectionDict = {} for UserExtension in ModuleObject.GetUserExtensionList(): + if UserExtension.GetUserID() == DT.TAB_BINARY_HEADER_USERID and \ + UserExtension.GetIdentifier() == DT.TAB_BINARY_HEADER_IDENTIFIER: + continue if UserExtension.GetIdentifier() == 'Depex': continue Statement = UserExtension.GetStatement() if not Statement: continue - ArchList = UserExtension.GetSupArchList() for Index in xrange(0, len(ArchList)): ArchList[Index] = ConvertArchForInstall(ArchList[Index]) ArchList.sort() - KeyList = [] CommonPreFix = '' if UserExtension.GetUserID(): @@ -410,17 +582,16 @@ def GenUserExtensions(ModuleObject): if ArchList: KeyList = [CommonPreFix + '.' + Arch for Arch in ArchList] else: - KeyList = [CommonPreFix] - + KeyList = [CommonPreFix] for Key in KeyList: if Key in NewSectionDict: NewSectionDict[Key] = NewSectionDict[Key] + [Statement] else: NewSectionDict[Key] = [Statement] Content = GenSection('UserExtensions', NewSectionDict, False) - + return Content - + # GenSourceStatement # # @param SourceFile: string of source file path/name @@ -432,23 +603,21 @@ def GenUserExtensions(ModuleObject): # # @retval Statement: The generated statement for source # -def GenSourceStatement(SourceFile, Family, FeatureFlag, TagName=None, +def GenSourceStatement(SourceFile, Family, FeatureFlag, TagName=None, ToolCode=None, HelpStr=None): Statement = '' if HelpStr: - Statement += GenGenericCommentF(HelpStr) + Statement += GenGenericCommentF(HelpStr) # # format of SourceFile|Family|TagName|ToolCode|FeatureFlag # Statement += SourceFile - if TagName == None: TagName = '' if ToolCode == None: ToolCode = '' if HelpStr == None: HelpStr = '' - if FeatureFlag: Statement += '|' + Family + '|' + TagName + '|' + ToolCode + '|' + FeatureFlag elif ToolCode: @@ -457,7 +626,6 @@ def GenSourceStatement(SourceFile, Family, FeatureFlag, TagName=None, Statement += '|' + Family + '|' + TagName elif Family: Statement += '|' + Family - return Statement # GenBinaryStatement @@ -466,7 +634,7 @@ def GenSourceStatement(SourceFile, Family, FeatureFlag, TagName=None, # @param Value: (Target, Family, TagName, Comment) # # -def GenBinaryStatement(Key, Value): +def GenBinaryStatement(Key, Value, SubTypeGuidValue=None): (FileName, FileType, FFE, SortedArch) = Key if SortedArch: pass @@ -477,14 +645,14 @@ def GenBinaryStatement(Key, Value): Family = '' TagName = '' Comment = '' - if Comment: Statement = GenGenericCommentF(Comment) else: Statement = '' - - Statement += FileType + '|' + FileName - + if FileType == 'SUBTYPE_GUID' and SubTypeGuidValue: + Statement += FileType + '|' + SubTypeGuidValue + '|' + FileName + else: + Statement += FileType + '|' + FileName if FileType in DT.BINARY_FILE_TYPE_UI_LIST + DT.BINARY_FILE_TYPE_VER_LIST: if FFE: Statement += '|' + Target + '|' + FFE @@ -499,9 +667,7 @@ def GenBinaryStatement(Key, Value): Statement += '|' + Target + '|' + Family elif Target: Statement += '|' + Target - return Statement - ## GenGuidSections # # @param GuidObjList: List of GuidObject @@ -511,26 +677,21 @@ def GenGuidSections(GuidObjList): # # generate [Guids] section # - Content = '' + Content = '' GuidDict = Sdict() - for Guid in GuidObjList: HelpTextList = Guid.GetHelpTextList() HelpStr = _GetHelpStr(HelpTextList) - CName = Guid.GetCName() FFE = Guid.GetFeatureFlag() Statement = CName if FFE: Statement += '|' + FFE - Usage = Guid.GetUsage() GuidType = Guid.GetGuidTypeList()[0] VariableName = Guid.GetVariableName() - # - # we need to differentiate the generic comment and usage comment - # as multiple generic comment need to be put at first + # Differentiate the generic comment and usage comment as multiple generic comment need to be put at first # if Usage == DT.ITEM_UNDEFINED and GuidType == DT.ITEM_UNDEFINED: # generate list of generic comment @@ -543,17 +704,15 @@ def GenGuidSections(GuidObjList): Comment = ' # ' + Comment else: Comment = '' - if Usage != DT.ITEM_UNDEFINED and GuidType == DT.ITEM_UNDEFINED: - Comment = '## ' + Usage + Comment + Comment = '## ' + Usage + ' ## GUID ' + Comment elif GuidType == 'Variable': Comment = '## ' + Usage + ' ## ' + GuidType + ':' + VariableName + Comment else: Comment = '## ' + Usage + ' ## ' + GuidType + Comment - + if Comment: Comment += '\n' - # # merge duplicate items # @@ -562,18 +721,15 @@ def GenGuidSections(GuidObjList): SortedArch = ' '.join(ArchList) if (Statement, SortedArch) in GuidDict: PreviousComment = GuidDict[Statement, SortedArch] - Comment = PreviousComment + Comment + Comment = PreviousComment + Comment GuidDict[Statement, SortedArch] = Comment - - - NewSectionDict = GenMetaFileMisc.TransferDict(GuidDict) - + NewSectionDict = GenMetaFileMisc.TransferDict(GuidDict, 'INF_GUID') # # generate the section contents # if NewSectionDict: Content = GenSection('Guids', NewSectionDict) - + return Content ## GenProtocolPPiSections @@ -587,19 +743,15 @@ def GenProtocolPPiSections(ObjList, IsProtocol): for Object in ObjList: HelpTextList = Object.GetHelpTextList() HelpStr = _GetHelpStr(HelpTextList) - CName = Object.GetCName() FFE = Object.GetFeatureFlag() Statement = CName if FFE: Statement += '|' + FFE - Usage = Object.GetUsage() Notify = Object.GetNotify() - # - # we need to differentiate the generic comment and usage comment - # as consecutive generic comment need to be put together + # Differentiate the generic comment and usage comment as consecutive generic comment need to be put together # if Usage == DT.ITEM_UNDEFINED and Notify == '': # generate list of generic comment @@ -612,7 +764,6 @@ def GenProtocolPPiSections(ObjList, IsProtocol): Comment = ' # ' + Comment else: Comment = '' - if Usage == DT.ITEM_UNDEFINED and not Comment and Notify == '': Comment = '' else: @@ -620,10 +771,8 @@ def GenProtocolPPiSections(ObjList, IsProtocol): Comment = '## ' + Usage + ' ## ' + 'NOTIFY' + Comment else: Comment = '## ' + Usage + Comment - if Comment: Comment += '\n' - # # merge duplicate items # @@ -634,9 +783,7 @@ def GenProtocolPPiSections(ObjList, IsProtocol): PreviousComment = Dict[Statement, SortedArch] Comment = PreviousComment + Comment Dict[Statement, SortedArch] = Comment - - NewSectionDict = GenMetaFileMisc.TransferDict(Dict) - + NewSectionDict = GenMetaFileMisc.TransferDict(Dict, 'INF_PPI_PROTOCOL') # # generate the section contents # @@ -645,7 +792,7 @@ def GenProtocolPPiSections(ObjList, IsProtocol): Content = GenSection('Protocols', NewSectionDict) else: Content = GenSection('Ppis', NewSectionDict) - + return Content ## GenPcdSections @@ -662,7 +809,6 @@ def GenPcdSections(ModuleObject): for Pcd in ModuleObject.GetPcdList(): HelpTextList = Pcd.GetHelpTextList() HelpStr = _GetHelpStr(HelpTextList) - Statement = '' CName = Pcd.GetCName() TokenSpaceGuidCName = Pcd.GetTokenSpaceGuidCName() @@ -673,7 +819,6 @@ def GenPcdSections(ModuleObject): else: Dict = Sdict() ItemTypeDict[ItemType] = Dict - FFE = Pcd.GetFeatureFlag() Statement += TokenSpaceGuidCName + '.' + CName if DefaultValue: @@ -682,18 +827,14 @@ def GenPcdSections(ModuleObject): Statement += '|' + FFE elif FFE: Statement += '||' + FFE - # # Generate comment # Usage = Pcd.GetValidUsage() - - # # if FeatureFlag Pcd, then assume all Usage is CONSUMES - # if ItemType == DT.TAB_INF_FEATURE_PCD: Usage = DT.USAGE_ITEM_CONSUMES - if Usage == DT.ITEM_UNDEFINED or (ItemType == DT.TAB_INF_FEATURE_PCD): + if Usage == DT.ITEM_UNDEFINED: # generate list of generic comment Comment = GenGenericCommentF(HelpStr) else: @@ -704,12 +845,9 @@ def GenPcdSections(ModuleObject): Comment = ' # ' + Comment else: Comment = '' - Comment = '## ' + Usage + Comment - if Comment: Comment += '\n' - # # Merge duplicate entries # @@ -719,15 +857,11 @@ def GenPcdSections(ModuleObject): if (Statement, SortedArch) in Dict: PreviousComment = Dict[Statement, SortedArch] Comment = PreviousComment + Comment - Dict[Statement, SortedArch] = Comment - + Dict[Statement, SortedArch] = Comment for ItemType in ItemTypeDict: - # # First we need to transfer the Dict to use SortedArch as key - # Dict = ItemTypeDict[ItemType] - NewSectionDict = GenMetaFileMisc.TransferDict(Dict) - + NewSectionDict = GenMetaFileMisc.TransferDict(Dict, 'INF_PCD') if NewSectionDict: Content += GenSection(ItemType, NewSectionDict) # @@ -736,7 +870,7 @@ def GenPcdSections(ModuleObject): else: Content += GenAsBuiltPacthPcdSections(ModuleObject) Content += GenAsBuiltPcdExSections(ModuleObject) - + return Content ## GenPcdSections @@ -746,8 +880,8 @@ def GenAsBuiltPacthPcdSections(ModuleObject): PatchPcdDict = {} for BinaryFile in ModuleObject.GetBinaryFileList(): if not BinaryFile.AsBuiltList: - continue - for PatchPcd in BinaryFile.AsBuiltList[0].PatchPcdList: + continue + for PatchPcd in BinaryFile.AsBuiltList[0].PatchPcdList: TokenSpaceName = '' PcdCName = PatchPcd.CName PcdValue = PatchPcd.DefaultValue @@ -758,31 +892,38 @@ def GenAsBuiltPacthPcdSections(ModuleObject): HelpString = '' for HelpStringItem in HelpTextList: for HelpLine in GetSplitValueList(HelpStringItem.String, '\n'): - HelpString += '# ' + HelpLine + '\n' - - TokenSpaceName, PcdCName = GenMetaFileMisc.ObtainPcdName(ModuleObject.PackageDependencyList, - TokenSpaceGuidValue, + HelpString += '## ' + HelpLine + '\n' + TokenSpaceName, PcdCName = GenMetaFileMisc.ObtainPcdName(ModuleObject.PackageDependencyList, + TokenSpaceGuidValue, Token) - if TokenSpaceName == '' or PcdCName == '': - Logger.Error("Upt", + if TokenSpaceName == '' or PcdCName == '': + Logger.Error("Upt", ToolError.RESOURCE_NOT_AVAILABLE, - ST.ERR_INSTALL_FILE_DEC_FILE_ERROR%(TokenSpaceGuidValue, Token), - File=ModuleObject.GetFullPath()) - Statement = HelpString[:-3] + TokenSpaceName + '.' + PcdCName + ' | ' + PcdValue + ' | ' + PcdOffset - - if len(BinaryFile.SupArchList) == 0: - if PatchPcdDict.has_key('COMMON'): - PatchPcdDict['COMMON'].append(Statement) + ST.ERR_INSTALL_FILE_DEC_FILE_ERROR % (TokenSpaceGuidValue, Token), + File=ModuleObject.GetFullPath()) + Statement = HelpString + TokenSpaceName + '.' + PcdCName + ' | ' + PcdValue + ' | ' + \ + PcdOffset + DT.TAB_SPACE_SPLIT + # + # Use binary file's Arch to be Pcd's Arch + # + ArchList = [] + FileNameObjList = BinaryFile.GetFileNameList() + if FileNameObjList: + ArchList = FileNameObjList[0].GetSupArchList() + if len(ArchList) == 0: + if PatchPcdDict.has_key(DT.TAB_ARCH_COMMON): + if Statement not in PatchPcdDict[DT.TAB_ARCH_COMMON]: + PatchPcdDict[DT.TAB_ARCH_COMMON].append(Statement) else: - PatchPcdDict['COMMON'] = [Statement] + PatchPcdDict[DT.TAB_ARCH_COMMON] = [Statement] else: - for Arch in BinaryFile.SupArchList: + for Arch in ArchList: if PatchPcdDict.has_key(Arch): - PatchPcdDict[Arch].append(Statement) + if Statement not in PatchPcdDict[Arch]: + PatchPcdDict[Arch].append(Statement) else: PatchPcdDict[Arch] = [Statement] - return GenSection('PatchPcd', PatchPcdDict) - + return GenSection(DT.TAB_INF_PATCH_PCD, PatchPcdDict) ## GenPcdSections # # @@ -790,42 +931,49 @@ def GenAsBuiltPcdExSections(ModuleObject): PcdExDict = {} for BinaryFile in ModuleObject.GetBinaryFileList(): if not BinaryFile.AsBuiltList: - continue + continue for PcdExItem in BinaryFile.AsBuiltList[0].PcdExValueList: TokenSpaceName = '' PcdCName = PcdExItem.CName - PcdValue = PcdExItem.DefaultValue TokenSpaceGuidValue = PcdExItem.TokenSpaceGuidValue Token = PcdExItem.Token HelpTextList = PcdExItem.HelpTextList HelpString = '' for HelpStringItem in HelpTextList: for HelpLine in GetSplitValueList(HelpStringItem.String, '\n'): - HelpString += '# ' + HelpLine + '\n' - TokenSpaceName, PcdCName = GenMetaFileMisc.ObtainPcdName(ModuleObject.PackageDependencyList, + HelpString += '## ' + HelpLine + '\n' + TokenSpaceName, PcdCName = GenMetaFileMisc.ObtainPcdName(ModuleObject.PackageDependencyList, TokenSpaceGuidValue, Token) - - if TokenSpaceName == '' or PcdCName == '': + if TokenSpaceName == '' or PcdCName == '': Logger.Error("Upt", ToolError.RESOURCE_NOT_AVAILABLE, - ST.ERR_INSTALL_FILE_DEC_FILE_ERROR%(TokenSpaceGuidValue, Token), - File=ModuleObject.GetFullPath()) - - Statement = HelpString[:-3] + TokenSpaceName + '.' + PcdCName + ' | ' + PcdValue - - if len(BinaryFile.SupArchList) == 0: + ST.ERR_INSTALL_FILE_DEC_FILE_ERROR % (TokenSpaceGuidValue, Token), + File=ModuleObject.GetFullPath()) + + Statement = HelpString + TokenSpaceName + DT.TAB_SPLIT + PcdCName + DT.TAB_SPACE_SPLIT + + # + # Use binary file's Arch to be Pcd's Arch + # + ArchList = [] + FileNameObjList = BinaryFile.GetFileNameList() + if FileNameObjList: + ArchList = FileNameObjList[0].GetSupArchList() + + if len(ArchList) == 0: if PcdExDict.has_key('COMMON'): PcdExDict['COMMON'].append(Statement) else: PcdExDict['COMMON'] = [Statement] else: - for Arch in BinaryFile.SupArchList: + for Arch in ArchList: if PcdExDict.has_key(Arch): - PcdExDict[Arch].append(Statement) + if Statement not in PcdExDict[Arch]: + PcdExDict[Arch].append(Statement) else: PcdExDict[Arch] = [Statement] return GenSection('PcdEx', PcdExDict) - + ## GenSpecialSections # generate special sections for Event/BootMode/Hob # @@ -843,7 +991,6 @@ def GenSpecialSections(ObjectList, SectionName): HelpTextList = Obj.GetHelpTextList() HelpStr = _GetHelpStr(HelpTextList) CommentStr = GenGenericCommentF(HelpStr) - if SectionName == 'Hob': Type = Obj.GetHobType() elif SectionName == 'Event': @@ -852,25 +999,20 @@ def GenSpecialSections(ObjectList, SectionName): Type = Obj.GetSupportedBootModes() else: assert(SectionName) - Usage = Obj.GetUsage() Statement = ' ' + Type + ' ## ' + Usage - if CommentStr in ['#\n', '#\n#\n']: CommentStr = '#\n#\n#\n' # - # the first head comment line should start with '##\n', - # if it starts with '#\n', then add one '#' + # the first head comment line should start with '##\n', if it starts with '#\n', then add one '#' # else add '##\n' to meet the format defined in INF spec # if CommentStr.startswith('#\n'): CommentStr = '#' + CommentStr elif CommentStr: CommentStr = '##\n' + CommentStr - if CommentStr and not CommentStr.endswith('\n#\n'): - CommentStr = CommentStr + '#\n' - + CommentStr = CommentStr + '#\n' NewStateMent = CommentStr + Statement SupArch = Obj.GetSupArchList() SupArch.sort() @@ -879,20 +1021,17 @@ def GenSpecialSections(ObjectList, SectionName): NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [NewStateMent] else: NewSectionDict[SortedArch] = [NewStateMent] - SectionContent = GenSection(SectionName, NewSectionDict) SectionContent = SectionContent.strip() if SectionContent: Content = '# ' + ('\n' + '# ').join(GetSplitValueList(SectionContent, '\n')) Content = Content.lstrip() # - # add two empty line after the generated section content to differentiate - # it between other possible sections - # - if Content: + # add two empty line after the generated section content to differentiate it between other possible sections + # + if Content: Content += '\n#\n#\n' return Content - ## GenBuildOptions # # @@ -912,7 +1051,6 @@ def GenBuildOptions(ModuleObject): NewSectionDict[Arch] = NewSectionDict[Arch] + [BuildOptionDict[Arch]] else: NewSectionDict[Arch] = [BuildOptionDict[Arch]] - Content = GenSection('BuildOptions', NewSectionDict) else: BuildOptionDict = {} @@ -920,7 +1058,7 @@ def GenBuildOptions(ModuleObject): if not BinaryFile.AsBuiltList: continue for BuilOptionItem in BinaryFile.AsBuiltList[0].BinaryBuildFlagList: - Statement = '#' + BuilOptionItem.AsBuiltOptionFlags + Statement = '#' + BuilOptionItem.AsBuiltOptionFlags if len(BinaryFile.SupArchList) == 0: if BuildOptionDict.has_key('COMMON'): if Statement not in BuildOptionDict['COMMON']: @@ -936,11 +1074,9 @@ def GenBuildOptions(ModuleObject): else: BuildOptionDict[Arch] = ['## @AsBuilt'] BuildOptionDict[Arch].append(Statement) - Content = GenSection('BuildOptions', BuildOptionDict) - - return Content + return Content ## GenBinaries # # @@ -951,7 +1087,6 @@ def GenBinaries(ModuleObject): BinariesDict = UserExtension.GetBinariesDict() if BinariesDict: break - for BinaryFile in ModuleObject.GetBinaryFileList(): FileNameObjList = BinaryFile.GetFileNameList() for FileNameObj in FileNameObjList: @@ -960,10 +1095,8 @@ def GenBinaries(ModuleObject): FFE = FileNameObj.GetFeatureFlag() ArchList = FileNameObj.GetSupArchList() ArchList.sort() - SortedArch = ' '.join(ArchList) - + SortedArch = ' '.join(ArchList) Key = (FileName, FileType, FFE, SortedArch) - if Key in BinariesDict: ValueList = BinariesDict[Key] for ValueItem in ValueList: @@ -973,16 +1106,19 @@ def GenBinaries(ModuleObject): else: NewSectionDict[SortedArch] = [Statement] # - # as we already generated statement for this DictKey - # here set the Valuelist to be empty to avoid generate duplicate entries - # as the DictKey may have multiple entries + # as we already generated statement for this DictKey here set the Valuelist to be empty + # to avoid generate duplicate entries as the DictKey may have multiple entries # BinariesDict[Key] = [] else: - Statement = GenBinaryStatement(Key, None) + if FileType == 'SUBTYPE_GUID' and FileNameObj.GetGuidValue(): + Statement = GenBinaryStatement(Key, None, FileNameObj.GetGuidValue()) + else: + Statement = GenBinaryStatement(Key, None) if SortedArch in NewSectionDict: NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement] else: - NewSectionDict[SortedArch] = [Statement] - - return GenSection('Binaries', NewSectionDict) \ No newline at end of file + NewSectionDict[SortedArch] = [Statement] + Content = GenSection('Binaries', NewSectionDict) + + return Content diff --git a/BaseTools/Source/Python/UPT/GenMetaFile/GenMetaFileMisc.py b/BaseTools/Source/Python/UPT/GenMetaFile/GenMetaFileMisc.py index 54c113a9d0..0a8624c67f 100644 --- a/BaseTools/Source/Python/UPT/GenMetaFile/GenMetaFileMisc.py +++ b/BaseTools/Source/Python/UPT/GenMetaFile/GenMetaFileMisc.py @@ -2,7 +2,7 @@ # # This file contained the miscellaneous routines for GenMetaFile usage. # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -28,10 +28,11 @@ from Parser.DecParser import Dec # @param ExternList: string of source file FeatureFlag field # def AddExternToDefineSec(SectionDict, Arch, ExternList): + LeftOffset = 31 for ArchList, EntryPoint, UnloadImage, Constructor, Destructor, FFE, HelpStringList in ExternList: if Arch or ArchList: if EntryPoint: - Statement = '%s = %s' % (DT.TAB_INF_DEFINES_ENTRY_POINT, EntryPoint) + Statement = (u'%s ' % DT.TAB_INF_DEFINES_ENTRY_POINT).ljust(LeftOffset) + u'= %s' % EntryPoint if FFE: Statement += ' | %s' % FFE if len(HelpStringList) > 0: @@ -39,37 +40,40 @@ def AddExternToDefineSec(SectionDict, Arch, ExternList): if len(HelpStringList) > 1: Statement = Statement + HelpStringList[1].GetString() SectionDict[Arch] = SectionDict[Arch] + [Statement] + if UnloadImage: - Statement = '%s = %s' % (DT.TAB_INF_DEFINES_UNLOAD_IMAGE, UnloadImage) + Statement = (u'%s ' % DT.TAB_INF_DEFINES_UNLOAD_IMAGE).ljust(LeftOffset) + u'= %s' % UnloadImage if FFE: Statement += ' | %s' % FFE - + if len(HelpStringList) > 0: Statement = HelpStringList[0].GetString() + '\n' + Statement if len(HelpStringList) > 1: Statement = Statement + HelpStringList[1].GetString() SectionDict[Arch] = SectionDict[Arch] + [Statement] + if Constructor: - Statement = '%s = %s' % (DT.TAB_INF_DEFINES_CONSTRUCTOR, Constructor) + Statement = (u'%s ' % DT.TAB_INF_DEFINES_CONSTRUCTOR).ljust(LeftOffset) + u'= %s' % Constructor if FFE: Statement += ' | %s' % FFE - + if len(HelpStringList) > 0: Statement = HelpStringList[0].GetString() + '\n' + Statement if len(HelpStringList) > 1: - Statement = Statement + HelpStringList[1].GetString() - SectionDict[Arch] = SectionDict[Arch] + [Statement] + Statement = Statement + HelpStringList[1].GetString() + SectionDict[Arch] = SectionDict[Arch] + [Statement] + if Destructor: - Statement = '%s = %s' % (DT.TAB_INF_DEFINES_DESTRUCTOR, Destructor) + Statement = (u'%s ' % DT.TAB_INF_DEFINES_DESTRUCTOR).ljust(LeftOffset) + u'= %s' % Destructor if FFE: Statement += ' | %s' % FFE - + if len(HelpStringList) > 0: Statement = HelpStringList[0].GetString() + '\n' + Statement if len(HelpStringList) > 1: Statement = Statement + HelpStringList[1].GetString() SectionDict[Arch] = SectionDict[Arch] + [Statement] - + ## ObtainPcdName # # Using TokenSpaceGuidValue and Token to obtain PcdName from DEC file @@ -81,7 +85,7 @@ def ObtainPcdName(Packages, TokenSpaceGuidValue, Token): # Guid = PackageDependency.GetGuid() Version = PackageDependency.GetVersion() - + # # find package path/name # @@ -90,16 +94,22 @@ def ObtainPcdName(Packages, TokenSpaceGuidValue, Token): if (not Version) or (Version == PkgInfo[2]): Path = PkgInfo[3] break - - DecFile = Dec(Path) + + DecFile = None + if Path not in GlobalData.gPackageDict: + DecFile = Dec(Path) + GlobalData.gPackageDict[Path] = DecFile + else: + DecFile = GlobalData.gPackageDict[Path] + DecGuidsDict = DecFile.GetGuidSectionObject().ValueDict DecPcdsDict = DecFile.GetPcdSectionObject().ValueDict - + TokenSpaceGuidName = '' PcdCName = '' TokenSpaceGuidNameFound = False PcdCNameFound = False - + # # Get TokenSpaceGuidCName from Guids section # @@ -108,24 +118,24 @@ def ObtainPcdName(Packages, TokenSpaceGuidValue, Token): if TokenSpaceGuidNameFound: break for GuidItem in GuidList: - if TokenSpaceGuidValue == GuidItem.GuidString: + if TokenSpaceGuidValue.upper() == GuidItem.GuidString.upper(): TokenSpaceGuidName = GuidItem.GuidCName TokenSpaceGuidNameFound = True break - + # # Retrieve PcdCName from Pcds Section # for PcdKey in DecPcdsDict: PcdList = DecPcdsDict[PcdKey] if PcdCNameFound: - break + return TokenSpaceGuidName, PcdCName for PcdItem in PcdList: if TokenSpaceGuidName == PcdItem.TokenSpaceGuidCName and Token == PcdItem.TokenValue: PcdCName = PcdItem.TokenCName PcdCNameFound = True - break - + break + return TokenSpaceGuidName, PcdCName ## _TransferDict @@ -133,23 +143,35 @@ def ObtainPcdName(Packages, TokenSpaceGuidValue, Token): # (GenericComment, UsageComment) as value into a dict that using SortedArch as # key and NewStatement as value # -def TransferDict(OrigDict): +def TransferDict(OrigDict, Type=None): NewDict = {} - + LeftOffset = 0 + if Type in ['INF_GUID', 'INF_PPI_PROTOCOL']: + LeftOffset = 45 + if Type in ['INF_PCD']: + LeftOffset = 75 + if LeftOffset > 0: + for Statement, SortedArch in OrigDict: + if len(Statement) > LeftOffset: + LeftOffset = len(Statement) + for Statement, SortedArch in OrigDict: Comment = OrigDict[Statement, SortedArch] # # apply the NComment/1Comment rule # - if Comment.find('\n') != len(Comment) - 1: + if Comment.find('\n') != len(Comment) - 1: NewStateMent = Comment + Statement else: - NewStateMent = Statement + ' ' + Comment.rstrip('\n') + if LeftOffset: + NewStateMent = Statement.ljust(LeftOffset) + ' ' + Comment.rstrip('\n') + else: + NewStateMent = Statement + ' ' + Comment.rstrip('\n') if SortedArch in NewDict: NewDict[SortedArch] = NewDict[SortedArch] + [NewStateMent] else: NewDict[SortedArch] = [NewStateMent] - return NewDict - \ No newline at end of file + return NewDict + diff --git a/BaseTools/Source/Python/UPT/InstallPkg.py b/BaseTools/Source/Python/UPT/InstallPkg.py index 776196e8ea..3084b60bff 100644 --- a/BaseTools/Source/Python/UPT/InstallPkg.py +++ b/BaseTools/Source/Python/UPT/InstallPkg.py @@ -1,7 +1,7 @@ ## @file # Install distribution package. # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -17,12 +17,14 @@ Install a distribution package ## # Import Modules # +from Core.FileHook import __FileHookOpen__ import os.path from os import chmod from os import SEEK_SET from os import SEEK_END import stat import md5 +import copy from sys import stdin from sys import platform from shutil import rmtree @@ -42,7 +44,6 @@ from Logger.ToolError import FORMAT_INVALID from Logger.ToolError import FILE_TYPE_MISMATCH import Logger.Log as Logger -from Library.Misc import CheckEnvVariable from Library.Misc import Sdict from Library.Misc import ConvertPath from Library.ParserValidate import IsValidInstallPath @@ -83,7 +84,6 @@ def InstallNewPackage(WorkspaceDir, Path, CustomPath = False): Input = Input.replace('\r', '').replace('\n', '') return InstallNewPackage(WorkspaceDir, Input, False) - ## InstallNewModule # # @param WorkspaceDir: Workspace Directory @@ -133,10 +133,9 @@ def InstallNewFile(WorkspaceDir, File): # # UnZipDp # -def UnZipDp(WorkspaceDir, Options, DataBase): +def UnZipDp(WorkspaceDir, DpPkgFileName): ContentZipFile = None Logger.Quiet(ST.MSG_UZIP_PARSE_XML) - DpPkgFileName = Options.PackageFile DistFile = PackageFile(DpPkgFileName) DpDescFileName, ContentFileName = GetDPFile(DistFile.GetZipFile()) @@ -156,26 +155,7 @@ def UnZipDp(WorkspaceDir, Options, DataBase): DistPkg.Header.RePackage = False if DistPkg.Header.ReadOnly == '': DistPkg.Header.ReadOnly = False - - # - # prepare check dependency - # - Dep = DependencyRules(DataBase) - # - # Check distribution package installed or not - # - if Dep.CheckDpExists(DistPkg.Header.GetGuid(), - DistPkg.Header.GetVersion()): - Logger.Error("InstallPkg", UPT_ALREADY_INSTALLED_ERROR, - ST.WRN_DIST_PKG_INSTALLED) - # - # Check distribution dependency (all module dependency should be - # satisfied) - # - if not Dep.CheckDpDepexSatisfied(DistPkg): - Logger.Error("InstallPkg", UNKNOWN_ERROR, - ST.ERR_PACKAGE_NOT_MATCH_DEPENDENCY, - ExtraData=DistPkg.Header.Name) + # # unzip contents.zip file # @@ -185,7 +165,7 @@ def UnZipDp(WorkspaceDir, Options, DataBase): Logger.Error("InstallPkg", FILE_NOT_FOUND, ST.ERR_FILE_BROKEN % ContentFileName) - FilePointer = open(ContentFile, "rb") + FilePointer = __FileHookOpen__(ContentFile, "rb") # # Assume no archive comment. # @@ -204,13 +184,13 @@ def UnZipDp(WorkspaceDir, Options, DataBase): # verify MD5 signature when existed # if DistPkg.Header.Signature != '': - Md5Sigature = md5.new(open(ContentFile, 'rb').read()) + Md5Sigature = md5.new(__FileHookOpen__(ContentFile, 'rb').read()) if DistPkg.Header.Signature != Md5Sigature.hexdigest(): ContentZipFile.Close() Logger.Error("InstallPkg", FILE_CHECKSUM_FAILURE, ExtraData=ContentFile) - return DistPkg, Dep, ContentZipFile, DpPkgFileName + return DistPkg, ContentZipFile, DpPkgFileName, DistFile ## GetPackageList # @@ -224,7 +204,11 @@ def GetPackageList(DistPkg, Dep, WorkspaceDir, Options, ContentZipFile, ModuleLi Logger.Info(ST.MSG_INSTALL_PACKAGE % Package.GetName()) if Dep.CheckPackageExists(Guid, Version): Logger.Info(ST.WRN_PACKAGE_EXISTED %(Guid, Version)) - NewPackagePath = InstallNewPackage(WorkspaceDir, PackagePath, Options.CustomPath) + if Options.UseGuidedPkgPath: + GuidedPkgPath = "%s_%s_%s" % (Package.GetName(), Guid, Version) + NewPackagePath = InstallNewPackage(WorkspaceDir, GuidedPkgPath, Options.CustomPath) + else: + NewPackagePath = InstallNewPackage(WorkspaceDir, PackagePath, Options.CustomPath) InstallPackageContent(PackagePath, NewPackagePath, Package, ContentZipFile, Dep, WorkspaceDir, ModuleList, DistPkg.Header.ReadOnly) PackageList.append(Package) @@ -238,8 +222,8 @@ def GetPackageList(DistPkg, Dep, WorkspaceDir, Options, ContentZipFile, ModuleLi # dependency (Hard to get the location of the newly installed package) # for Package in PackageList: - FilePath = PackageToDec(Package) - Md5Sigature = md5.new(open(str(FilePath), 'rb').read()) + FilePath = PackageToDec(Package, DistPkg.Header) + Md5Sigature = md5.new(__FileHookOpen__(str(FilePath), 'rb').read()) Md5Sum = Md5Sigature.hexdigest() if (FilePath, Md5Sum) not in Package.FileList: Package.FileList.append((FilePath, Md5Sum)) @@ -258,7 +242,7 @@ def GetModuleList(DistPkg, Dep, WorkspaceDir, ContentZipFile, ModuleList): # install them directly. If not, we will try to create a new directory # for it. # - ModulePathList = [] + ModulePathList = [] # # Check module exist and install @@ -297,8 +281,9 @@ def GetModuleList(DistPkg, Dep, WorkspaceDir, ContentZipFile, ModuleList): # generate all inf for modules # for (Module, Package) in ModuleList: - FilePath = ModuleToInf(Module) - Md5Sigature = md5.new(open(str(FilePath), 'rb').read()) + CheckCNameInModuleRedefined(Module, DistPkg) + FilePath = ModuleToInf(Module, Package, DistPkg.Header) + Md5Sigature = md5.new(__FileHookOpen__(str(FilePath), 'rb').read()) Md5Sum = Md5Sigature.hexdigest() if Package: if (FilePath, Md5Sum) not in Package.FileList: @@ -306,9 +291,167 @@ def GetModuleList(DistPkg, Dep, WorkspaceDir, ContentZipFile, ModuleList): else: if (FilePath, Md5Sum) not in Module.FileList: Module.FileList.append((FilePath, Md5Sum)) + # + # append the module unicode files to Package FileList + # + for (FilePath, Md5Sum) in Module.FileList: + if str(FilePath).endswith('.uni') and Package and (FilePath, Md5Sum) not in Package.FileList: + Package.FileList.append((FilePath, Md5Sum)) return NewDict +## +# Get all protocol/ppi/guid CNames and pcd name from all dependent DEC file +# +def GetDepProtocolPpiGuidPcdNames(DePackageObjList): + # + # [[Dec1Protocol1, Dec1Protocol2...], [Dec2Protocols...],...] + # + DependentProtocolCNames = [] + DependentPpiCNames = [] + DependentGuidCNames = [] + DependentPcdNames = [] + + for PackageObj in DePackageObjList: + # + # Get protocol CName list from all dependent DEC file + # + ProtocolCNames = [] + for Protocol in PackageObj.GetProtocolList(): + if Protocol.GetCName() not in ProtocolCNames: + ProtocolCNames.append(Protocol.GetCName()) + + DependentProtocolCNames.append(ProtocolCNames) + + # + # Get Ppi CName list from all dependent DEC file + # + PpiCNames = [] + for Ppi in PackageObj.GetPpiList(): + if Ppi.GetCName() not in PpiCNames: + PpiCNames.append(Ppi.GetCName()) + + DependentPpiCNames.append(PpiCNames) + + # + # Get Guid CName list from all dependent DEC file + # + GuidCNames = [] + for Guid in PackageObj.GetGuidList(): + if Guid.GetCName() not in GuidCNames: + GuidCNames.append(Guid.GetCName()) + + DependentGuidCNames.append(GuidCNames) + + # + # Get PcdName list from all dependent DEC file + # + PcdNames = [] + for Pcd in PackageObj.GetPcdList(): + PcdName = '.'.join([Pcd.GetTokenSpaceGuidCName(), Pcd.GetCName()]) + if PcdName not in PcdNames: + PcdNames.append(PcdName) + + DependentPcdNames.append(PcdNames) + + + return DependentProtocolCNames, DependentPpiCNames, DependentGuidCNames, DependentPcdNames + +## +# Check if protocol CName is redefined +# +def CheckProtoclCNameRedefined(Module, DependentProtocolCNames): + for ProtocolInModule in Module.GetProtocolList(): + IsCNameDefined = False + for PackageProtocolCNames in DependentProtocolCNames: + if ProtocolInModule.GetCName() in PackageProtocolCNames: + if IsCNameDefined: + Logger.Error("\nUPT", FORMAT_INVALID, + File = Module.GetFullPath(), + ExtraData = \ + ST.ERR_INF_PARSER_ITEM_DUPLICATE_IN_DEC % ProtocolInModule.GetCName()) + else: + IsCNameDefined = True + +## +# Check if Ppi CName is redefined +# +def CheckPpiCNameRedefined(Module, DependentPpiCNames): + for PpiInModule in Module.GetPpiList(): + IsCNameDefined = False + for PackagePpiCNames in DependentPpiCNames: + if PpiInModule.GetCName() in PackagePpiCNames: + if IsCNameDefined: + Logger.Error("\nUPT", FORMAT_INVALID, + File = Module.GetFullPath(), + ExtraData = ST.ERR_INF_PARSER_ITEM_DUPLICATE_IN_DEC % PpiInModule.GetCName()) + else: + IsCNameDefined = True + +## +# Check if Guid CName is redefined +# +def CheckGuidCNameRedefined(Module, DependentGuidCNames): + for GuidInModule in Module.GetGuidList(): + IsCNameDefined = False + for PackageGuidCNames in DependentGuidCNames: + if GuidInModule.GetCName() in PackageGuidCNames: + if IsCNameDefined: + Logger.Error("\nUPT", FORMAT_INVALID, + File = Module.GetFullPath(), + ExtraData = \ + ST.ERR_INF_PARSER_ITEM_DUPLICATE_IN_DEC % GuidInModule.GetCName()) + else: + IsCNameDefined = True + +## +# Check if PcdName is redefined +# +def CheckPcdNameRedefined(Module, DependentPcdNames): + PcdObjs = [] + if not Module.GetBinaryFileList(): + PcdObjs += Module.GetPcdList() + else: + Binary = Module.GetBinaryFileList()[0] + for AsBuild in Binary.GetAsBuiltList(): + PcdObjs += AsBuild.GetPatchPcdList() + AsBuild.GetPcdExList() + + for PcdObj in PcdObjs: + PcdName = '.'.join([PcdObj.GetTokenSpaceGuidCName(), PcdObj.GetCName()]) + IsPcdNameDefined = False + for PcdNames in DependentPcdNames: + if PcdName in PcdNames: + if IsPcdNameDefined: + Logger.Error("\nUPT", FORMAT_INVALID, + File = Module.GetFullPath(), + ExtraData = ST.ERR_INF_PARSER_ITEM_DUPLICATE_IN_DEC % PcdName) + else: + IsPcdNameDefined = True + +## +# Check if any Protocol/Ppi/Guid and Pcd name is redefined in its dependent DEC files +# +def CheckCNameInModuleRedefined(Module, DistPkg): + DePackageObjList = [] + # + # Get all dependent package objects + # + for Obj in Module.GetPackageDependencyList(): + Guid = Obj.GetGuid() + Version = Obj.GetVersion() + for Key in DistPkg.PackageSurfaceArea: + if Key[0] == Guid and Key[1] == Version: + if DistPkg.PackageSurfaceArea[Key] not in DePackageObjList: + DePackageObjList.append(DistPkg.PackageSurfaceArea[Key]) + + DependentProtocolCNames, DependentPpiCNames, DependentGuidCNames, DependentPcdNames = \ + GetDepProtocolPpiGuidPcdNames(DePackageObjList) + + CheckProtoclCNameRedefined(Module, DependentProtocolCNames) + CheckPpiCNameRedefined(Module, DependentPpiCNames) + CheckGuidCNameRedefined(Module, DependentGuidCNames) + CheckPcdNameRedefined(Module, DependentPcdNames) + ## GenToolMisc # # GenToolMisc @@ -369,8 +512,7 @@ def Main(Options = None): ContentZipFile, DistFile = None, None try: - DataBase = GlobalData.gDB - CheckEnvVariable() + DataBase = GlobalData.gDB WorkspaceDir = GlobalData.gWORKSPACE if not Options.PackageFile: Logger.Error("InstallPkg", OPTION_MISSING, ExtraData=ST.ERR_SPECIFY_PACKAGE) @@ -378,63 +520,30 @@ def Main(Options = None): # # unzip dist.pkg file # - DistPkg, Dep, ContentZipFile, DpPkgFileName = UnZipDp(WorkspaceDir, Options, DataBase) - - # - # PackageList, ModuleList record the information for the meta-data - # files that need to be generated later - # - PackageList = [] - ModuleList = [] - DistPkg.PackageSurfaceArea = GetPackageList(DistPkg, Dep, WorkspaceDir, Options, - ContentZipFile, ModuleList, PackageList) + DistPkg, ContentZipFile, DpPkgFileName, DistFile = UnZipDp(WorkspaceDir, Options.PackageFile) - DistPkg.ModuleSurfaceArea = GetModuleList(DistPkg, Dep, WorkspaceDir, ContentZipFile, ModuleList) - - - GenToolMisc(DistPkg, WorkspaceDir, ContentZipFile) - # - # copy "Distribution File" to directory $(WORKSPACE)/conf/upt + # check dependency # - DistFileName = os.path.split(DpPkgFileName)[1] - DestDir = os.path.normpath(os.path.join(WorkspaceDir, GlobalData.gUPT_DIR)) - CreateDirectory(DestDir) - DestFile = os.path.normpath(os.path.join(DestDir, DistFileName)) - if os.path.exists(DestFile): - FileName, Ext = os.path.splitext(DistFileName) - NewFileName = FileName + '_' + DistPkg.Header.GetGuid() + '_' + DistPkg.Header.GetVersion() + Ext - DestFile = os.path.normpath(os.path.join(DestDir, NewFileName)) - if os.path.exists(DestFile): - # - # ask for user input the new file name - # - Logger.Info( ST.MSG_NEW_FILE_NAME_FOR_DIST) - Input = stdin.readline() - Input = Input.replace('\r', '').replace('\n', '') - DestFile = os.path.normpath(os.path.join(DestDir, Input)) - copyfile(DpPkgFileName, DestFile) - NewDpPkgFileName = DestFile[DestFile.find(DestDir) + len(DestDir) + 1:] + Dep = DependencyRules(DataBase) + CheckInstallDpx(Dep, DistPkg) # - # update database + # Install distribution # - Logger.Quiet(ST.MSG_UPDATE_PACKAGE_DATABASE) - DataBase.AddDPObject(DistPkg, NewDpPkgFileName, DistFileName, - DistPkg.Header.RePackage) - + InstallDp(DistPkg, DpPkgFileName, ContentZipFile, Options, Dep, WorkspaceDir, DataBase) ReturnCode = 0 except FatalError, XExcept: ReturnCode = XExcept.args[0] if Logger.GetLevel() <= Logger.DEBUG_9: - Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), - platform) + format_exc()) + Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), platform) + format_exc()) + except KeyboardInterrupt: ReturnCode = ABORT_ERROR if Logger.GetLevel() <= Logger.DEBUG_9: - Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), - platform) + format_exc()) + Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), platform) + format_exc()) + except: ReturnCode = CODE_ERROR Logger.Error( @@ -446,7 +555,6 @@ def Main(Options = None): ) Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), platform) + format_exc()) - finally: Logger.Quiet(ST.MSG_REMOVE_TEMP_FILE_STARTED) if DistFile: @@ -457,12 +565,66 @@ def Main(Options = None): rmtree(GlobalData.gUNPACK_DIR) GlobalData.gUNPACK_DIR = None Logger.Quiet(ST.MSG_REMOVE_TEMP_FILE_DONE) - if ReturnCode == 0: Logger.Quiet(ST.MSG_FINISH) - return ReturnCode +# BackupDist method +# +# This method will backup the Distribution file into the $(WORKSPACE)/conf/upt, and rename it +# if there is already a same-named distribution existed. +# +# @param DpPkgFileName: The distribution path +# @param Guid: The distribution Guid +# @param Version: The distribution Version +# @param WorkspaceDir: The workspace directory +# @retval NewDpPkgFileName: The exact backup file name +# +def BackupDist(DpPkgFileName, Guid, Version, WorkspaceDir): + DistFileName = os.path.split(DpPkgFileName)[1] + DestDir = os.path.normpath(os.path.join(WorkspaceDir, GlobalData.gUPT_DIR)) + CreateDirectory(DestDir) + DestFile = os.path.normpath(os.path.join(DestDir, DistFileName)) + if os.path.exists(DestFile): + FileName, Ext = os.path.splitext(DistFileName) + NewFileName = FileName + '_' + Guid + '_' + Version + Ext + DestFile = os.path.normpath(os.path.join(DestDir, NewFileName)) + if os.path.exists(DestFile): + # + # ask for user input the new file name + # + Logger.Info( ST.MSG_NEW_FILE_NAME_FOR_DIST) + Input = stdin.readline() + Input = Input.replace('\r', '').replace('\n', '') + DestFile = os.path.normpath(os.path.join(DestDir, Input)) + copyfile(DpPkgFileName, DestFile) + NewDpPkgFileName = DestFile[DestFile.find(DestDir) + len(DestDir) + 1:] + return NewDpPkgFileName + +## CheckInstallDpx method +# +# check whether distribution could be installed +# +# @param Dep: the DependencyRules instance that used to check dependency +# @param DistPkg: the distribution object +# +def CheckInstallDpx(Dep, DistPkg): + # + # Check distribution package installed or not + # + if Dep.CheckDpExists(DistPkg.Header.GetGuid(), + DistPkg.Header.GetVersion()): + Logger.Error("InstallPkg", UPT_ALREADY_INSTALLED_ERROR, + ST.WRN_DIST_PKG_INSTALLED) + # + # Check distribution dependency (all module dependency should be + # satisfied) + # + if not Dep.CheckInstallDpDepexSatisfied(DistPkg): + Logger.Error("InstallPkg", UNKNOWN_ERROR, + ST.ERR_PACKAGE_NOT_MATCH_DEPENDENCY, + ExtraData=DistPkg.Header.Name) + ## InstallModuleContent method # # If this is standalone module, then Package should be none, @@ -501,7 +663,7 @@ def InstallModuleContent(FromPath, NewPath, ModulePath, Module, ContentZipFile, if not IsValidInstallPath(File): Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%File) - + FromFile = os.path.join(FromPath, ModulePath, File) Executable = Item.GetExecutable() ToFile = os.path.normpath(os.path.join(NewModuleFullPath, ConvertPath(File))) @@ -575,7 +737,7 @@ def InstallModuleContentZipFile(ContentZipFile, FromPath, ModulePath, WorkspaceD FromFile = FileName ToFile = os.path.normpath(os.path.join(WorkspaceDir, ConvertPath(FileName.replace(FromPath, NewPath, 1)))) - CheckList = Module.FileList + CheckList = copy.copy(Module.FileList) if Package: CheckList += Package.FileList for Item in CheckList: @@ -619,23 +781,28 @@ def FileUnderPath(FileName, CheckPath): # @return: True or False # def InstallFile(ContentZipFile, FromFile, ToFile, ReadOnly, Executable=False): - if not ContentZipFile or not ContentZipFile.UnpackFile(FromFile, ToFile): - Logger.Error("UPT", FILE_NOT_FOUND, ST.ERR_INSTALL_FILE_FROM_EMPTY_CONTENT%FromFile) + if os.path.exists(os.path.normpath(ToFile)): + pass + else: + if not ContentZipFile or not ContentZipFile.UnpackFile(FromFile, ToFile): + Logger.Error("UPT", FILE_NOT_FOUND, ST.ERR_INSTALL_FILE_FROM_EMPTY_CONTENT % FromFile) - if ReadOnly: - if not Executable: - chmod(ToFile, stat.S_IREAD) + if ReadOnly: + if not Executable: + chmod(ToFile, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH) + else: + chmod(ToFile, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH | stat.S_IEXEC | stat.S_IXGRP | stat.S_IXOTH) + elif Executable: + chmod(ToFile, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH | stat.S_IWUSR | stat.S_IWGRP | + stat.S_IWOTH | stat.S_IEXEC | stat.S_IXGRP | stat.S_IXOTH) else: - chmod(ToFile, stat.S_IREAD|stat.S_IEXEC) - elif Executable: - chmod(ToFile, stat.S_IREAD|stat.S_IWRITE|stat.S_IEXEC) - else: - chmod(ToFile, stat.S_IREAD|stat.S_IWRITE) + chmod(ToFile, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH | stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH) - Md5Sigature = md5.new(open(str(ToFile), 'rb').read()) + Md5Sigature = md5.new(__FileHookOpen__(str(ToFile), 'rb').read()) Md5Sum = Md5Sigature.hexdigest() + return Md5Sum - + ## InstallPackageContent method # # @param FromPath: FromPath @@ -701,10 +868,10 @@ def InstallPackageContent(FromPath, ToPath, Package, ContentZipFile, Dep, CreateDirectory(ToFile) continue if ReadOnly: - chmod(ToFile, stat.S_IREAD) + chmod(ToFile, stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH) else: - chmod(ToFile, stat.S_IREAD|stat.S_IWRITE) - Md5Sigature = md5.new(open(str(ToFile), 'rb').read()) + chmod(ToFile, stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH|stat.S_IWUSR|stat.S_IWGRP|stat.S_IWOTH) + Md5Sigature = md5.new(__FileHookOpen__(str(ToFile), 'rb').read()) Md5Sum = Md5Sigature.hexdigest() if (ToFile, Md5Sum) not in Package.FileList: Package.FileList.append((ToFile, Md5Sum)) @@ -768,3 +935,34 @@ def GetDPFile(ZipFile): ExtraData=ST.ERR_DIST_FILE_TOOFEW) return DescFile, ContentFile +## InstallDp method +# +# Install the distribution to current workspace +# +def InstallDp(DistPkg, DpPkgFileName, ContentZipFile, Options, Dep, WorkspaceDir, DataBase): + # + # PackageList, ModuleList record the information for the meta-data + # files that need to be generated later + # + PackageList = [] + ModuleList = [] + DistPkg.PackageSurfaceArea = GetPackageList(DistPkg, Dep, WorkspaceDir, Options, + ContentZipFile, ModuleList, PackageList) + + DistPkg.ModuleSurfaceArea = GetModuleList(DistPkg, Dep, WorkspaceDir, ContentZipFile, ModuleList) + + GenToolMisc(DistPkg, WorkspaceDir, ContentZipFile) + + # + # copy "Distribution File" to directory $(WORKSPACE)/conf/upt + # + DistFileName = os.path.split(DpPkgFileName)[1] + NewDpPkgFileName = BackupDist(DpPkgFileName, DistPkg.Header.GetGuid(), DistPkg.Header.GetVersion(), WorkspaceDir) + + # + # update database + # + Logger.Quiet(ST.MSG_UPDATE_PACKAGE_DATABASE) + DataBase.AddDPObject(DistPkg, NewDpPkgFileName, DistFileName, + DistPkg.Header.RePackage) + diff --git a/BaseTools/Source/Python/UPT/InventoryWs.py b/BaseTools/Source/Python/UPT/InventoryWs.py new file mode 100644 index 0000000000..824e1c2889 --- /dev/null +++ b/BaseTools/Source/Python/UPT/InventoryWs.py @@ -0,0 +1,117 @@ +## @file +# Inventory workspace's distribution package information. +# +# Copyright (c) 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. +# +""" +Inventory workspace's distribution package information. +""" +## +# Import Modules +# +from sys import platform +from traceback import format_exc +from platform import python_version + +from Logger import StringTable as ST +from Logger.ToolError import FatalError +from Logger.ToolError import ABORT_ERROR +from Logger.ToolError import CODE_ERROR +import Logger.Log as Logger + +from Library import GlobalData + +## InventoryDistInstalled +# +# This method retrieves the installed distribution information from the internal UPT database +# +# @param DataBase: the UPT database +# +def InventoryDistInstalled(DataBase): + DistInstalled = DataBase.InventoryDistInstalled() + + # + # find the max length for each item + # + DpNameStr = "DpName" + DpGuidStr = "DpGuid" + DpVerStr = "DpVer" + DpOriginalNameStr = "DpOriginalName" + MaxGuidlen = len(DpGuidStr) + MaxVerlen = len(DpVerStr) + MaxDpAliasFileNameLen = len(DpNameStr) + MaxDpOrigFileNamelen = len(DpOriginalNameStr) + + for (DpGuid, DpVersion, DpOriginalName, DpAliasFileName) in DistInstalled: + MaxGuidlen = max(MaxGuidlen, len(DpGuid)) + MaxVerlen = max(MaxVerlen, len(DpVersion)) + MaxDpAliasFileNameLen = max(MaxDpAliasFileNameLen, len(DpAliasFileName)) + MaxDpOrigFileNamelen = max(MaxDpOrigFileNamelen, len(DpOriginalName)) + + OutMsgFmt = "%-*s\t%-*s\t%-*s\t%-s" + OutMsg = OutMsgFmt % (MaxDpAliasFileNameLen, + DpNameStr, + MaxGuidlen, + DpGuidStr, + MaxVerlen, + DpVerStr, + DpOriginalNameStr) + Logger.Info(OutMsg) + + for (DpGuid, DpVersion, DpFileName, DpAliasFileName) in DistInstalled: + OutMsg = OutMsgFmt % (MaxDpAliasFileNameLen, + DpAliasFileName, + MaxGuidlen, + DpGuid, + MaxVerlen, + DpVersion, + DpFileName) + Logger.Info(OutMsg) + +## Tool entrance method +# +# This method mainly dispatch specific methods per the command line options. +# If no error found, return zero value so the caller of this tool can know +# if it's executed successfully or not. +# +# @param Options: command Options +# +def Main(Options = None): + if Options: + pass + + try: + DataBase = GlobalData.gDB + InventoryDistInstalled(DataBase) + ReturnCode = 0 + except FatalError, XExcept: + ReturnCode = XExcept.args[0] + if Logger.GetLevel() <= Logger.DEBUG_9: + Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), platform) + format_exc()) + except KeyboardInterrupt: + ReturnCode = ABORT_ERROR + if Logger.GetLevel() <= Logger.DEBUG_9: + Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), platform) + format_exc()) + except: + ReturnCode = CODE_ERROR + Logger.Error("\nInventoryWs", + CODE_ERROR, + ST.ERR_UNKNOWN_FATAL_INVENTORYWS_ERR, + ExtraData=ST.MSG_SEARCH_FOR_HELP, + RaiseError=False + ) + Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), + platform) + format_exc()) + + if ReturnCode == 0: + Logger.Quiet(ST.MSG_FINISH) + + return ReturnCode \ No newline at end of file diff --git a/BaseTools/Source/Python/UPT/Library/CommentGenerating.py b/BaseTools/Source/Python/UPT/Library/CommentGenerating.py index 06da61b3e9..1cf919a96b 100644 --- a/BaseTools/Source/Python/UPT/Library/CommentGenerating.py +++ b/BaseTools/Source/Python/UPT/Library/CommentGenerating.py @@ -1,7 +1,7 @@ ## @file # This file is used to define comment generating interface # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -24,8 +24,18 @@ from Library.DataType import TAB_SPACE_SPLIT from Library.DataType import TAB_INF_GUIDTYPE_VAR from Library.DataType import USAGE_ITEM_NOTIFY from Library.DataType import ITEM_UNDEFINED -from Library.DataType import LANGUAGE_EN_US - +from Library.DataType import TAB_HEADER_COMMENT +from Library.DataType import TAB_BINARY_HEADER_COMMENT +from Library.DataType import TAB_COMMENT_SPLIT +from Library.DataType import TAB_SPECIAL_COMMENT +from Library.DataType import END_OF_LINE +from Library.DataType import TAB_COMMENT_EDK1_SPLIT +from Library.DataType import TAB_COMMENT_EDK1_START +from Library.DataType import TAB_COMMENT_EDK1_END +from Library.DataType import TAB_STAR +from Library.DataType import TAB_PCD_PROMPT +from Library.UniClassObject import ConvertSpecialUnicodes +from Library.Misc import GetLocalValue ## GenTailCommentLines # # @param TailCommentLines: the tail comment lines that need to be generated @@ -33,11 +43,11 @@ from Library.DataType import LANGUAGE_EN_US # line tail comment # def GenTailCommentLines (TailCommentLines, LeadingSpaceNum = 0): - EndOfLine = "\n" - TailCommentLines = TailCommentLines.rstrip(EndOfLine) - CommentStr = " ## " + (EndOfLine + LeadingSpaceNum * TAB_SPACE_SPLIT + \ - " ## ").join(GetSplitValueList(TailCommentLines, \ - EndOfLine)) + TailCommentLines = TailCommentLines.rstrip(END_OF_LINE) + CommentStr = TAB_SPACE_SPLIT*2 + TAB_SPECIAL_COMMENT + TAB_SPACE_SPLIT + \ + (END_OF_LINE + LeadingSpaceNum * TAB_SPACE_SPLIT + TAB_SPACE_SPLIT*2 + TAB_SPECIAL_COMMENT + \ + TAB_SPACE_SPLIT).join(GetSplitValueList(TailCommentLines, END_OF_LINE)) + return CommentStr ## GenGenericComment @@ -47,10 +57,9 @@ def GenTailCommentLines (TailCommentLines, LeadingSpaceNum = 0): def GenGenericComment (CommentLines): if not CommentLines: return '' - EndOfLine = "\n" - CommentLines = CommentLines.rstrip(EndOfLine) - CommentStr = '## ' + (EndOfLine + '# ').join\ - (GetSplitValueList(CommentLines, EndOfLine)) + EndOfLine + CommentLines = CommentLines.rstrip(END_OF_LINE) + CommentStr = TAB_SPECIAL_COMMENT + TAB_SPACE_SPLIT + (END_OF_LINE + TAB_COMMENT_SPLIT + TAB_SPACE_SPLIT).join\ + (GetSplitValueList(CommentLines, END_OF_LINE)) + END_OF_LINE return CommentStr ## GenGenericCommentF @@ -61,23 +70,40 @@ def GenGenericComment (CommentLines): # @param CommentLines: Generic comment Text, maybe Multiple Lines # @return CommentStr: Generated comment line # -def GenGenericCommentF (CommentLines, NumOfPound=1): +def GenGenericCommentF (CommentLines, NumOfPound=1, IsPrompt=False, IsInfLibraryClass=False): if not CommentLines: return '' - EndOfLine = "\n" # # if comment end with '\n', then remove it to prevent one extra line # generate later on # - if CommentLines.endswith(EndOfLine): + if CommentLines.endswith(END_OF_LINE): CommentLines = CommentLines[:-1] - CommentLineList = GetSplitValueList(CommentLines, EndOfLine) CommentStr = '' - for Line in CommentLineList: - if Line == '': - CommentStr += '#' * NumOfPound + '\n' - else: - CommentStr += '#' * NumOfPound + ' ' + Line + '\n' + if IsPrompt: + CommentStr += TAB_COMMENT_SPLIT * NumOfPound + TAB_SPACE_SPLIT + TAB_PCD_PROMPT + TAB_SPACE_SPLIT + \ + CommentLines.replace(END_OF_LINE, '') + END_OF_LINE + else: + CommentLineList = GetSplitValueList(CommentLines, END_OF_LINE) + FindLibraryClass = False + for Line in CommentLineList: + # If this comment is for @libraryclass and it has multiple lines + # make sure the second lines align to the first line after @libraryclass as below + # + # ## @libraryclass XYZ FIRST_LINE + # ## ABC SECOND_LINE + # + if IsInfLibraryClass and Line.find(u'@libraryclass ') > -1: + FindLibraryClass = True + if Line == '': + CommentStr += TAB_COMMENT_SPLIT * NumOfPound + END_OF_LINE + else: + if FindLibraryClass and Line.find(u'@libraryclass ') > -1: + CommentStr += TAB_COMMENT_SPLIT * NumOfPound + TAB_SPACE_SPLIT + Line + END_OF_LINE + elif FindLibraryClass: + CommentStr += TAB_COMMENT_SPLIT * NumOfPound + TAB_SPACE_SPLIT * 16 + Line + END_OF_LINE + else: + CommentStr += TAB_COMMENT_SPLIT * NumOfPound + TAB_SPACE_SPLIT + Line + END_OF_LINE return CommentStr @@ -91,40 +117,57 @@ def GenGenericCommentF (CommentLines, NumOfPound=1): # @param Copyright possible multiple copyright lines # @param License possible multiple license lines # -def GenHeaderCommentSection(Abstract, Description, Copyright, License): - EndOfLine = '\n' +def GenHeaderCommentSection(Abstract, Description, Copyright, License, IsBinaryHeader=False, \ + CommChar=TAB_COMMENT_SPLIT): Content = '' - - Content += '## @file' + EndOfLine + + # + # Convert special character to (c), (r) and (tm). + # + if isinstance(Abstract, unicode): + Abstract = ConvertSpecialUnicodes(Abstract) + if isinstance(Description, unicode): + Description = ConvertSpecialUnicodes(Description) + if IsBinaryHeader: + Content += CommChar * 2 + TAB_SPACE_SPLIT + TAB_BINARY_HEADER_COMMENT + END_OF_LINE + elif CommChar == TAB_COMMENT_EDK1_SPLIT: + Content += CommChar + TAB_SPACE_SPLIT + TAB_COMMENT_EDK1_START + TAB_STAR + TAB_SPACE_SPLIT +\ + TAB_HEADER_COMMENT + END_OF_LINE + else: + Content += CommChar * 2 + TAB_SPACE_SPLIT + TAB_HEADER_COMMENT + END_OF_LINE if Abstract: - Abstract = Abstract.rstrip(EndOfLine) - Content += '# ' + Abstract + EndOfLine - Content += '#' + EndOfLine + Abstract = Abstract.rstrip(END_OF_LINE) + Content += CommChar + TAB_SPACE_SPLIT + (END_OF_LINE + CommChar + TAB_SPACE_SPLIT).join(GetSplitValueList\ + (Abstract, END_OF_LINE)) + Content += END_OF_LINE + CommChar + END_OF_LINE else: - Content += '#' + EndOfLine + Content += CommChar + END_OF_LINE if Description: - Description = Description.rstrip(EndOfLine) - Content += '# ' + (EndOfLine + '# ').join(GetSplitValueList\ - (Description, '\n')) - Content += EndOfLine + '#' + EndOfLine + Description = Description.rstrip(END_OF_LINE) + Content += CommChar + TAB_SPACE_SPLIT + (END_OF_LINE + CommChar + TAB_SPACE_SPLIT).join(GetSplitValueList\ + (Description, END_OF_LINE)) + Content += END_OF_LINE + CommChar + END_OF_LINE # # There is no '#\n' line to separate multiple copyright lines in code base # if Copyright: - Copyright = Copyright.rstrip(EndOfLine) - Content += '# ' + (EndOfLine + '# ').join\ - (GetSplitValueList(Copyright, '\n')) - Content += EndOfLine + '#' + EndOfLine + Copyright = Copyright.rstrip(END_OF_LINE) + Content += CommChar + TAB_SPACE_SPLIT + (END_OF_LINE + CommChar + TAB_SPACE_SPLIT).join\ + (GetSplitValueList(Copyright, END_OF_LINE)) + Content += END_OF_LINE + CommChar + END_OF_LINE if License: - License = License.rstrip(EndOfLine) - Content += '# ' + (EndOfLine + '# ').join(GetSplitValueList\ - (License, '\n')) - Content += EndOfLine + '#' + EndOfLine - - Content += '##' + EndOfLine + License = License.rstrip(END_OF_LINE) + Content += CommChar + TAB_SPACE_SPLIT + (END_OF_LINE + CommChar + TAB_SPACE_SPLIT).join(GetSplitValueList\ + (License, END_OF_LINE)) + Content += END_OF_LINE + CommChar + END_OF_LINE + + if CommChar == TAB_COMMENT_EDK1_SPLIT: + Content += CommChar + TAB_SPACE_SPLIT + TAB_STAR + TAB_COMMENT_EDK1_END + END_OF_LINE + else: + Content += CommChar * 2 + END_OF_LINE return Content @@ -197,21 +240,7 @@ def GenDecTailComment (SupModuleList): # @return HelpStr: the help text string found, '' means no help text found # def _GetHelpStr(HelpTextObjList): - HelpStr = '' - - for HelpObj in HelpTextObjList: - if HelpObj and HelpObj.GetLang() == LANGUAGE_EN_US: - HelpStr = HelpObj.GetString() - return HelpStr - - for HelpObj in HelpTextObjList: - if HelpObj and HelpObj.GetLang().startswith('en'): - HelpStr = HelpObj.GetString() - return HelpStr - + ValueList = [] for HelpObj in HelpTextObjList: - if HelpObj and not HelpObj.GetLang(): - HelpStr = HelpObj.GetString() - return HelpStr - - return HelpStr \ No newline at end of file + ValueList.append((HelpObj.GetLang(), HelpObj.GetString())) + return GetLocalValue(ValueList, True) diff --git a/BaseTools/Source/Python/UPT/Library/CommentParsing.py b/BaseTools/Source/Python/UPT/Library/CommentParsing.py index 5c07f34a74..e6d45103f9 100644 --- a/BaseTools/Source/Python/UPT/Library/CommentParsing.py +++ b/BaseTools/Source/Python/UPT/Library/CommentParsing.py @@ -1,7 +1,7 @@ ## @file # This file is used to define comment parsing interface # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -32,6 +32,17 @@ from Library.DataType import HEADER_COMMENT_DESCRIPTION from Library.DataType import TAB_SPACE_SPLIT from Library.DataType import TAB_COMMA_SPLIT from Library.DataType import SUP_MODULE_LIST +from Library.DataType import TAB_VALUE_SPLIT +from Library.DataType import TAB_PCD_VALIDRANGE +from Library.DataType import TAB_PCD_VALIDLIST +from Library.DataType import TAB_PCD_EXPRESSION +from Library.DataType import TAB_PCD_PROMPT +from Library.DataType import TAB_CAPHEX_START +from Library.DataType import TAB_HEX_START +from Library.DataType import PCD_ERR_CODE_MAX_SIZE +from Library.ExpressionValidate import IsValidRangeExpr +from Library.ExpressionValidate import IsValidListExpr +from Library.ExpressionValidate import IsValidLogicalExpr from Object.POM.CommonObject import TextObject from Object.POM.CommonObject import PcdErrorObject import Logger.Log as Logger @@ -47,13 +58,16 @@ from Logger import StringTable as ST # @param CommentList: List of (Comment, LineNumber) # @param FileName: FileName of the comment # -def ParseHeaderCommentSection(CommentList, FileName = None): +def ParseHeaderCommentSection(CommentList, FileName = None, IsBinaryHeader = False): Abstract = '' Description = '' Copyright = '' License = '' EndOfLine = "\n" - STR_HEADER_COMMENT_START = "@file" + if IsBinaryHeader: + STR_HEADER_COMMENT_START = "@BinaryHeader" + else: + STR_HEADER_COMMENT_START = "@file" HeaderCommentStage = HEADER_COMMENT_NOT_STARTED # @@ -94,7 +108,6 @@ def ParseHeaderCommentSection(CommentList, FileName = None): # in case there is no abstract and description # if not Comment: - Abstract = '' HeaderCommentStage = HEADER_COMMENT_DESCRIPTION elif _IsCopyrightLine(Comment): Result, ErrMsg = _ValidateCopyright(Comment) @@ -134,14 +147,7 @@ def ParseHeaderCommentSection(CommentList, FileName = None): if not Comment and not License: continue License += Comment + EndOfLine - - if not Copyright: - Logger.Error("\nUPT", FORMAT_INVALID, ST.ERR_COPYRIGHT_MISSING, \ - FileName) - - if not License: - Logger.Error("\nUPT", FORMAT_INVALID, ST.ERR_LICENSE_MISSING, FileName) - + return Abstract.strip(), Description.strip(), Copyright.strip(), License.strip() ## _IsCopyrightLine @@ -158,7 +164,7 @@ def _IsCopyrightLine (LineContent): ReIsCopyrightRe = re.compile(r"""(^|\s)COPYRIGHT *\(""", re.DOTALL) if ReIsCopyrightRe.search(LineContent): Result = True - + return Result ## ParseGenericComment @@ -188,6 +194,37 @@ def ParseGenericComment (GenericComment, ContainerFile=None, SkipTag=None): return HelpTxt +## ParsePcdErrorCode +# +# @param Value: original ErrorCode value +# @param ContainerFile: Input value for filename of Dec file +# @param LineNum: Line Num +# +def ParsePcdErrorCode (Value = None, ContainerFile = None, LineNum = None): + try: + if Value.strip().startswith((TAB_HEX_START, TAB_CAPHEX_START)): + Base = 16 + else: + Base = 10 + ErrorCode = long(Value, Base) + if ErrorCode > PCD_ERR_CODE_MAX_SIZE or ErrorCode < 0: + Logger.Error('Parser', + FORMAT_NOT_SUPPORTED, + "The format %s of ErrorCode is not valid, should be UNIT32 type or long type" % Value, + File = ContainerFile, + Line = LineNum) + # + # To delete the tailing 'L' + # + return hex(ErrorCode)[:-1] + except ValueError, XStr: + if XStr: + pass + Logger.Error('Parser', + FORMAT_NOT_SUPPORTED, + "The format %s of ErrorCode is not valid, should be UNIT32 type or long type" % Value, + File = ContainerFile, + Line = LineNum) ## ParseDecPcdGenericComment # @@ -195,46 +232,135 @@ def ParseGenericComment (GenericComment, ContainerFile=None, SkipTag=None): # LineNum) # @param ContainerFile: Input value for filename of Dec file # -def ParseDecPcdGenericComment (GenericComment, ContainerFile): +def ParseDecPcdGenericComment (GenericComment, ContainerFile, TokenSpaceGuidCName, CName, MacroReplaceDict): HelpStr = '' + PromptStr = '' PcdErr = None + PcdErrList = [] + ValidValueNum = 0 + ValidRangeNum = 0 + ExpressionNum = 0 for (CommentLine, LineNum) in GenericComment: Comment = CleanString2(CommentLine)[1] - if Comment.startswith("@ValidRange"): - if PcdErr: + # + # To replace Macro + # + MACRO_PATTERN = '[\t\s]*\$\([A-Z][_A-Z0-9]*\)' + MatchedStrs = re.findall(MACRO_PATTERN, Comment) + for MatchedStr in MatchedStrs: + if MatchedStr: + Macro = MatchedStr.strip().lstrip('$(').rstrip(')').strip() + if Macro in MacroReplaceDict: + Comment = Comment.replace(MatchedStr, MacroReplaceDict[Macro]) + if Comment.startswith(TAB_PCD_VALIDRANGE): + if ValidValueNum > 0 or ExpressionNum > 0: Logger.Error('Parser', FORMAT_NOT_SUPPORTED, ST.WRN_MULTI_PCD_RANGES, File = ContainerFile, Line = LineNum) - ValidRange = Comment.replace("@ValidRange", "", 1) - if _CheckRangeExpression(ValidRange): + else: PcdErr = PcdErrorObject() - PcdErr.SetValidValueRange(ValidRange) - elif Comment.startswith("@ValidList"): - if PcdErr: + PcdErr.SetTokenSpaceGuidCName(TokenSpaceGuidCName) + PcdErr.SetCName(CName) + PcdErr.SetFileLine(Comment) + PcdErr.SetLineNum(LineNum) + ValidRangeNum += 1 + ValidRange = Comment.replace(TAB_PCD_VALIDRANGE, "", 1).strip() + Valid, Cause = _CheckRangeExpression(ValidRange) + if Valid: + ValueList = ValidRange.split(TAB_VALUE_SPLIT) + if len(ValueList) > 1: + PcdErr.SetValidValueRange((TAB_VALUE_SPLIT.join(ValueList[1:])).strip()) + PcdErr.SetErrorNumber(ParsePcdErrorCode(ValueList[0], ContainerFile, LineNum)) + else: + PcdErr.SetValidValueRange(ValidRange) + PcdErrList.append(PcdErr) + else: + Logger.Error("Parser", + FORMAT_NOT_SUPPORTED, + Cause, + ContainerFile, + LineNum) + elif Comment.startswith(TAB_PCD_VALIDLIST): + if ValidRangeNum > 0 or ExpressionNum > 0: Logger.Error('Parser', FORMAT_NOT_SUPPORTED, ST.WRN_MULTI_PCD_RANGES, File = ContainerFile, Line = LineNum) - ValidValue = Comment.replace("@ValidList", "", 1).replace(TAB_COMMA_SPLIT, TAB_SPACE_SPLIT) - PcdErr = PcdErrorObject() - PcdErr.SetValidValue(ValidValue) - elif Comment.startswith("@Expression"): - if PcdErr: + elif ValidValueNum > 0: + Logger.Error('Parser', + FORMAT_NOT_SUPPORTED, + ST.WRN_MULTI_PCD_VALIDVALUE, + File = ContainerFile, + Line = LineNum) + else: + PcdErr = PcdErrorObject() + PcdErr.SetTokenSpaceGuidCName(TokenSpaceGuidCName) + PcdErr.SetCName(CName) + PcdErr.SetFileLine(Comment) + PcdErr.SetLineNum(LineNum) + ValidValueNum += 1 + ValidValueExpr = Comment.replace(TAB_PCD_VALIDLIST, "", 1).strip() + Valid, Cause = _CheckListExpression(ValidValueExpr) + if Valid: + ValidValue = Comment.replace(TAB_PCD_VALIDLIST, "", 1).replace(TAB_COMMA_SPLIT, TAB_SPACE_SPLIT) + ValueList = ValidValue.split(TAB_VALUE_SPLIT) + if len(ValueList) > 1: + PcdErr.SetValidValue((TAB_VALUE_SPLIT.join(ValueList[1:])).strip()) + PcdErr.SetErrorNumber(ParsePcdErrorCode(ValueList[0], ContainerFile, LineNum)) + else: + PcdErr.SetValidValue(ValidValue) + PcdErrList.append(PcdErr) + else: + Logger.Error("Parser", + FORMAT_NOT_SUPPORTED, + Cause, + ContainerFile, + LineNum) + elif Comment.startswith(TAB_PCD_EXPRESSION): + if ValidRangeNum > 0 or ValidValueNum > 0: Logger.Error('Parser', FORMAT_NOT_SUPPORTED, ST.WRN_MULTI_PCD_RANGES, File = ContainerFile, Line = LineNum) - Expression = Comment.replace("@Expression", "", 1) - if _CheckRangeExpression(Expression): + else: PcdErr = PcdErrorObject() - PcdErr.SetExpression(Expression) + PcdErr.SetTokenSpaceGuidCName(TokenSpaceGuidCName) + PcdErr.SetCName(CName) + PcdErr.SetFileLine(Comment) + PcdErr.SetLineNum(LineNum) + ExpressionNum += 1 + Expression = Comment.replace(TAB_PCD_EXPRESSION, "", 1).strip() + Valid, Cause = _CheckExpression(Expression) + if Valid: + ValueList = Expression.split(TAB_VALUE_SPLIT) + if len(ValueList) > 1: + PcdErr.SetExpression((TAB_VALUE_SPLIT.join(ValueList[1:])).strip()) + PcdErr.SetErrorNumber(ParsePcdErrorCode(ValueList[0], ContainerFile, LineNum)) + else: + PcdErr.SetExpression(Expression) + PcdErrList.append(PcdErr) + else: + Logger.Error("Parser", + FORMAT_NOT_SUPPORTED, + Cause, + ContainerFile, + LineNum) + elif Comment.startswith(TAB_PCD_PROMPT): + if PromptStr: + Logger.Error('Parser', + FORMAT_NOT_SUPPORTED, + ST.WRN_MULTI_PCD_PROMPT, + File = ContainerFile, + Line = LineNum) + PromptStr = Comment.replace(TAB_PCD_PROMPT, "", 1).strip() else: - HelpStr += Comment + '\n' + if Comment: + HelpStr += Comment + '\n' # # remove the last EOL if the comment is of format 'FOO\n' @@ -243,7 +369,7 @@ def ParseDecPcdGenericComment (GenericComment, ContainerFile): if HelpStr != '\n' and not HelpStr.endswith('\n\n'): HelpStr = HelpStr[:-1] - return HelpStr, PcdErr + return HelpStr, PcdErrList, PromptStr ## ParseDecPcdTailComment # @@ -289,18 +415,43 @@ def ParseDecPcdTailComment (TailCommentList, ContainerFile): return SupModuleList, HelpStr +## _CheckListExpression +# +# @param Expression: Pcd value list expression +# +def _CheckListExpression(Expression): + ListExpr = '' + if TAB_VALUE_SPLIT in Expression: + ListExpr = Expression[Expression.find(TAB_VALUE_SPLIT)+1:] + else: + ListExpr = Expression + + return IsValidListExpr(ListExpr) + +## _CheckExpreesion +# +# @param Expression: Pcd value expression +# +def _CheckExpression(Expression): + Expr = '' + if TAB_VALUE_SPLIT in Expression: + Expr = Expression[Expression.find(TAB_VALUE_SPLIT)+1:] + else: + Expr = Expression + return IsValidLogicalExpr(Expr, True) ## _CheckRangeExpression # # @param Expression: Pcd range expression # def _CheckRangeExpression(Expression): - # - # check grammar for Pcd range expression is not required yet - # - if Expression: - pass - return True + RangeExpr = '' + if TAB_VALUE_SPLIT in Expression: + RangeExpr = Expression[Expression.find(TAB_VALUE_SPLIT)+1:] + else: + RangeExpr = Expression + + return IsValidRangeExpr(RangeExpr) ## ValidateCopyright # @@ -349,7 +500,6 @@ def ParseComment (Comment, UsageTokens, TypeTokens, RemoveTokens, ParseVariable) Usage = None Type = None String = None - HelpText = None Comment = Comment[0] diff --git a/BaseTools/Source/Python/UPT/Library/DataType.py b/BaseTools/Source/Python/UPT/Library/DataType.py index 4b30f3343e..8449dc8d6d 100644 --- a/BaseTools/Source/Python/UPT/Library/DataType.py +++ b/BaseTools/Source/Python/UPT/Library/DataType.py @@ -1,7 +1,7 @@ ## @file # This file is used to define class for data type structure # -# Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -47,7 +47,10 @@ USAGE_LIST = ["CONSUMES", "PRODUCES", "SOMETIMES_PRODUCES"] -LANGUAGE_EN_US = 'en-US' +TAB_LANGUAGE_EN_US = 'en-US' +TAB_LANGUAGE_ENG = 'eng' +TAB_LANGUAGE_EN = 'en' +TAB_LANGUAGE_EN_X = 'en-x-tianocore' USAGE_ITEM_PRODUCES = 'PRODUCES' USAGE_ITEM_SOMETIMES_PRODUCES = 'SOMETIMES_PRODUCES' @@ -80,6 +83,14 @@ USAGE_SOMETIMES_CONSUMES_LIST = [USAGE_ITEM_SOMETIMES_CONSUMES, ITEM_UNDEFINED = 'UNDEFINED' +TAB_PCD_VALIDRANGE = '@ValidRange' +TAB_PCD_VALIDLIST = '@ValidList' +TAB_PCD_EXPRESSION = '@Expression' +TAB_PCD_PROMPT = '@Prompt' +TAB_STR_TOKENCNAME = 'STR' +TAB_STR_TOKENPROMPT = 'PROMPT' +TAB_STR_TOKENHELP = 'HELP' +TAB_STR_TOKENERR = 'ERR' # # Dictionary of usage tokens and their synonmys @@ -269,11 +280,12 @@ PCD_USAGE_TYPE_LIST_OF_UPT = PCD_USAGE_TYPE_LIST_OF_MODULE ## # Binary File Type List # -BINARY_FILE_TYPE_LIST = ["GUID", "PE32", "PIC", "TE", "DXE_DEPEX", "VER", "UI", "COMPAT16", "FV", "BIN", "RAW", +BINARY_FILE_TYPE_LIST = ["PE32", "PIC", "TE", "DXE_DEPEX", "VER", "UI", "COMPAT16", "FV", "BIN", "RAW", "ACPI", "ASL", "PEI_DEPEX", "SMM_DEPEX", - "SUBTYPE_GUID" + "SUBTYPE_GUID", + "DISPOSABLE" ] BINARY_FILE_TYPE_LIST_IN_UDP = \ ["GUID", "FREEFORM", @@ -285,6 +297,7 @@ BINARY_FILE_TYPE_LIST_IN_UDP = \ "BIN", "VER", "UI" ] +SUBTYPE_GUID_BINARY_FILE_TYPE = "FREEFORM" ## # Possible values for COMPONENT_TYPE, and their descriptions, are listed in # the table, @@ -328,6 +341,7 @@ TAB_EQUAL_SPLIT = '=' TAB_DEQUAL_SPLIT = '==' TAB_VALUE_SPLIT = '|' TAB_COMMA_SPLIT = ',' +TAB_HORIZON_LINE_SPLIT = '-' TAB_SPACE_SPLIT = ' ' TAB_UNDERLINE_SPLIT = '_' TAB_SEMI_COLON_SPLIT = ';' @@ -341,7 +355,13 @@ TAB_BACK_SLASH = '/' TAB_SPECIAL_COMMENT = '##' TAB_HEADER_COMMENT = '@file' TAB_BINARY_HEADER_COMMENT = '@BinaryHeader' -TAB_STAR = "*" +TAB_STAR = '*' +TAB_ENCODING_UTF16LE = 'utf_16_le' +TAB_CAPHEX_START = '0X' +TAB_HEX_START = '0x' +TAB_PCD_ERROR = 'Error' +TAB_PCD_ERROR_SECTION_COMMENT = 'Error message section' +TAB_UNI_FILE_SUFFIXS = ['.uni', '.UNI', '.Uni'] TAB_EDK_SOURCE = '$(EDK_SOURCE)' TAB_EFI_SOURCE = '$(EFI_SOURCE)' @@ -354,10 +374,9 @@ TAB_ARCH_X64 = 'X64' TAB_ARCH_IPF = 'IPF' TAB_ARCH_ARM = 'ARM' TAB_ARCH_EBC = 'EBC' -TAB_ARCH_AARCH64 = 'AARCH64' ARCH_LIST = \ -[TAB_ARCH_IA32, TAB_ARCH_X64, TAB_ARCH_IPF, TAB_ARCH_ARM, TAB_ARCH_EBC, TAB_ARCH_AARCH64] +[TAB_ARCH_IA32, TAB_ARCH_X64, TAB_ARCH_IPF, TAB_ARCH_ARM, TAB_ARCH_EBC] SUP_MODULE_BASE = 'BASE' SUP_MODULE_SEC = 'SEC' @@ -442,7 +461,6 @@ TAB_SOURCES_X64 = TAB_SOURCES + TAB_SPLIT + TAB_ARCH_X64 TAB_SOURCES_IPF = TAB_SOURCES + TAB_SPLIT + TAB_ARCH_IPF TAB_SOURCES_ARM = TAB_SOURCES + TAB_SPLIT + TAB_ARCH_ARM TAB_SOURCES_EBC = TAB_SOURCES + TAB_SPLIT + TAB_ARCH_EBC -TAB_SOURCES_AARCH64 = TAB_SOURCES + TAB_SPLIT + TAB_ARCH_AARCH64 TAB_BINARIES = 'Binaries' TAB_BINARIES_COMMON = TAB_BINARIES + TAB_SPLIT + TAB_ARCH_COMMON @@ -451,7 +469,6 @@ TAB_BINARIES_X64 = TAB_BINARIES + TAB_SPLIT + TAB_ARCH_X64 TAB_BINARIES_IPF = TAB_BINARIES + TAB_SPLIT + TAB_ARCH_IPF TAB_BINARIES_ARM = TAB_BINARIES + TAB_SPLIT + TAB_ARCH_ARM TAB_BINARIES_EBC = TAB_BINARIES + TAB_SPLIT + TAB_ARCH_EBC -TAB_BINARIES_AARCH64 = TAB_BINARIES + TAB_SPLIT + TAB_ARCH_AARCH64 TAB_INCLUDES = 'Includes' TAB_INCLUDES_COMMON = TAB_INCLUDES + TAB_SPLIT + TAB_ARCH_COMMON @@ -460,7 +477,6 @@ TAB_INCLUDES_X64 = TAB_INCLUDES + TAB_SPLIT + TAB_ARCH_X64 TAB_INCLUDES_IPF = TAB_INCLUDES + TAB_SPLIT + TAB_ARCH_IPF TAB_INCLUDES_ARM = TAB_INCLUDES + TAB_SPLIT + TAB_ARCH_ARM TAB_INCLUDES_EBC = TAB_INCLUDES + TAB_SPLIT + TAB_ARCH_EBC -TAB_INCLUDES_AARCH64 = TAB_INCLUDES + TAB_SPLIT + TAB_ARCH_AARCH64 TAB_GUIDS = 'Guids' TAB_GUIDS_COMMON = TAB_GUIDS + TAB_SPLIT + TAB_ARCH_COMMON @@ -469,7 +485,6 @@ TAB_GUIDS_X64 = TAB_GUIDS + TAB_SPLIT + TAB_ARCH_X64 TAB_GUIDS_IPF = TAB_GUIDS + TAB_SPLIT + TAB_ARCH_IPF TAB_GUIDS_ARM = TAB_GUIDS + TAB_SPLIT + TAB_ARCH_ARM TAB_GUIDS_EBC = TAB_GUIDS + TAB_SPLIT + TAB_ARCH_EBC -TAB_GUIDS_AARCH64 = TAB_GUIDS + TAB_SPLIT + TAB_ARCH_AARCH64 TAB_PROTOCOLS = 'Protocols' TAB_PROTOCOLS_COMMON = TAB_PROTOCOLS + TAB_SPLIT + TAB_ARCH_COMMON @@ -478,7 +493,6 @@ TAB_PROTOCOLS_X64 = TAB_PROTOCOLS + TAB_SPLIT + TAB_ARCH_X64 TAB_PROTOCOLS_IPF = TAB_PROTOCOLS + TAB_SPLIT + TAB_ARCH_IPF TAB_PROTOCOLS_ARM = TAB_PROTOCOLS + TAB_SPLIT + TAB_ARCH_ARM TAB_PROTOCOLS_EBC = TAB_PROTOCOLS + TAB_SPLIT + TAB_ARCH_EBC -TAB_PROTOCOLS_AARCH64 = TAB_PROTOCOLS + TAB_SPLIT + TAB_ARCH_AARCH64 TAB_PPIS = 'Ppis' TAB_PPIS_COMMON = TAB_PPIS + TAB_SPLIT + TAB_ARCH_COMMON @@ -487,7 +501,6 @@ TAB_PPIS_X64 = TAB_PPIS + TAB_SPLIT + TAB_ARCH_X64 TAB_PPIS_IPF = TAB_PPIS + TAB_SPLIT + TAB_ARCH_IPF TAB_PPIS_ARM = TAB_PPIS + TAB_SPLIT + TAB_ARCH_ARM TAB_PPIS_EBC = TAB_PPIS + TAB_SPLIT + TAB_ARCH_EBC -TAB_PPIS_AARCH64 = TAB_PPIS + TAB_SPLIT + TAB_ARCH_AARCH64 TAB_LIBRARY_CLASSES = 'LibraryClasses' TAB_LIBRARY_CLASSES_COMMON = TAB_LIBRARY_CLASSES + TAB_SPLIT + TAB_ARCH_COMMON @@ -496,7 +509,6 @@ TAB_LIBRARY_CLASSES_X64 = TAB_LIBRARY_CLASSES + TAB_SPLIT + TAB_ARCH_X64 TAB_LIBRARY_CLASSES_IPF = TAB_LIBRARY_CLASSES + TAB_SPLIT + TAB_ARCH_IPF TAB_LIBRARY_CLASSES_ARM = TAB_LIBRARY_CLASSES + TAB_SPLIT + TAB_ARCH_ARM TAB_LIBRARY_CLASSES_EBC = TAB_LIBRARY_CLASSES + TAB_SPLIT + TAB_ARCH_EBC -TAB_LIBRARY_CLASSES_AARCH64 = TAB_LIBRARY_CLASSES + TAB_SPLIT + TAB_ARCH_AARCH64 TAB_PACKAGES = 'Packages' TAB_PACKAGES_COMMON = TAB_PACKAGES + TAB_SPLIT + TAB_ARCH_COMMON @@ -505,7 +517,6 @@ TAB_PACKAGES_X64 = TAB_PACKAGES + TAB_SPLIT + TAB_ARCH_X64 TAB_PACKAGES_IPF = TAB_PACKAGES + TAB_SPLIT + TAB_ARCH_IPF TAB_PACKAGES_ARM = TAB_PACKAGES + TAB_SPLIT + TAB_ARCH_ARM TAB_PACKAGES_EBC = TAB_PACKAGES + TAB_SPLIT + TAB_ARCH_EBC -TAB_PACKAGES_AARCH64 = TAB_PACKAGES + TAB_SPLIT + TAB_ARCH_AARCH64 TAB_PCDS = 'Pcds' TAB_PCDS_FIXED_AT_BUILD = 'FixedAtBuild' @@ -545,8 +556,6 @@ TAB_PCDS_FIXED_AT_BUILD_ARM = TAB_PCDS + TAB_PCDS_FIXED_AT_BUILD + \ TAB_SPLIT + TAB_ARCH_ARM TAB_PCDS_FIXED_AT_BUILD_EBC = TAB_PCDS + TAB_PCDS_FIXED_AT_BUILD + \ TAB_SPLIT + TAB_ARCH_EBC -TAB_PCDS_FIXED_AT_BUILD_AARCH64 = TAB_PCDS + TAB_PCDS_FIXED_AT_BUILD + \ -TAB_SPLIT + TAB_ARCH_AARCH64 TAB_PCDS_PATCHABLE_IN_MODULE_NULL = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE TAB_PCDS_PATCHABLE_IN_MODULE_COMMON = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE \ @@ -561,8 +570,6 @@ TAB_PCDS_PATCHABLE_IN_MODULE_ARM = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE + \ TAB_SPLIT + TAB_ARCH_ARM TAB_PCDS_PATCHABLE_IN_MODULE_EBC = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE + \ TAB_SPLIT + TAB_ARCH_EBC -TAB_PCDS_PATCHABLE_IN_MODULE_AARCH64 = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE + \ -TAB_SPLIT + TAB_ARCH_AARCH64 TAB_PCDS_FEATURE_FLAG_NULL = TAB_PCDS + TAB_PCDS_FEATURE_FLAG TAB_PCDS_FEATURE_FLAG_COMMON = TAB_PCDS + TAB_PCDS_FEATURE_FLAG + TAB_SPLIT \ @@ -577,8 +584,6 @@ TAB_PCDS_FEATURE_FLAG_ARM = TAB_PCDS + TAB_PCDS_FEATURE_FLAG + TAB_SPLIT + \ TAB_ARCH_ARM TAB_PCDS_FEATURE_FLAG_EBC = TAB_PCDS + TAB_PCDS_FEATURE_FLAG + TAB_SPLIT + \ TAB_ARCH_EBC -TAB_PCDS_FEATURE_FLAG_AARCH64 = TAB_PCDS + TAB_PCDS_FEATURE_FLAG + TAB_SPLIT + \ -TAB_ARCH_AARCH64 TAB_PCDS_DYNAMIC_EX_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC_EX TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC_EX_DEFAULT @@ -596,8 +601,6 @@ TAB_PCDS_DYNAMIC_EX_ARM = TAB_PCDS + TAB_PCDS_DYNAMIC_EX + TAB_SPLIT + \ TAB_ARCH_ARM TAB_PCDS_DYNAMIC_EX_EBC = TAB_PCDS + TAB_PCDS_DYNAMIC_EX + TAB_SPLIT + \ TAB_ARCH_EBC -TAB_PCDS_DYNAMIC_EX_AARCH64 = TAB_PCDS + TAB_PCDS_DYNAMIC_EX + TAB_SPLIT + \ -TAB_ARCH_AARCH64 TAB_PCDS_DYNAMIC_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC TAB_PCDS_DYNAMIC_DEFAULT_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC_DEFAULT @@ -610,7 +613,6 @@ TAB_PCDS_DYNAMIC_X64 = TAB_PCDS + TAB_PCDS_DYNAMIC + TAB_SPLIT + TAB_ARCH_X64 TAB_PCDS_DYNAMIC_IPF = TAB_PCDS + TAB_PCDS_DYNAMIC + TAB_SPLIT + TAB_ARCH_IPF TAB_PCDS_DYNAMIC_ARM = TAB_PCDS + TAB_PCDS_DYNAMIC + TAB_SPLIT + TAB_ARCH_ARM TAB_PCDS_DYNAMIC_EBC = TAB_PCDS + TAB_PCDS_DYNAMIC + TAB_SPLIT + TAB_ARCH_EBC -TAB_PCDS_DYNAMIC_AARCH64 = TAB_PCDS + TAB_PCDS_DYNAMIC + TAB_SPLIT + TAB_ARCH_AARCH64 TAB_PCD_DYNAMIC_TYPE_LIST = [TAB_PCDS_DYNAMIC_DEFAULT_NULL, \ TAB_PCDS_DYNAMIC_VPD_NULL, \ @@ -651,7 +653,6 @@ TAB_DEPEX_X64 = TAB_DEPEX + TAB_SPLIT + TAB_ARCH_X64 TAB_DEPEX_IPF = TAB_DEPEX + TAB_SPLIT + TAB_ARCH_IPF TAB_DEPEX_ARM = TAB_DEPEX + TAB_SPLIT + TAB_ARCH_ARM TAB_DEPEX_EBC = TAB_DEPEX + TAB_SPLIT + TAB_ARCH_EBC -TAB_DEPEX_AARCH64 = TAB_DEPEX + TAB_SPLIT + TAB_ARCH_AARCH64 TAB_SKUIDS = 'SkuIds' @@ -662,7 +663,6 @@ TAB_LIBRARIES_X64 = TAB_LIBRARIES + TAB_SPLIT + TAB_ARCH_X64 TAB_LIBRARIES_IPF = TAB_LIBRARIES + TAB_SPLIT + TAB_ARCH_IPF TAB_LIBRARIES_ARM = TAB_LIBRARIES + TAB_SPLIT + TAB_ARCH_ARM TAB_LIBRARIES_EBC = TAB_LIBRARIES + TAB_SPLIT + TAB_ARCH_EBC -TAB_LIBRARIES_AARCH64 = TAB_LIBRARIES + TAB_SPLIT + TAB_ARCH_AARCH64 TAB_COMPONENTS = 'Components' TAB_COMPONENTS_COMMON = TAB_COMPONENTS + TAB_SPLIT + TAB_ARCH_COMMON @@ -671,7 +671,6 @@ TAB_COMPONENTS_X64 = TAB_COMPONENTS + TAB_SPLIT + TAB_ARCH_X64 TAB_COMPONENTS_IPF = TAB_COMPONENTS + TAB_SPLIT + TAB_ARCH_IPF TAB_COMPONENTS_ARM = TAB_COMPONENTS + TAB_SPLIT + TAB_ARCH_ARM TAB_COMPONENTS_EBC = TAB_COMPONENTS + TAB_SPLIT + TAB_ARCH_EBC -TAB_COMPONENTS_AARCH64 = TAB_COMPONENTS + TAB_SPLIT + TAB_ARCH_AARCH64 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH = 'SOURCE_OVERRIDE_PATH' @@ -699,6 +698,7 @@ TAB_INF_DEFINES_EFI_SPECIFICATION_VERSION = 'EFI_SPECIFICATION_VERSION' TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION = 'UEFI_SPECIFICATION_VERSION' TAB_INF_DEFINES_PI_SPECIFICATION_VERSION = 'PI_SPECIFICATION_VERSION' TAB_INF_DEFINES_EDK_RELEASE_VERSION = 'EDK_RELEASE_VERSION' +TAB_INF_DEFINES_MODULE_UNI_FILE = 'MODULE_UNI_FILE' TAB_INF_DEFINES_BINARY_MODULE = 'BINARY_MODULE' TAB_INF_DEFINES_LIBRARY_CLASS = 'LIBRARY_CLASS' TAB_INF_DEFINES_COMPONENT_TYPE = 'COMPONENT_TYPE' @@ -750,7 +750,7 @@ TAB_DEC_DEFINES_DEC_SPECIFICATION = 'DEC_SPECIFICATION' TAB_DEC_DEFINES_PACKAGE_NAME = 'PACKAGE_NAME' TAB_DEC_DEFINES_PACKAGE_GUID = 'PACKAGE_GUID' TAB_DEC_DEFINES_PACKAGE_VERSION = 'PACKAGE_VERSION' -TAB_DEC_DEFINES_PKG_UNI_FILE = 'PKG_UNI_FILE' +TAB_DEC_DEFINES_PKG_UNI_FILE = 'PACKAGE_UNI_FILE' TAB_DEC_PACKAGE_ABSTRACT = 'STR_PACKAGE_ABSTRACT' TAB_DEC_PACKAGE_DESCRIPTION = 'STR_PACKAGE_DESCRIPTION' TAB_DEC_PACKAGE_LICENSE = 'STR_PACKAGE_LICENSE' @@ -827,6 +827,7 @@ TAB_HEADER_COPYRIGHT = 'Copyright' TAB_HEADER_LICENSE = 'License' TAB_BINARY_HEADER_IDENTIFIER = 'BinaryHeader' TAB_BINARY_HEADER_USERID = 'TianoCore' + # # Build database path # @@ -951,3 +952,5 @@ TOOL_FAMILY_LIST = ["MSFT", TYPE_HOB_SECTION = 'HOB' TYPE_EVENT_SECTION = 'EVENT' TYPE_BOOTMODE_SECTION = 'BOOTMODE' + +PCD_ERR_CODE_MAX_SIZE = 4294967295 diff --git a/BaseTools/Source/Python/UPT/Library/ExpressionValidate.py b/BaseTools/Source/Python/UPT/Library/ExpressionValidate.py index 3b476b4c48..090c7eb957 100644 --- a/BaseTools/Source/Python/UPT/Library/ExpressionValidate.py +++ b/BaseTools/Source/Python/UPT/Library/ExpressionValidate.py @@ -1,7 +1,7 @@ ## @file # This file is used to check PCD logical expression # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -106,16 +106,21 @@ class _ExprBase: '>' : '=', '<' : '=' } + for Operator in OpList: if not self.Token[self.Index:].startswith(Operator): continue + self.Index += len(Operator) Char = self.Token[self.Index : self.Index + 1] + if (Operator in LetterOp and (Char == '_' or Char.isalnum())) \ or (Operator in OpMap and OpMap[Operator] == Char): self.Index -= len(Operator) break + return True + return False ## _LogicalExpressionParser @@ -166,6 +171,7 @@ class _LogicalExpressionParser(_ExprBase): return False return True + return False def IsAtomicNumVal(self): @@ -216,32 +222,32 @@ class _LogicalExpressionParser(_ExprBase): # def LogicalExpression(self): Ret = self.SpecNot() - while self.IsCurrentOp(['||', 'OR', 'or', '&&', 'AND', 'and', 'XOR']): + while self.IsCurrentOp(['||', 'OR', 'or', '&&', 'AND', 'and', 'XOR', 'xor', '^']): if self.Token[self.Index-1] == '|' and self.Parens <= 0: - raise _ExprError(ST.ERR_EXPR_OR) - if Ret == self.ARITH: + raise _ExprError(ST.ERR_EXPR_OR % self.Token) + if Ret not in [self.ARITH, self.LOGICAL, self.REALLOGICAL, self.STRINGITEM]: raise _ExprError(ST.ERR_EXPR_LOGICAL % self.Token) Ret = self.SpecNot() - if Ret == self.ARITH: + if Ret not in [self.ARITH, self.LOGICAL, self.REALLOGICAL, self.STRINGITEM]: raise _ExprError(ST.ERR_EXPR_LOGICAL % self.Token) Ret = self.REALLOGICAL return Ret def SpecNot(self): - if self.IsCurrentOp(["NOT", "!"]): + if self.IsCurrentOp(["NOT", "!", "not"]): return self.SpecNot() return self.Rel() - ## A < B, A > B, A <= B, A >= b + ## A < B, A > B, A <= B, A >= B # def Rel(self): Ret = self.Expr() if self.IsCurrentOp(["<=", ">=", ">", "<", "GT", "LT", "GE", "LE", "==", "EQ", "!=", "NE"]): - if Ret == self.STRINGITEM or Ret == self.REALLOGICAL: + if Ret == self.STRINGITEM: raise _ExprError(ST.ERR_EXPR_LOGICAL % self.Token) Ret = self.Expr() - if Ret == self.STRINGITEM or Ret == self.REALLOGICAL: + if Ret == self.REALLOGICAL: raise _ExprError(ST.ERR_EXPR_LOGICAL % self.Token) Ret = self.REALLOGICAL return Ret @@ -250,7 +256,7 @@ class _LogicalExpressionParser(_ExprBase): # def Expr(self): Ret = self.Factor() - while self.IsCurrentOp(["+", "-", "&", "|", "^"]): + while self.IsCurrentOp(["+", "-", "&", "|", "^", "XOR", "xor"]): if self.Token[self.Index-1] == '|' and self.Parens <= 0: raise _ExprError(ST.ERR_EXPR_OR) if Ret == self.STRINGITEM or Ret == self.REALLOGICAL: @@ -281,15 +287,15 @@ class _LogicalExpressionParser(_ExprBase): return self.ARITH else: raise _ExprError(ST.ERR_EXPR_FACTOR % \ - (self.Token, self.Token[self.Index:])) + (self.Token[self.Index:], self.Token)) ## IsValidLogicalExpression # def IsValidLogicalExpression(self): if self.Len == 0: - return False, ST.ERR_EXPR_EMPTY + return False, ST.ERR_EXPRESS_EMPTY try: - if self.LogicalExpression() == self.ARITH: + if self.LogicalExpression() not in [self.ARITH, self.LOGICAL, self.REALLOGICAL, self.STRINGITEM]: return False, ST.ERR_EXPR_LOGICAL % self.Token except _ExprError, XExcept: return False, XExcept.Error @@ -307,55 +313,84 @@ class _ValidRangeExpressionParser(_ExprBase): '[\t\s]*0[xX][a-fA-F0-9]+[\t\s]*-[\t\s]*0[xX][a-fA-F0-9]+' def __init__(self, Token): _ExprBase.__init__(self, Token) + self.Parens = 0 + self.HEX = 1 + self.INT = 2 + self.IsParenHappen = False + self.IsLogicalOpHappen = False ## IsValidRangeExpression # def IsValidRangeExpression(self): if self.Len == 0: - return False + return False, ST.ERR_EXPR_RANGE_EMPTY try: - self.RangeExpression() - except _ExprError: - return False + if self.RangeExpression() not in [self.HEX, self.INT]: + return False, ST.ERR_EXPR_RANGE % self.Token + except _ExprError, XExcept: + return False, XExcept.Error + self.SkipWhitespace() if self.Index != self.Len: - return False - return True + return False, (ST.ERR_EXPR_RANGE % self.Token) + return True, '' ## RangeExpression # def RangeExpression(self): - self.Unary() - while self.IsCurrentOp(['OR', 'AND', 'XOR']): - self.Unary() + Ret = self.Unary() + while self.IsCurrentOp(['OR', 'AND', 'and', 'or']): + self.IsLogicalOpHappen = True + if not self.IsParenHappen: + raise _ExprError(ST.ERR_PAREN_NOT_USED % self.Token) + self.IsParenHappen = False + Ret = self.Unary() + + if self.IsCurrentOp(['XOR']): + Ret = self.Unary() + + return Ret ## Unary # def Unary(self): - if self.IsCurrentOp(["NOT", "-"]): + if self.IsCurrentOp(["NOT"]): return self.Unary() + return self.ValidRange() ## ValidRange # def ValidRange(self): + Ret = -1 if self.IsCurrentOp(["("]): - self.RangeExpression() + self.IsLogicalOpHappen = False + self.IsParenHappen = True + self.Parens += 1 + if self.Parens > 1: + raise _ExprError(ST.ERR_EXPR_RANGE_DOUBLE_PAREN_NESTED % self.Token) + Ret = self.RangeExpression() if not self.IsCurrentOp([")"]): - raise _ExprError('') - return + raise _ExprError(ST.ERR_EXPR_RIGHT_PAREN % self.Token) + self.Parens -= 1 + return Ret + + if self.IsLogicalOpHappen: + raise _ExprError(ST.ERR_PAREN_NOT_USED % self.Token) - if self.IsCurrentOp(["LT", "GT", "LE", "GE", "EQ"]): + if self.IsCurrentOp(["LT", "GT", "LE", "GE", "EQ", "XOR"]): IntMatch = \ re.compile(self.INT_PATTERN).match(self.Token[self.Index:]) HexMatch = \ re.compile(self.HEX_PATTERN).match(self.Token[self.Index:]) if HexMatch and HexMatch.start() == 0: self.Index += HexMatch.end() + Ret = self.HEX elif IntMatch and IntMatch.start() == 0: self.Index += IntMatch.end() + Ret = self.INT else: - raise _ExprError('') + raise _ExprError(ST.ERR_EXPR_RANGE_FACTOR % (self.Token[self.Index:], self.Token)) else: IntRangeMatch = re.compile( self.INT_RANGE_PATTERN).match(self.Token[self.Index:] @@ -365,15 +400,50 @@ class _ValidRangeExpressionParser(_ExprBase): ) if HexRangeMatch and HexRangeMatch.start() == 0: self.Index += HexRangeMatch.end() + Ret = self.HEX elif IntRangeMatch and IntRangeMatch.start() == 0: self.Index += IntRangeMatch.end() + Ret = self.INT else: - raise _ExprError('') + raise _ExprError(ST.ERR_EXPR_RANGE % self.Token) + + return Ret + +## _ValidListExpressionParser +# +class _ValidListExpressionParser(_ExprBase): + VALID_LIST_PATTERN = '(0[xX][0-9a-fA-F]+|[0-9]+)([\t\s]*,[\t\s]*(0[xX][0-9a-fA-F]+|[0-9]+))*' + def __init__(self, Token): + _ExprBase.__init__(self, Token) + self.NUM = 1 - if self.Token[self.Index:self.Index+1] == '_' or \ - self.Token[self.Index:self.Index+1].isalnum(): - raise _ExprError('') + def IsValidListExpression(self): + if self.Len == 0: + return False, ST.ERR_EXPR_LIST_EMPTY + try: + if self.ListExpression() not in [self.NUM]: + return False, ST.ERR_EXPR_LIST % self.Token + except _ExprError, XExcept: + return False, XExcept.Error + self.SkipWhitespace() + if self.Index != self.Len: + return False, (ST.ERR_EXPR_LIST % self.Token) + + return True, '' + + def ListExpression(self): + Ret = -1 + self.SkipWhitespace() + ListMatch = re.compile(self.VALID_LIST_PATTERN).match(self.Token[self.Index:]) + if ListMatch and ListMatch.start() == 0: + self.Index += ListMatch.end() + Ret = self.NUM + else: + raise _ExprError(ST.ERR_EXPR_LIST % self.Token) + + return Ret + ## _StringTestParser # class _StringTestParser(_ExprBase): @@ -423,37 +493,38 @@ class _StringTestParser(_ExprBase): self.StringItem() if not self.IsCurrentOp(["==", "EQ", "!=", "NE"]): raise _ExprError(ST.ERR_EXPR_EQUALITY % \ - (self.Token, self.Token[self.Index:])) + (self.Token[self.Index:], self.Token)) self.StringItem() if self.Index != self.Len: raise _ExprError(ST.ERR_EXPR_BOOLEAN % \ (self.Token[self.Index:], self.Token)) ## -# Check syntax of logical expression +# Check syntax of string test # -# @param Token: expression token +# @param Token: string test token # -def IsValidLogicalExpr(Token, Flag=False): +def IsValidStringTest(Token, Flag=False): # # Not do the check right now, keep the implementation for future enhancement. # if not Flag: return True, "" - return _LogicalExpressionParser(Token).IsValidLogicalExpression() + return _StringTestParser(Token).IsValidStringTest() + ## -# Check syntax of string test +# Check syntax of logical expression # -# @param Token: string test token +# @param Token: expression token # -def IsValidStringTest(Token, Flag=False): +def IsValidLogicalExpr(Token, Flag=False): # # Not do the check right now, keep the implementation for future enhancement. # if not Flag: return True, "" - return _StringTestParser(Token).IsValidStringTest() + return _LogicalExpressionParser(Token).IsValidLogicalExpression() ## # Check syntax of range expression @@ -463,6 +534,14 @@ def IsValidStringTest(Token, Flag=False): def IsValidRangeExpr(Token): return _ValidRangeExpressionParser(Token).IsValidRangeExpression() +## +# Check syntax of value list expression token +# +# @param Token: value list expression token +# +def IsValidListExpr(Token): + return _ValidListExpressionParser(Token).IsValidListExpression() + ## # Check whether the feature flag expression is valid or not # @@ -486,4 +565,8 @@ def IsValidFeatureFlagExp(Token, Flag=False): return True, "" if __name__ == '__main__': - print _LogicalExpressionParser('a ^ b > a + b').IsValidLogicalExpression() +# print IsValidRangeExpr('LT 9') + print _LogicalExpressionParser('gCrownBayTokenSpaceGuid.PcdPciDevice1BridgeAddressLE0').IsValidLogicalExpression() + + + diff --git a/BaseTools/Source/Python/UPT/Library/GlobalData.py b/BaseTools/Source/Python/UPT/Library/GlobalData.py index e47e24a714..d478983c23 100644 --- a/BaseTools/Source/Python/UPT/Library/GlobalData.py +++ b/BaseTools/Source/Python/UPT/Library/GlobalData.py @@ -1,7 +1,7 @@ ## @file # This file is used to define common static strings and global data used by UPT # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -92,6 +92,17 @@ gUNPACK_DIR = None # Flag used to mark whether the INF file is Binary INF or not. # gIS_BINARY_INF = False + +# +# Used by FileHook module. +# +gRECOVERMGR = None + +# +# Used by PCD parser +# +gPackageDict = {} + # # Used by Library instance parser # {FilePath: FileObj} diff --git a/BaseTools/Source/Python/UPT/Library/Misc.py b/BaseTools/Source/Python/UPT/Library/Misc.py index 750805e328..bc9e0e172b 100644 --- a/BaseTools/Source/Python/UPT/Library/Misc.py +++ b/BaseTools/Source/Python/UPT/Library/Misc.py @@ -1,7 +1,7 @@ ## @file # Common routines used by all tools # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -41,11 +41,15 @@ from Library import GlobalData from Library.DataType import SUP_MODULE_LIST from Library.DataType import END_OF_LINE from Library.DataType import TAB_SPLIT -from Library.DataType import LANGUAGE_EN_US +from Library.DataType import TAB_LANGUAGE_EN_US +from Library.DataType import TAB_LANGUAGE_EN +from Library.DataType import TAB_LANGUAGE_EN_X +from Library.DataType import TAB_UNI_FILE_SUFFIXS from Library.String import GetSplitValueList from Library.ParserValidate import IsValidHexVersion from Library.ParserValidate import IsValidPath from Object.POM.CommonObject import TextObject +from Core.FileHook import __FileHookOpen__ ## Convert GUID string in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx style to C # structure style @@ -160,14 +164,14 @@ def SaveFileOnChange(File, Content, IsBinaryFile=True): if os.path.exists(File): try: - if Content == open(File, "rb").read(): + if Content == __FileHookOpen__(File, "rb").read(): return False except BaseException: Logger.Error(None, ToolError.FILE_OPEN_FAILURE, ExtraData=File) CreateDirectory(os.path.dirname(File)) try: - FileFd = open(File, "wb") + FileFd = __FileHookOpen__(File, "wb") FileFd.write(Content) FileFd.close() except BaseException: @@ -188,6 +192,8 @@ def GetFiles(Root, SkipList=None, FullPath=True): for Item in SkipList: if Item in Dirs: Dirs.remove(Item) + if Item in Files: + Files.remove(Item) for Dir in Dirs: if Dir.startswith('.'): Dirs.remove(Dir) @@ -566,39 +572,46 @@ class PathClass(object): Key = property(_GetFileKey) -## Check environment variables +## Get current workspace # -# Check environment variables that must be set for build. Currently they are +# get WORKSPACE from environment variable if present,if not use current working directory as WORKSPACE # -# WORKSPACE The directory all packages/platforms start from -# EDK_TOOLS_PATH The directory contains all tools needed by the build -# PATH $(EDK_TOOLS_PATH)/Bin/ must be set in PATH -# -# If any of above environment variable is not set or has error, the build -# will be broken. -# -def CheckEnvVariable(): +def GetWorkspace(): # # check WORKSPACE # - if "WORKSPACE" not in environ: - Logger.Error("UPT", - ToolError.UPT_ENVIRON_MISSING_ERROR, - ST.ERR_NOT_FOUND_ENVIRONMENT, - ExtraData="WORKSPACE") - - WorkspaceDir = os.path.normpath(environ["WORKSPACE"]) - if not os.path.exists(WorkspaceDir): - Logger.Error("UPT", - ToolError.UPT_ENVIRON_MISSING_ERROR, - ST.ERR_WORKSPACE_NOTEXIST, - ExtraData="%s" % WorkspaceDir) - elif ' ' in WorkspaceDir: - Logger.Error("UPT", - ToolError.FORMAT_NOT_SUPPORTED, - ST.ERR_SPACE_NOTALLOWED, - ExtraData=WorkspaceDir) + if "WORKSPACE" in environ: + WorkspaceDir = os.path.normpath(environ["WORKSPACE"]) + if not os.path.exists(WorkspaceDir): + Logger.Error("UPT", + ToolError.UPT_ENVIRON_MISSING_ERROR, + ST.ERR_WORKSPACE_NOTEXIST, + ExtraData="%s" % WorkspaceDir) + else: + WorkspaceDir = os.getcwd() + if WorkspaceDir[-1] == ':': + WorkspaceDir += os.sep + return WorkspaceDir + +## Get relative path +# +# use full path and workspace to get relative path +# the destination of this function is mainly to resolve the root path issue(like c: or c:\) +# +# @param Fullpath: a string of fullpath +# @param Workspace: a string of workspace +# +def GetRelativePath(Fullpath, Workspace): + + RelativePath = '' + if Workspace.endswith(os.sep): + RelativePath = Fullpath[Fullpath.upper().find(Workspace.upper())+len(Workspace):] + else: + RelativePath = Fullpath[Fullpath.upper().find(Workspace.upper())+len(Workspace)+1:] + + return RelativePath + ## Check whether all module types are in list # # check whether all module types (SUP_MODULE_LIST) are in list @@ -644,7 +657,7 @@ class MergeCommentDict(dict): # def GenDummyHelpTextObj(): HelpTxt = TextObject() - HelpTxt.SetLang(LANGUAGE_EN_US) + HelpTxt.SetLang(TAB_LANGUAGE_EN_US) HelpTxt.SetString(' ') return HelpTxt @@ -972,3 +985,136 @@ def GetLibInstanceInfo(String, WorkSpace, LineNo): VerString = GetSplitValueList(VerString, '=', 1)[1] return FileGuidString, VerString + +## GetLocalValue +# +# Generate the local value for INF and DEC file. If Lang attribute not present, then use this value. +# If present, and there is no element without the Lang attribute, and one of the elements has the rfc1766 code is +# "en-x-tianocore", or "en-US" if "en-x-tianocore" was not found, or "en" if "en-US" was not found, or startswith 'en' +# if 'en' was not found, then use this value. +# If multiple entries of a tag exist which have the same language code, use the last entry. +# +# @param ValueList A list need to be processed. +# @param UseFirstValue: True to use the first value, False to use the last value +# +# @return LocalValue +def GetLocalValue(ValueList, UseFirstValue=False): + Value1 = '' + Value2 = '' + Value3 = '' + Value4 = '' + Value5 = '' + for (Key, Value) in ValueList: + if Key == TAB_LANGUAGE_EN_X: + if UseFirstValue: + if not Value1: + Value1 = Value + else: + Value1 = Value + if Key == TAB_LANGUAGE_EN_US: + if UseFirstValue: + if not Value2: + Value2 = Value + else: + Value2 = Value + if Key == TAB_LANGUAGE_EN: + if UseFirstValue: + if not Value3: + Value3 = Value + else: + Value3 = Value + if Key.startswith(TAB_LANGUAGE_EN): + if UseFirstValue: + if not Value4: + Value4 = Value + else: + Value4 = Value + if Key == '': + if UseFirstValue: + if not Value5: + Value5 = Value + else: + Value5 = Value + + if Value1: + return Value1 + if Value2: + return Value2 + if Value3: + return Value3 + if Value4: + return Value4 + if Value5: + return Value5 + + return '' + + +## GetCharIndexOutStr +# +# Get comment character index outside a string +# +# @param Line: The string to be checked +# @param CommentCharacter: Comment char, used to ignore comment content +# +# @retval Index +# +def GetCharIndexOutStr(CommentCharacter, Line): + # + # remove whitespace + # + Line = Line.strip() + + # + # Check whether comment character is in a string + # + InString = False + for Index in range(0, len(Line)): + if Line[Index] == '"': + InString = not InString + elif Line[Index] == CommentCharacter and InString : + pass + elif Line[Index] == CommentCharacter and (Index +1) < len(Line) and Line[Index+1] == CommentCharacter \ + and not InString : + return Index + return -1 + +## ValidateUNIFilePath +# +# Check the UNI file path +# +# @param FilePath: The UNI file path +# +def ValidateUNIFilePath(Path): + Suffix = Path[Path.rfind(TAB_SPLIT):] + + # + # Check if the suffix is one of the '.uni', '.UNI', '.Uni' + # + if Suffix not in TAB_UNI_FILE_SUFFIXS: + Logger.Error("Unicode File Parser", + ToolError.FORMAT_INVALID, + Message=ST.ERR_UNI_FILE_SUFFIX_WRONG, + ExtraData=Path) + + # + # Check if '..' in the file name(without suffixe) + # + if (TAB_SPLIT + TAB_SPLIT) in Path: + Logger.Error("Unicode File Parser", + ToolError.FORMAT_INVALID, + Message=ST.ERR_UNI_FILE_NAME_INVALID, + ExtraData=Path) + + # + # Check if the file name is valid according to the DEC and INF specification + # + Pattern = '[a-zA-Z0-9_][a-zA-Z0-9_\-\.]*' + FileName = Path.replace(Suffix, '') + InvalidCh = re.sub(Pattern, '', FileName) + if InvalidCh: + Logger.Error("Unicode File Parser", + ToolError.FORMAT_INVALID, + Message=ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID, + ExtraData=Path) + diff --git a/BaseTools/Source/Python/UPT/Library/ParserValidate.py b/BaseTools/Source/Python/UPT/Library/ParserValidate.py index 860fb4f1dc..bfb4bc749f 100644 --- a/BaseTools/Source/Python/UPT/Library/ParserValidate.py +++ b/BaseTools/Source/Python/UPT/Library/ParserValidate.py @@ -1,6 +1,7 @@ ## @file ParserValidate.py +# Functions for parser validation # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -566,7 +567,7 @@ def IsValidPcdValue(PcdValue): for Char in PcdValue: if Char == '\n' or Char == '\t' or Char == '\f': return False - + # # # @@ -582,7 +583,7 @@ def IsValidPcdValue(PcdValue): if IsValidHex(PcdValue): return True - ReIsValidIntegerSingle = re.compile(r"^\s*[0-9]\s*$", re.DOTALL) + ReIsValidIntegerSingle = re.compile(r"^\s*[0-9]\s*$", re.DOTALL) if ReIsValidIntegerSingle.match(PcdValue) != None: return True @@ -590,7 +591,6 @@ def IsValidPcdValue(PcdValue): if ReIsValidIntegerMulti.match(PcdValue) != None: return True - # # ::= {} {} {"$(" ")"} # ::= {} {} diff --git a/BaseTools/Source/Python/UPT/Library/Parsing.py b/BaseTools/Source/Python/UPT/Library/Parsing.py index 95c51406b2..db0fec3a73 100644 --- a/BaseTools/Source/Python/UPT/Library/Parsing.py +++ b/BaseTools/Source/Python/UPT/Library/Parsing.py @@ -2,7 +2,7 @@ # This file is used to define common parsing related functions used in parsing # INF/DEC/DSC process # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -42,6 +42,7 @@ from Logger import StringTable as ST import Logger.Log as Logger from Parser.DecParser import Dec +import GlobalData gPKG_INFO_DICT = {} @@ -53,7 +54,7 @@ gPKG_INFO_DICT = {} # @param String: String with BuildOption statement # @param File: The file which defines build option, used in error report # -def GetBuildOption(String, File, LineNo=-1): +def GetBuildOption(String, File, LineNo= -1): (Family, ToolChain, Flag) = ('', '', '') if String.find(DataType.TAB_EQUAL_SPLIT) < 0: RaiseParserError(String, 'BuildOptions', File, \ @@ -76,7 +77,7 @@ def GetBuildOption(String, File, LineNo=-1): # @param ContainerFile: The file which describes the library class, used for # error report # -def GetLibraryClass(Item, ContainerFile, WorkspaceDir, LineNo=-1): +def GetLibraryClass(Item, ContainerFile, WorkspaceDir, LineNo= -1): List = GetSplitValueList(Item[0]) SupMod = DataType.SUP_MODULE_LIST_STRING if len(List) != 2: @@ -101,7 +102,7 @@ def GetLibraryClass(Item, ContainerFile, WorkspaceDir, LineNo=-1): # @param ContainerFile: The file which describes the library class, used for # error report # -def GetLibraryClassOfInf(Item, ContainerFile, WorkspaceDir, LineNo = -1): +def GetLibraryClassOfInf(Item, ContainerFile, WorkspaceDir, LineNo= -1): ItemList = GetSplitValueList((Item[0] + DataType.TAB_VALUE_SPLIT * 2)) SupMod = DataType.SUP_MODULE_LIST_STRING @@ -131,7 +132,7 @@ def GetLibraryClassOfInf(Item, ContainerFile, WorkspaceDir, LineNo = -1): # @param Section: Used for error report # @param File: Used for error report # -def CheckPcdTokenInfo(TokenInfoString, Section, File, LineNo=-1): +def CheckPcdTokenInfo(TokenInfoString, Section, File, LineNo= -1): Format = '.' if TokenInfoString != '' and TokenInfoString != None: TokenInfoList = GetSplitValueList(TokenInfoString, DataType.TAB_SPLIT) @@ -151,7 +152,7 @@ def CheckPcdTokenInfo(TokenInfoString, Section, File, LineNo=-1): # report # -def GetPcd(Item, Type, ContainerFile, LineNo=-1): +def GetPcd(Item, Type, ContainerFile, LineNo= -1): TokenGuid, TokenName, Value, MaximumDatumSize, Token = '', '', '', '', '' List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT * 2) @@ -178,7 +179,7 @@ def GetPcd(Item, Type, ContainerFile, LineNo=-1): # @param ContainerFile: The file which describes the pcd, used for error # report # -def GetFeatureFlagPcd(Item, Type, ContainerFile, LineNo=-1): +def GetFeatureFlagPcd(Item, Type, ContainerFile, LineNo= -1): TokenGuid, TokenName, Value = '', '', '' List = GetSplitValueList(Item) if len(List) != 2: @@ -202,7 +203,7 @@ def GetFeatureFlagPcd(Item, Type, ContainerFile, LineNo=-1): # @param ContainerFile: The file which describes the pcd, used for error # report # -def GetDynamicDefaultPcd(Item, Type, ContainerFile, LineNo=-1): +def GetDynamicDefaultPcd(Item, Type, ContainerFile, LineNo= -1): TokenGuid, TokenName, Value, DatumTyp, MaxDatumSize = '', '', '', '', '' List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT * 2) if len(List) < 4 or len(List) > 8: @@ -228,7 +229,7 @@ def GetDynamicDefaultPcd(Item, Type, ContainerFile, LineNo=-1): # @param ContainerFile: The file which describes the pcd, used for error # report # -def GetDynamicHiiPcd(Item, Type, ContainerFile, LineNo = -1): +def GetDynamicHiiPcd(Item, Type, ContainerFile, LineNo= -1): TokenGuid, TokenName, List1, List2, List3, List4, List5 = \ '', '', '', '', '', '', '' List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT * 2) @@ -255,7 +256,7 @@ def GetDynamicHiiPcd(Item, Type, ContainerFile, LineNo = -1): # @param ContainerFile: The file which describes the pcd, used for error # report # -def GetDynamicVpdPcd(Item, Type, ContainerFile, LineNo=-1): +def GetDynamicVpdPcd(Item, Type, ContainerFile, LineNo= -1): TokenGuid, TokenName, List1, List2 = '', '', '', '' List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT) if len(List) < 3 or len(List) > 4: @@ -533,7 +534,7 @@ def GetComponents(Lines, KeyValues, CommentCharacter): # @param ContainerFile: The file which describes the library class, used # for error report # -def GetSource(Item, ContainerFile, FileRelativePath, LineNo=-1): +def GetSource(Item, ContainerFile, FileRelativePath, LineNo= -1): ItemNew = Item + DataType.TAB_VALUE_SPLIT * 4 List = GetSplitValueList(ItemNew) if len(List) < 5 or len(List) > 9: @@ -558,7 +559,7 @@ def GetSource(Item, ContainerFile, FileRelativePath, LineNo=-1): # @param ContainerFile: The file which describes the library class, # used for error report # -def GetBinary(Item, ContainerFile, LineNo=-1): +def GetBinary(Item, ContainerFile, LineNo= -1): ItemNew = Item + DataType.TAB_VALUE_SPLIT List = GetSplitValueList(ItemNew) if len(List) < 3 or len(List) > 5: @@ -596,7 +597,7 @@ def GetGuidsProtocolsPpisOfInf(Item): # @param ContainerFile: The file which describes the library class, # used for error report # -def GetGuidsProtocolsPpisOfDec(Item, Type, ContainerFile, LineNo=-1): +def GetGuidsProtocolsPpisOfDec(Item, Type, ContainerFile, LineNo= -1): List = GetSplitValueList(Item, DataType.TAB_EQUAL_SPLIT) if len(List) != 2: RaiseParserError(Item, Type, ContainerFile, '=', \ @@ -614,7 +615,7 @@ def GetGuidsProtocolsPpisOfDec(Item, Type, ContainerFile, LineNo=-1): RegisterFormatGuid = List[1] else: RaiseParserError(Item, Type, ContainerFile, \ - 'CFormat or RegisterFormat', LineNo) + 'CFormat or RegisterFormat', LineNo) return (List[0], RegisterFormatGuid) @@ -627,7 +628,7 @@ def GetGuidsProtocolsPpisOfDec(Item, Type, ContainerFile, LineNo=-1): # @param ContainerFile: The file which describes the library class, # used for error report # -def GetPackage(Item, ContainerFile, FileRelativePath, LineNo=-1): +def GetPackage(Item, ContainerFile, FileRelativePath, LineNo= -1): ItemNew = Item + DataType.TAB_VALUE_SPLIT List = GetSplitValueList(ItemNew) CheckFileType(List[0], '.Dec', ContainerFile, 'package', List[0], LineNo) @@ -683,7 +684,7 @@ def GetPcdOfInf(Item, Type, File, LineNo): # @param File: Dec file # @param LineNo: Line number # -def GetPcdOfDec(Item, Type, File, LineNo=-1): +def GetPcdOfDec(Item, Type, File, LineNo= -1): Format = '.|||' TokenGuid, TokenName, Value, DatumType, Token = '', '', '', '', '' List = GetSplitValueList(Item) @@ -756,7 +757,7 @@ def InsertSectionItems(Model, SectionItemList, ArchList, \ LineValue, StartLine, Comment = SectionItem[0], \ SectionItem[1], SectionItem[2] - Logger.Debug(4, ST.MSG_PARSING %LineValue) + Logger.Debug(4, ST.MSG_PARSING % LineValue) # # And then parse DEFINE statement # @@ -782,7 +783,7 @@ def GenMetaDatSectionItem(Key, Value, List): List[Key] = [Value] else: List[Key].append(Value) - + ## GetPkgInfoFromDec # # get package name, guid, version info from dec files @@ -793,17 +794,23 @@ def GetPkgInfoFromDec(Path): PkgName = None PkgGuid = None PkgVersion = None - + Path = Path.replace('\\', '/') - + if not os.path.exists(Path): - Logger.Error("\nUPT", FILE_NOT_FOUND, File = Path) + Logger.Error("\nUPT", FILE_NOT_FOUND, File=Path) if Path in gPKG_INFO_DICT: return gPKG_INFO_DICT[Path] try: - DecParser = Dec(Path) + DecParser = None + if Path not in GlobalData.gPackageDict: + DecParser = Dec(Path) + GlobalData.gPackageDict[Path] = DecParser + else: + DecParser = GlobalData.gPackageDict[Path] + PkgName = DecParser.GetPackageName() PkgGuid = DecParser.GetPackageGuid() PkgVersion = DecParser.GetPackageVersion() @@ -819,7 +826,7 @@ def GetPkgInfoFromDec(Path): # def GetWorkspacePackage(): DecFileList = [] - WorkspaceDir = os.environ["WORKSPACE"] + WorkspaceDir = GlobalData.gWORKSPACE for Root, Dirs, Files in os.walk(WorkspaceDir): if 'CVS' in Dirs: Dirs.remove('CVS') @@ -843,7 +850,7 @@ def GetWorkspacePackage(): (PkgName, PkgGuid, PkgVersion) = GetPkgInfoFromDec(DecFile) if PkgName and PkgGuid and PkgVersion: PkgList.append((PkgName, PkgGuid, PkgVersion, DecFile)) - + return PkgList ## GetWorkspaceModule @@ -852,7 +859,7 @@ def GetWorkspacePackage(): # def GetWorkspaceModule(): InfFileList = [] - WorkspaceDir = os.environ["WORKSPACE"] + WorkspaceDir = GlobalData.gWORKSPACE for Root, Dirs, Files in os.walk(WorkspaceDir): if 'CVS' in Dirs: Dirs.remove('CVS') @@ -870,7 +877,7 @@ def GetWorkspaceModule(): if Ext.lower() in ['.inf']: InfFileList.append\ (os.path.normpath(os.path.join(Root, FileSp))) - + return InfFileList ## MacroParser used to parse macro definition @@ -890,7 +897,7 @@ def MacroParser(Line, FileName, SectionType, FileLocalMacros): # Not 'DEFINE/EDK_GLOBAL' statement, call decorated method # return None, None - + TokenList = GetSplitValueList(LineContent[Match.end(1):], \ DataType.TAB_EQUAL_SPLIT, 1) # @@ -910,16 +917,16 @@ def MacroParser(Line, FileName, SectionType, FileLocalMacros): # if SectionType == DataType.MODEL_META_DATA_HEADER: FileLocalMacros[Name] = Value - + ReIsValidMacroName = re.compile(r"^[A-Z][A-Z0-9_]*$", re.DOTALL) if ReIsValidMacroName.match(Name) == None: - Logger.Error('Parser', - FORMAT_INVALID, - ST.ERR_MACRONAME_INVALID%(Name), - ExtraData=LineContent, - File=FileName, + Logger.Error('Parser', + FORMAT_INVALID, + ST.ERR_MACRONAME_INVALID % (Name), + ExtraData=LineContent, + File=FileName, Line=LineNo) - + # Validate MACRO Value # # ::= []{0,} @@ -932,13 +939,13 @@ def MacroParser(Line, FileName, SectionType, FileLocalMacros): # ReIsValidMacroValue = re.compile(r"^[\x20-\x7e]*$", re.DOTALL) if ReIsValidMacroValue.match(Value) == None: - Logger.Error('Parser', - FORMAT_INVALID, - ST.ERR_MACROVALUE_INVALID%(Value), - ExtraData=LineContent, - File=FileName, + Logger.Error('Parser', + FORMAT_INVALID, + ST.ERR_MACROVALUE_INVALID % (Value), + ExtraData=LineContent, + File=FileName, Line=LineNo) - + return Name, Value ## GenSection @@ -952,7 +959,7 @@ def MacroParser(Line, FileName, SectionType, FileLocalMacros): # seperated by space, # value is statement # -def GenSection(SectionName, SectionDict, SplitArch=True): +def GenSection(SectionName, SectionDict, SplitArch=True, NeedBlankLine=False): Content = '' for SectionAttrs in SectionDict: StatementList = SectionDict[SectionAttrs] @@ -969,11 +976,29 @@ def GenSection(SectionName, SectionDict, SplitArch=True): Section = '[' + SectionName + '.' + (', ' + SectionName + '.').join(ArchList) + ']' else: Section = '[' + SectionName + ']' - Content += '\n\n' + Section + '\n' + Content += '\n' + Section + '\n' if StatementList != None: for Statement in StatementList: - Content += Statement + '\n' + LineList = Statement.split('\n') + NewStatement = "" + for Line in LineList: + # ignore blank comment + if not Line.replace("#", '').strip() and SectionName != 'Defines': + continue + # add two space before non-comments line except the comments in Defines section + if Line.strip().startswith('#') and SectionName == 'Defines': + NewStatement += "%s\n" % Line + continue + NewStatement += " %s\n" % Line + if NeedBlankLine: + Content += NewStatement + '\n' + else: + Content += NewStatement + if NeedBlankLine: + Content = Content[:-1] + if not Content.replace('\\n', '').strip(): + return '' return Content ## ConvertArchForInstall @@ -984,10 +1009,10 @@ def GenSection(SectionName, SectionDict, SplitArch=True): # @return: the arch string that get converted # def ConvertArchForInstall(Arch): - if Arch.upper() in [DataType.TAB_ARCH_IA32, DataType.TAB_ARCH_X64, + if Arch.upper() in [DataType.TAB_ARCH_IA32, DataType.TAB_ARCH_X64, DataType.TAB_ARCH_IPF, DataType.TAB_ARCH_EBC]: Arch = Arch.upper() elif Arch.upper() == DataType.TAB_ARCH_COMMON: Arch = Arch.lower() - + return Arch diff --git a/BaseTools/Source/Python/UPT/Library/String.py b/BaseTools/Source/Python/UPT/Library/String.py index f709ff1bce..37ce1418ae 100644 --- a/BaseTools/Source/Python/UPT/Library/String.py +++ b/BaseTools/Source/Python/UPT/Library/String.py @@ -1,12 +1,12 @@ ## @file -# This file is used to define common string related functions used in parsing +# This file is used to define common string related functions used in parsing # process # # Copyright (c) 2011 - 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 +# 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, @@ -43,7 +43,7 @@ gMACRO_PATTERN = re.compile("\$\(([_A-Z][_A-Z0-9]*)\)", re.UNICODE) # @param MaxSplit: The max number of split values, default is -1 # # -def GetSplitValueList(String, SplitTag=DataType.TAB_VALUE_SPLIT, MaxSplit=-1): +def GetSplitValueList(String, SplitTag=DataType.TAB_VALUE_SPLIT, MaxSplit= -1): return map(lambda l: l.strip(), String.split(SplitTag, MaxSplit)) ## MergeArches @@ -129,7 +129,7 @@ def GetDynamics(Lines, Key, KeyValues, CommentCharacter): ## SplitModuleType # # Split ModuleType out of section defien to get key -# [LibraryClass.Arch.ModuleType|ModuleType|ModuleType] -> [ +# [LibraryClass.Arch.ModuleType|ModuleType|ModuleType] -> [ # 'LibraryClass.Arch', ['ModuleType', 'ModuleType', 'ModuleType'] ] # # @param Key: String to be parsed @@ -164,7 +164,7 @@ def SplitModuleType(Key): # @param Line: The content contain line string and line number # @param FileName: The meta-file file name # -def ReplaceMacro(String, MacroDefinitions = None, SelfReplacement = False, Line = None, FileName = None, Flag = False): +def ReplaceMacro(String, MacroDefinitions=None, SelfReplacement=False, Line=None, FileName=None, Flag=False): LastString = String if MacroDefinitions == None: MacroDefinitions = {} @@ -184,10 +184,10 @@ def ReplaceMacro(String, MacroDefinitions = None, SelfReplacement = False, Line Count += 1 if Count % 2 != 0: MacroString += QuotedStringItem - - if Count == len(QuotedStringList) and Count%2 == 0: + + if Count == len(QuotedStringList) and Count % 2 == 0: MacroString += QuotedStringItem - + MacroUsed = gMACRO_PATTERN.findall(MacroString) # # no macro found in String, stop replacing @@ -198,7 +198,7 @@ def ReplaceMacro(String, MacroDefinitions = None, SelfReplacement = False, Line if Macro not in MacroDefinitions: if SelfReplacement: String = String.replace("$(%s)" % Macro, '') - Logger.Debug(5, "Delete undefined MACROs in file %s line %d: %s!" %(FileName, Line[1], Line[0])) + Logger.Debug(5, "Delete undefined MACROs in file %s line %d: %s!" % (FileName, Line[1], Line[0])) continue if not HaveQuotedMacroFlag: String = String.replace("$(%s)" % Macro, MacroDefinitions[Macro]) @@ -207,25 +207,25 @@ def ReplaceMacro(String, MacroDefinitions = None, SelfReplacement = False, Line for QuotedStringItem in QuotedStringList: Count += 1 if Count % 2 != 0: - QuotedStringList[Count-1] = QuotedStringList[Count-1].replace("$(%s)" % Macro, + QuotedStringList[Count - 1] = QuotedStringList[Count - 1].replace("$(%s)" % Macro, MacroDefinitions[Macro]) - elif Count == len(QuotedStringList) and Count%2 == 0: - QuotedStringList[Count-1] = QuotedStringList[Count-1].replace("$(%s)" % Macro, + elif Count == len(QuotedStringList) and Count % 2 == 0: + QuotedStringList[Count - 1] = QuotedStringList[Count - 1].replace("$(%s)" % Macro, MacroDefinitions[Macro]) - + RetString = '' if HaveQuotedMacroFlag: Count = 0 for QuotedStringItem in QuotedStringList: - Count += 1 + Count += 1 if Count != len(QuotedStringList): - RetString += QuotedStringList[Count-1] + "\"" + RetString += QuotedStringList[Count - 1] + "\"" else: - RetString += QuotedStringList[Count-1] - + RetString += QuotedStringList[Count - 1] + String = RetString - - # + + # # in case there's macro not defined # if String == LastString: @@ -242,7 +242,7 @@ def ReplaceMacro(String, MacroDefinitions = None, SelfReplacement = False, Line # @param Path: The input value for Path to be converted # @param Defines: A set for DEFINE statement # -def NormPath(Path, Defines = None): +def NormPath(Path, Defines=None): IsRelativePath = False if Defines == None: Defines = {} @@ -269,7 +269,7 @@ def NormPath(Path, Defines = None): # Remove spaces # # @param Line: The string to be cleaned -# @param CommentCharacter: Comment char, used to ignore comment content, +# @param CommentCharacter: Comment char, used to ignore comment content, # default is DataType.TAB_COMMENT_SPLIT # def CleanString(Line, CommentCharacter=DataType.TAB_COMMENT_SPLIT, AllowCppStyleComment=False): @@ -305,7 +305,7 @@ def CleanString(Line, CommentCharacter=DataType.TAB_COMMENT_SPLIT, AllowCppStyle # Remove spaces # # @param Line: The string to be cleaned -# @param CommentCharacter: Comment char, used to ignore comment content, +# @param CommentCharacter: Comment char, used to ignore comment content, # default is DataType.TAB_COMMENT_SPLIT # def CleanString2(Line, CommentCharacter=DataType.TAB_COMMENT_SPLIT, AllowCppStyleComment=False): @@ -394,10 +394,10 @@ def GetDefineValue(String, Key, CommentCharacter): # @param CommentCharacter: Comment char, be used to ignore comment content # @param KeySplitCharacter: Key split char, between key name and key value. # Key1 = Value1, '=' is the key split char -# @param ValueSplitFlag: Value split flag, be used to decide if has +# @param ValueSplitFlag: Value split flag, be used to decide if has # multiple values -# @param ValueSplitCharacter: Value split char, be used to split multiple -# values. Key1 = Value1|Value2, '|' is the value +# @param ValueSplitCharacter: Value split char, be used to split multiple +# values. Key1 = Value1|Value2, '|' is the value # split char # def GetSingleValueOfKeyFromLines(Lines, Dictionary, CommentCharacter, KeySplitCharacter, \ @@ -489,7 +489,7 @@ def PreCheck(FileName, FileContent, SupSectionTag): # if Line.find('$') > -1: if Line.find('$(') < 0 or Line.find(')') < 0: - Logger.Error("Parser", FORMAT_INVALID, Line=LineNo, File=FileName, RaiseError = Logger.IS_RAISE_ERROR) + Logger.Error("Parser", FORMAT_INVALID, Line=LineNo, File=FileName, RaiseError=Logger.IS_RAISE_ERROR) # # Check [] # @@ -498,14 +498,14 @@ def PreCheck(FileName, FileContent, SupSectionTag): # Only get one '[' or one ']' # if not (Line.find('[') > -1 and Line.find(']') > -1): - Logger.Error("Parser", FORMAT_INVALID, Line=LineNo, File=FileName, RaiseError = Logger.IS_RAISE_ERROR) + Logger.Error("Parser", FORMAT_INVALID, Line=LineNo, File=FileName, RaiseError=Logger.IS_RAISE_ERROR) # # Regenerate FileContent # NewFileContent = NewFileContent + Line + '\r\n' if IsFailed: - Logger.Error("Parser", FORMAT_INVALID, Line=LineNo, File=FileName, RaiseError = Logger.IS_RAISE_ERROR) + Logger.Error("Parser", FORMAT_INVALID, Line=LineNo, File=FileName, RaiseError=Logger.IS_RAISE_ERROR) return NewFileContent @@ -523,7 +523,7 @@ def PreCheck(FileName, FileContent, SupSectionTag): # @param Line: The line in container file which defines the file # to be checked # -def CheckFileType(CheckFilename, ExtName, ContainerFilename, SectionName, Line, LineNo=-1): +def CheckFileType(CheckFilename, ExtName, ContainerFilename, SectionName, Line, LineNo= -1): if CheckFilename != '' and CheckFilename != None: (Root, Ext) = os.path.splitext(CheckFilename) if Ext.upper() != ExtName.upper() and Root: @@ -544,13 +544,13 @@ def CheckFileType(CheckFilename, ExtName, ContainerFilename, SectionName, Line, # # @param CheckFilename: Name of the file to be checked # @param WorkspaceDir: Current workspace dir -# @param ContainerFilename: The container file which describes the file to +# @param ContainerFilename: The container file which describes the file to # be checked, used for error report # @param SectionName: Used for error report -# @param Line: The line in container file which defines the +# @param Line: The line in container file which defines the # file to be checked # -def CheckFileExist(WorkspaceDir, CheckFilename, ContainerFilename, SectionName, Line, LineNo=-1): +def CheckFileExist(WorkspaceDir, CheckFilename, ContainerFilename, SectionName, Line, LineNo= -1): CheckFile = '' if CheckFilename != '' and CheckFilename != None: CheckFile = WorkspaceFile(WorkspaceDir, CheckFilename) @@ -560,7 +560,7 @@ def CheckFileExist(WorkspaceDir, CheckFilename, ContainerFilename, SectionName, LineNo = GetLineNo(ContainerFile, Line) ErrorMsg = ST.ERR_CHECKFILE_NOTFOUND % (CheckFile, SectionName) Logger.Error("Parser", PARSER_ERROR, ErrorMsg, - File=ContainerFilename, Line = LineNo, RaiseError=Logger.IS_RAISE_ERROR) + File=ContainerFilename, Line=LineNo, RaiseError=Logger.IS_RAISE_ERROR) return CheckFile ## GetLineNo @@ -593,7 +593,7 @@ def GetLineNo(FileContent, Line, IsIgnoreComment=True): # @param File: File which has the string # @param Format: Correct format # -def RaiseParserError(Line, Section, File, Format='', LineNo=-1): +def RaiseParserError(Line, Section, File, Format='', LineNo= -1): if LineNo == -1: LineNo = GetLineNo(open(os.path.normpath(File), 'r').read(), Line) ErrorMsg = ST.ERR_INVALID_NOTFOUND % (Line, Section) @@ -650,7 +650,7 @@ def ConvertToSqlString2(String): # @param Lines: string list # @param Split: split character # -def GetStringOfList(List, Split = ' '): +def GetStringOfList(List, Split=' '): if type(List) != type([]): return List Str = '' @@ -696,7 +696,7 @@ def StringArrayLength(String): # @param OptionString: the option string # @param Which: Which flag # @param Against: Against flag -# +# def RemoveDupOption(OptionString, Which="/I", Against=None): OptionList = OptionString.split() ValueList = [] @@ -718,14 +718,14 @@ def RemoveDupOption(OptionString, Which="/I", Against=None): ## Check if the string is HexDgit # -# Return true if all characters in the string are digits and there is at -# least one character +# Return true if all characters in the string are digits and there is at +# least one character # or valid Hexs (started with 0x, following by hexdigit letters) -# , false otherwise. +# , false otherwise. # @param string: input string # def IsHexDigit(Str): - try: + try: int(Str, 10) return True except ValueError: @@ -737,16 +737,16 @@ def IsHexDigit(Str): return False return False -## Check if the string is HexDgit and its integer value within limit of UINT32 +## Check if the string is HexDgit and its interger value within limit of UINT32 # -# Return true if all characters in the string are digits and there is at -# least one character +# Return true if all characters in the string are digits and there is at +# least one character # or valid Hexs (started with 0x, following by hexdigit letters) -# , false otherwise. +# , false otherwise. # @param string: input string # def IsHexDigitUINT32(Str): - try: + try: Value = int(Str, 10) if (Value <= 0xFFFFFFFF) and (Value >= 0): return True @@ -761,11 +761,11 @@ def IsHexDigitUINT32(Str): return False ## CleanSpecialChar -# -# The ASCII text files of type INF, DEC, INI are edited by developers, +# +# The ASCII text files of type INF, DEC, INI are edited by developers, # and may contain characters that cannot be directly translated to strings that -# are conformant with the UDP XML Schema. Any characters in this category -# (0x00-0x08, TAB [0x09], 0x0B, 0x0C, 0x0E-0x1F, 0x80-0xFF) +# are conformant with the UDP XML Schema. Any characters in this category +# (0x00-0x08, TAB [0x09], 0x0B, 0x0C, 0x0E-0x1F, 0x80-0xFF) # must be converted to a space character[0x20] as part of the parsing process. # def ConvertSpecialChar(Lines): @@ -773,7 +773,7 @@ def ConvertSpecialChar(Lines): for line in Lines: ReMatchSpecialChar = re.compile(r"[\x00-\x08]|\x09|\x0b|\x0c|[\x0e-\x1f]|[\x7f-\xff]") RetLines.append(ReMatchSpecialChar.sub(' ', line)) - + return RetLines ## __GetTokenList @@ -817,7 +817,7 @@ def __GetTokenList(Str): if TokenOP: List.append(TokenOP) TokenOP = '' - + if PreChar == '\\' and Char == '\\': PreChar = '' else: @@ -870,61 +870,55 @@ def ConvertNOTEQToNE(Expr): return ''.join(RetList) ## SplitPcdEntry -# +# # Split an PCD entry string to Token.CName and PCD value and FFE. # NOTE: PCD Value and FFE can contain "|" in it's expression. And in INF specification, have below rule. -# When using the characters "|" or "||" in an expression, the expression must be encapsulated in +# When using the characters "|" or "||" in an expression, the expression must be encapsulated in # open "(" and close ")" parenthesis. -# +# # @param String An PCD entry string need to be split. -# -# @return List [PcdTokenCName, Value, FFE] +# +# @return List [PcdTokenCName, Value, FFE] # def SplitPcdEntry(String): if not String: - return ['', '',''], False - + return ['', '', ''], False + PcdTokenCName = '' PcdValue = '' PcdFeatureFlagExp = '' - + ValueList = GetSplitValueList(String, "|", 1) - + # # Only contain TokenCName # if len(ValueList) == 1: return [ValueList[0]], True - + NewValueList = [] - + if len(ValueList) == 2: PcdTokenCName = ValueList[0] - ValueList = GetSplitValueList(ValueList[1], "|") - - RemainCount = 0 - for Item in ValueList: - ParenthesisCount = 0 - for Char in Item: - if Char == "(": - ParenthesisCount += 1 - if Char == ")": - ParenthesisCount -= 1 - - # - # An individual item - # - if RemainCount == 0 and ParenthesisCount >= 0: - NewValueList.append(Item) - RemainCount = ParenthesisCount - elif RemainCount > 0 and RemainCount + ParenthesisCount >= 0: - NewValueList[-1] = NewValueList[-1] + '|' + Item - RemainCount = RemainCount + ParenthesisCount - elif RemainCount > 0 and RemainCount + ParenthesisCount < 0: - # - # ERROR, return - # - return ['', '', ''], False + + InQuote = False + InParenthesis = False + StrItem = '' + for StrCh in ValueList[1]: + if StrCh == '"': + InQuote = not InQuote + elif StrCh == '(' or StrCh == ')': + InParenthesis = not InParenthesis + + if StrCh == '|': + if not InQuote or not InParenthesis: + NewValueList.append(StrItem.strip()) + StrItem = ' ' + continue + + StrItem += StrCh + + NewValueList.append(StrItem.strip()) if len(NewValueList) == 1: PcdValue = NewValueList[0] @@ -935,7 +929,7 @@ def SplitPcdEntry(String): return [PcdTokenCName, PcdValue, PcdFeatureFlagExp], True else: return ['', '', ''], False - + return ['', '', ''], False ## Check if two arches matched? diff --git a/BaseTools/Source/Python/UPT/Library/UniClassObject.py b/BaseTools/Source/Python/UPT/Library/UniClassObject.py new file mode 100644 index 0000000000..d542dc5dc8 --- /dev/null +++ b/BaseTools/Source/Python/UPT/Library/UniClassObject.py @@ -0,0 +1,1042 @@ +## @file +# Collect all defined strings in multiple uni files. +# +# Copyright (c) 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. +# +""" +Collect all defined strings in multiple uni files +""" + +## +# Import Modules +# +import os, codecs, re +import distutils.util +from Logger import ToolError +from Logger import Log as EdkLogger +from Logger import StringTable as ST +from Library.String import GetLineNo +from Library.Misc import PathClass +from Library.Misc import GetCharIndexOutStr +from Library import DataType as DT + +## +# Static definitions +# +UNICODE_WIDE_CHAR = u'\\wide' +UNICODE_NARROW_CHAR = u'\\narrow' +UNICODE_NON_BREAKING_CHAR = u'\\nbr' +UNICODE_UNICODE_CR = '\r' +UNICODE_UNICODE_LF = '\n' + +NARROW_CHAR = u'\uFFF0' +WIDE_CHAR = u'\uFFF1' +NON_BREAKING_CHAR = u'\uFFF2' +CR = u'\u000D' +LF = u'\u000A' +NULL = u'\u0000' +TAB = u'\t' +BACK_SPLASH = u'\\' + +gINCLUDE_PATTERN = re.compile("^!include[\s]+([\S]+)[\s]*$", re.MULTILINE | re.UNICODE) + +gLANG_CONV_TABLE = {'eng':'en', 'fra':'fr', \ + 'aar':'aa', 'abk':'ab', 'ave':'ae', 'afr':'af', 'aka':'ak', 'amh':'am', \ + 'arg':'an', 'ara':'ar', 'asm':'as', 'ava':'av', 'aym':'ay', 'aze':'az', \ + 'bak':'ba', 'bel':'be', 'bul':'bg', 'bih':'bh', 'bis':'bi', 'bam':'bm', \ + 'ben':'bn', 'bod':'bo', 'bre':'br', 'bos':'bs', 'cat':'ca', 'che':'ce', \ + 'cha':'ch', 'cos':'co', 'cre':'cr', 'ces':'cs', 'chu':'cu', 'chv':'cv', \ + 'cym':'cy', 'dan':'da', 'deu':'de', 'div':'dv', 'dzo':'dz', 'ewe':'ee', \ + 'ell':'el', 'epo':'eo', 'spa':'es', 'est':'et', 'eus':'eu', 'fas':'fa', \ + 'ful':'ff', 'fin':'fi', 'fij':'fj', 'fao':'fo', 'fry':'fy', 'gle':'ga', \ + 'gla':'gd', 'glg':'gl', 'grn':'gn', 'guj':'gu', 'glv':'gv', 'hau':'ha', \ + 'heb':'he', 'hin':'hi', 'hmo':'ho', 'hrv':'hr', 'hat':'ht', 'hun':'hu', \ + 'hye':'hy', 'her':'hz', 'ina':'ia', 'ind':'id', 'ile':'ie', 'ibo':'ig', \ + 'iii':'ii', 'ipk':'ik', 'ido':'io', 'isl':'is', 'ita':'it', 'iku':'iu', \ + 'jpn':'ja', 'jav':'jv', 'kat':'ka', 'kon':'kg', 'kik':'ki', 'kua':'kj', \ + 'kaz':'kk', 'kal':'kl', 'khm':'km', 'kan':'kn', 'kor':'ko', 'kau':'kr', \ + 'kas':'ks', 'kur':'ku', 'kom':'kv', 'cor':'kw', 'kir':'ky', 'lat':'la', \ + 'ltz':'lb', 'lug':'lg', 'lim':'li', 'lin':'ln', 'lao':'lo', 'lit':'lt', \ + 'lub':'lu', 'lav':'lv', 'mlg':'mg', 'mah':'mh', 'mri':'mi', 'mkd':'mk', \ + 'mal':'ml', 'mon':'mn', 'mar':'mr', 'msa':'ms', 'mlt':'mt', 'mya':'my', \ + 'nau':'na', 'nob':'nb', 'nde':'nd', 'nep':'ne', 'ndo':'ng', 'nld':'nl', \ + 'nno':'nn', 'nor':'no', 'nbl':'nr', 'nav':'nv', 'nya':'ny', 'oci':'oc', \ + 'oji':'oj', 'orm':'om', 'ori':'or', 'oss':'os', 'pan':'pa', 'pli':'pi', \ + 'pol':'pl', 'pus':'ps', 'por':'pt', 'que':'qu', 'roh':'rm', 'run':'rn', \ + 'ron':'ro', 'rus':'ru', 'kin':'rw', 'san':'sa', 'srd':'sc', 'snd':'sd', \ + 'sme':'se', 'sag':'sg', 'sin':'si', 'slk':'sk', 'slv':'sl', 'smo':'sm', \ + 'sna':'sn', 'som':'so', 'sqi':'sq', 'srp':'sr', 'ssw':'ss', 'sot':'st', \ + 'sun':'su', 'swe':'sv', 'swa':'sw', 'tam':'ta', 'tel':'te', 'tgk':'tg', \ + 'tha':'th', 'tir':'ti', 'tuk':'tk', 'tgl':'tl', 'tsn':'tn', 'ton':'to', \ + 'tur':'tr', 'tso':'ts', 'tat':'tt', 'twi':'tw', 'tah':'ty', 'uig':'ug', \ + 'ukr':'uk', 'urd':'ur', 'uzb':'uz', 'ven':'ve', 'vie':'vi', 'vol':'vo', \ + 'wln':'wa', 'wol':'wo', 'xho':'xh', 'yid':'yi', 'yor':'yo', 'zha':'za', \ + 'zho':'zh', 'zul':'zu'} + +## Convert a python unicode string to a normal string +# +# Convert a python unicode string to a normal string +# UniToStr(u'I am a string') is 'I am a string' +# +# @param Uni: The python unicode string +# +# @retval: The formatted normal string +# +def UniToStr(Uni): + return repr(Uni)[2:-1] + +## Convert a unicode string to a Hex list +# +# Convert a unicode string to a Hex list +# UniToHexList('ABC') is ['0x41', '0x00', '0x42', '0x00', '0x43', '0x00'] +# +# @param Uni: The python unicode string +# +# @retval List: The formatted hex list +# +def UniToHexList(Uni): + List = [] + for Item in Uni: + Temp = '%04X' % ord(Item) + List.append('0x' + Temp[2:4]) + List.append('0x' + Temp[0:2]) + return List + +## Convert special unicode characters +# +# Convert special characters to (c), (r) and (tm). +# +# @param Uni: The python unicode string +# +# @retval NewUni: The converted unicode string +# +def ConvertSpecialUnicodes(Uni): + NewUni = Uni + NewUni = NewUni.replace(u'\u00A9', '(c)') + NewUni = NewUni.replace(u'\u00AE', '(r)') + NewUni = NewUni.replace(u'\u2122', '(tm)') + return NewUni + +## GetLanguageCode1766 +# +# Check the language code read from .UNI file and convert RFC 4646 codes to RFC 1766 codes +# RFC 1766 language codes supported in compatiblity mode +# RFC 4646 language codes supported in native mode +# +# @param LangName: Language codes read from .UNI file +# +# @retval LangName: Valid lanugage code in RFC 1766 format or None +# +def GetLanguageCode1766(LangName, File=None): + length = len(LangName) + if length == 2: + if LangName.isalpha(): + for Key in gLANG_CONV_TABLE.keys(): + if gLANG_CONV_TABLE.get(Key) == LangName.lower(): + return Key + elif length == 3: + if LangName.isalpha() and gLANG_CONV_TABLE.get(LangName.lower()): + return LangName + else: + EdkLogger.Error("Unicode File Parser", + ToolError.FORMAT_INVALID, + "Invalid RFC 1766 language code : %s" % LangName, + File) + elif length == 5: + if LangName[0:2].isalpha() and LangName[2] == '-': + for Key in gLANG_CONV_TABLE.keys(): + if gLANG_CONV_TABLE.get(Key) == LangName[0:2].lower(): + return Key + elif length >= 6: + if LangName[0:2].isalpha() and LangName[2] == '-': + for Key in gLANG_CONV_TABLE.keys(): + if gLANG_CONV_TABLE.get(Key) == LangName[0:2].lower(): + return Key + if LangName[0:3].isalpha() and gLANG_CONV_TABLE.get(LangName.lower()) == None and LangName[3] == '-': + for Key in gLANG_CONV_TABLE.keys(): + if Key == LangName[0:3].lower(): + return Key + + EdkLogger.Error("Unicode File Parser", + ToolError.FORMAT_INVALID, + "Invalid RFC 4646 language code : %s" % LangName, + File) + +## GetLanguageCode +# +# Check the language code read from .UNI file and convert RFC 1766 codes to RFC 4646 codes if appropriate +# RFC 1766 language codes supported in compatiblity mode +# RFC 4646 language codes supported in native mode +# +# @param LangName: Language codes read from .UNI file +# +# @retval LangName: Valid lanugage code in RFC 4646 format or None +# +def GetLanguageCode(LangName, IsCompatibleMode, File): + length = len(LangName) + if IsCompatibleMode: + if length == 3 and LangName.isalpha(): + TempLangName = gLANG_CONV_TABLE.get(LangName.lower()) + if TempLangName != None: + return TempLangName + return LangName + else: + EdkLogger.Error("Unicode File Parser", + ToolError.FORMAT_INVALID, + "Invalid RFC 1766 language code : %s" % LangName, + File) + if (LangName[0] == 'X' or LangName[0] == 'x') and LangName[1] == '-': + return LangName + if length == 2: + if LangName.isalpha(): + return LangName + elif length == 3: + if LangName.isalpha() and gLANG_CONV_TABLE.get(LangName.lower()) == None: + return LangName + elif length == 5: + if LangName[0:2].isalpha() and LangName[2] == '-': + return LangName + elif length >= 6: + if LangName[0:2].isalpha() and LangName[2] == '-': + return LangName + if LangName[0:3].isalpha() and gLANG_CONV_TABLE.get(LangName.lower()) == None and LangName[3] == '-': + return LangName + + EdkLogger.Error("Unicode File Parser", + ToolError.FORMAT_INVALID, + "Invalid RFC 4646 language code : %s" % LangName, + File) + +## FormatUniEntry +# +# Formated the entry in Uni file. +# +# @param StrTokenName StrTokenName. +# @param TokenValueList A list need to be processed. +# @param ContainerFile ContainerFile. +# +# @return formated entry +def FormatUniEntry(StrTokenName, TokenValueList, ContainerFile): + SubContent = '' + PreFormatLength = 40 + if len(StrTokenName) > PreFormatLength: + PreFormatLength = len(StrTokenName) + 1 + for (Lang, Value) in TokenValueList: + if not Value or Lang == DT.TAB_LANGUAGE_EN_X: + continue + if Lang == '': + Lang = DT.TAB_LANGUAGE_EN_US + if Lang == 'eng': + Lang = DT.TAB_LANGUAGE_EN_US + elif len(Lang.split('-')[0]) == 3: + Lang = GetLanguageCode(Lang.split('-')[0], True, ContainerFile) + else: + Lang = GetLanguageCode(Lang, False, ContainerFile) + ValueList = Value.split('\n') + SubValueContent = '' + for SubValue in ValueList: + if SubValue.strip(): + SubValueContent += \ + ' ' * (PreFormatLength + len('#language en-US ')) + '\"%s\\n\"' % SubValue.strip() + os.linesep + SubValueContent = SubValueContent[(PreFormatLength + len('#language en-US ')):SubValueContent.rfind('\\n')] \ + + '\"' + os.linesep + SubContent += ' '*PreFormatLength + '#language %-5s ' % Lang + SubValueContent + if SubContent: + SubContent = StrTokenName + ' '*(PreFormatLength - len(StrTokenName)) + SubContent[PreFormatLength:] + return SubContent + + +## StringDefClassObject +# +# A structure for language definition +# +class StringDefClassObject(object): + def __init__(self, Name = None, Value = None, Referenced = False, Token = None, UseOtherLangDef = ''): + self.StringName = '' + self.StringNameByteList = [] + self.StringValue = '' + self.StringValueByteList = '' + self.Token = 0 + self.Referenced = Referenced + self.UseOtherLangDef = UseOtherLangDef + self.Length = 0 + + if Name != None: + self.StringName = Name + self.StringNameByteList = UniToHexList(Name) + if Value != None: + self.StringValue = Value + self.StringValueByteList = UniToHexList(self.StringValue) + self.Length = len(self.StringValueByteList) + if Token != None: + self.Token = Token + + def __str__(self): + return repr(self.StringName) + ' ' + \ + repr(self.Token) + ' ' + \ + repr(self.Referenced) + ' ' + \ + repr(self.StringValue) + ' ' + \ + repr(self.UseOtherLangDef) + + def UpdateValue(self, Value = None): + if Value != None: + if self.StringValue: + self.StringValue = self.StringValue + os.linesep + Value + else: + self.StringValue = Value + self.StringValueByteList = UniToHexList(self.StringValue) + self.Length = len(self.StringValueByteList) + +## UniFileClassObject +# +# A structure for .uni file definition +# +class UniFileClassObject(object): + def __init__(self, FileList = None, IsCompatibleMode = False, IncludePathList = None): + self.FileList = FileList + self.File = None + self.IncFileList = FileList + self.UniFileHeader = '' + self.Token = 2 + self.LanguageDef = [] #[ [u'LanguageIdentifier', u'PrintableName'], ... ] + self.OrderedStringList = {} #{ u'LanguageIdentifier' : [StringDefClassObject] } + self.OrderedStringDict = {} #{ u'LanguageIdentifier' : {StringName:(IndexInList)} } + self.OrderedStringListByToken = {} #{ u'LanguageIdentifier' : {Token: StringDefClassObject} } + self.IsCompatibleMode = IsCompatibleMode + if not IncludePathList: + self.IncludePathList = [] + else: + self.IncludePathList = IncludePathList + if len(self.FileList) > 0: + self.LoadUniFiles(FileList) + + # + # Get Language definition + # + def GetLangDef(self, File, Line): + Lang = distutils.util.split_quoted((Line.split(u"//")[0])) + if len(Lang) != 3: + try: + FileIn = codecs.open(File.Path, mode='rb', encoding='utf_16').read() + except UnicodeError, Xstr: + FileIn = codecs.open(File.Path, mode='rb', encoding='utf_16_le').read() + except: + EdkLogger.Error("Unicode File Parser", + ToolError.FILE_OPEN_FAILURE, + "File read failure: %s" % str(Xstr), + ExtraData=File) + LineNo = GetLineNo(FileIn, Line, False) + EdkLogger.Error("Unicode File Parser", + ToolError.PARSER_ERROR, + "Wrong language definition", + ExtraData="""%s\n\t*Correct format is like '#langdef en-US "English"'""" % Line, + File = File, Line = LineNo) + else: + LangName = GetLanguageCode(Lang[1], self.IsCompatibleMode, self.File) + LangPrintName = Lang[2] + + IsLangInDef = False + for Item in self.LanguageDef: + if Item[0] == LangName: + IsLangInDef = True + break + + if not IsLangInDef: + self.LanguageDef.append([LangName, LangPrintName]) + + # + # Add language string + # + self.AddStringToList(u'$LANGUAGE_NAME', LangName, LangName, 0, True, Index=0) + self.AddStringToList(u'$PRINTABLE_LANGUAGE_NAME', LangName, LangPrintName, 1, True, Index=1) + + if not IsLangInDef: + # + # The found STRING tokens will be added into new language string list + # so that the unique STRING identifier is reserved for all languages in the package list. + # + FirstLangName = self.LanguageDef[0][0] + if LangName != FirstLangName: + for Index in range (2, len (self.OrderedStringList[FirstLangName])): + Item = self.OrderedStringList[FirstLangName][Index] + if Item.UseOtherLangDef != '': + OtherLang = Item.UseOtherLangDef + else: + OtherLang = FirstLangName + self.OrderedStringList[LangName].append (StringDefClassObject(Item.StringName, + '', + Item.Referenced, + Item.Token, + OtherLang)) + self.OrderedStringDict[LangName][Item.StringName] = len(self.OrderedStringList[LangName]) - 1 + return True + + # + # Get String name and value + # + def GetStringObject(self, Item): + Language = '' + Value = '' + + Name = Item.split()[1] + # Check the string name is the upper character + if Name != '': + MatchString = re.match('[A-Z0-9_]+', Name, re.UNICODE) + if MatchString == None or MatchString.end(0) != len(Name): + EdkLogger.Error("Unicode File Parser", + ToolError.FORMAT_INVALID, + 'The string token name %s in UNI file %s must be upper case character.' %(Name, self.File)) + LanguageList = Item.split(u'#language ') + for IndexI in range(len(LanguageList)): + if IndexI == 0: + continue + else: + Language = LanguageList[IndexI].split()[0] + #.replace(u'\r\n', u'') + Value = \ + LanguageList[IndexI][LanguageList[IndexI].find(u'\"') + len(u'\"') : LanguageList[IndexI].rfind(u'\"')] + Language = GetLanguageCode(Language, self.IsCompatibleMode, self.File) + self.AddStringToList(Name, Language, Value) + + # + # Get include file list and load them + # + def GetIncludeFile(self, Item, Dir = None): + if Dir: + pass + FileName = Item[Item.find(u'!include ') + len(u'!include ') :Item.find(u' ', len(u'!include '))][1:-1] + self.LoadUniFile(FileName) + + # + # Pre-process before parse .uni file + # + def PreProcess(self, File, IsIncludeFile=False): + if not os.path.exists(File.Path) or not os.path.isfile(File.Path): + EdkLogger.Error("Unicode File Parser", + ToolError.FILE_NOT_FOUND, + ExtraData=File.Path) + + try: + FileIn = codecs.open(File.Path, mode='rb', encoding='utf_16').readlines() + except UnicodeError: + FileIn = codecs.open(File.Path, mode='rb', encoding='utf_16_le').readlines() + except: + EdkLogger.Error("Unicode File Parser", ToolError.FILE_OPEN_FAILURE, ExtraData=File.Path) + + + # + # get the file header + # + Lines = [] + HeaderStart = False + HeaderEnd = False + if not self.UniFileHeader: + FirstGenHeader = True + else: + FirstGenHeader = False + for Line in FileIn: + Line = Line.strip() + if Line == u'': + continue + if Line.startswith(DT.TAB_COMMENT_EDK1_SPLIT) and (Line.find(DT.TAB_HEADER_COMMENT) > -1) \ + and not HeaderEnd and not HeaderStart: + HeaderStart = True + if not Line.startswith(DT.TAB_COMMENT_EDK1_SPLIT) and HeaderStart and not HeaderEnd: + HeaderEnd = True + if Line.startswith(DT.TAB_COMMENT_EDK1_SPLIT) and HeaderStart and not HeaderEnd and FirstGenHeader: + self.UniFileHeader += Line + os.linesep + continue + + # + # Use unique identifier + # + FindFlag = -1 + LineCount = 0 + MultiLineFeedExits = False + # + # 0: initial value + # 1: signle String entry exist + # 2: line feed exist under the some signle String entry + # + StringEntryExistsFlag = 0 + for Line in FileIn: + Line = FileIn[LineCount] + LineCount += 1 + Line = Line.strip() + # + # Ignore comment line and empty line + # + if Line == u'' or Line.startswith(u'//'): + # + # Change the single line String entry flag status + # + if StringEntryExistsFlag == 1: + StringEntryExistsFlag = 2 + # + # If the '#string' line and the '#language' line are not in the same line, + # there should be only one line feed character betwwen them + # + if MultiLineFeedExits: + EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path) + continue + + MultiLineFeedExits = False + # + # Process comment embeded in string define lines + # + FindFlag = Line.find(u'//') + if FindFlag != -1 and Line.find(u'//') < Line.find(u'"'): + Line = Line.replace(Line[FindFlag:], u' ') + if FileIn[LineCount].strip().startswith('#language'): + Line = Line + FileIn[LineCount] + FileIn[LineCount-1] = Line + FileIn[LineCount] = os.linesep + LineCount -= 1 + for Index in xrange (LineCount + 1, len (FileIn) - 1): + if (Index == len(FileIn) -1): + FileIn[Index] = os.linesep + else: + FileIn[Index] = FileIn[Index + 1] + continue + CommIndex = GetCharIndexOutStr(u'/', Line) + if CommIndex > -1: + if (len(Line) - 1) > CommIndex: + if Line[CommIndex+1] == u'/': + Line = Line[:CommIndex].strip() + else: + EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path) + else: + EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path) + + Line = Line.replace(UNICODE_WIDE_CHAR, WIDE_CHAR) + Line = Line.replace(UNICODE_NARROW_CHAR, NARROW_CHAR) + Line = Line.replace(UNICODE_NON_BREAKING_CHAR, NON_BREAKING_CHAR) + + Line = Line.replace(u'\\\\', u'\u0006') + Line = Line.replace(u'\\r\\n', CR + LF) + Line = Line.replace(u'\\n', CR + LF) + Line = Line.replace(u'\\r', CR) + Line = Line.replace(u'\\t', u'\t') + Line = Line.replace(u'''\"''', u'''"''') + Line = Line.replace(u'\t', u' ') + Line = Line.replace(u'\u0006', u'\\') + + IncList = gINCLUDE_PATTERN.findall(Line) + if len(IncList) == 1: + for Dir in [File.Dir] + self.IncludePathList: + IncFile = PathClass(str(IncList[0]), Dir) + self.IncFileList.append(IncFile) + if os.path.isfile(IncFile.Path): + Lines.extend(self.PreProcess(IncFile, True)) + break + else: + EdkLogger.Error("Unicode File Parser", + ToolError.FILE_NOT_FOUND, + Message="Cannot find include file", + ExtraData=str(IncList[0])) + continue + + # + # Between Name entry and Language entry can not contain line feed + # + if Line.startswith(u'#string') and Line.find(u'#language') == -1: + MultiLineFeedExits = True + + if Line.startswith(u'#string') and Line.find(u'#language') > 0 and Line.find(u'"') < 0: + MultiLineFeedExits = True + + # + # Between Language entry and String entry can not contain line feed + # + if Line.startswith(u'#language') and len(Line.split()) == 2: + MultiLineFeedExits = True + + # + # Between two String entry, can not contain line feed + # + if Line.startswith(u'"'): + if StringEntryExistsFlag == 2: + EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, + Message=ST.ERR_UNIPARSE_LINEFEED_UP_EXIST % Line, ExtraData=File.Path) + + StringEntryExistsFlag = 1 + if not Line.endswith('"'): + EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path) + elif Line.startswith(u'#language'): + if StringEntryExistsFlag == 2: + EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, + Message=ST.ERR_UNIPARSE_LINEFEED_UP_EXIST % Line, ExtraData=File.Path) + StringEntryExistsFlag = 0 + else: + StringEntryExistsFlag = 0 + + Lines.append(Line) + + # + # Convert string def format as below + # + # #string MY_STRING_1 + # #language eng + # "My first English string line 1" + # "My first English string line 2" + # #string MY_STRING_1 + # #language spa + # "Mi segunda secuencia 1" + # "Mi segunda secuencia 2" + # + + if not IsIncludeFile and not Lines: + EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \ + Message=ST.ERR_UNIPARSE_NO_SECTION_EXIST, \ + ExtraData=File.Path) + + NewLines = [] + StrName = u'' + ExistStrNameList = [] + for Line in Lines: + if StrName and not StrName.split()[1].startswith(DT.TAB_STR_TOKENCNAME + DT.TAB_UNDERLINE_SPLIT): + EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \ + Message=ST.ERR_UNIPARSE_STRNAME_FORMAT_ERROR % StrName.split()[1], \ + ExtraData=File.Path) + + if StrName and len(StrName.split()[1].split(DT.TAB_UNDERLINE_SPLIT)) == 4: + StringTokenList = StrName.split()[1].split(DT.TAB_UNDERLINE_SPLIT) + if (StringTokenList[3].upper() in [DT.TAB_STR_TOKENPROMPT, DT.TAB_STR_TOKENHELP] and \ + StringTokenList[3] not in [DT.TAB_STR_TOKENPROMPT, DT.TAB_STR_TOKENHELP]) or \ + (StringTokenList[2].upper() == DT.TAB_STR_TOKENERR and StringTokenList[2] != DT.TAB_STR_TOKENERR): + EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \ + Message=ST.ERR_UNIPARSE_STRTOKEN_FORMAT_ERROR % StrName.split()[1], \ + ExtraData=File.Path) + + if Line.count(u'#language') > 1: + EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \ + Message=ST.ERR_UNIPARSE_SEP_LANGENTRY_LINE % Line, \ + ExtraData=File.Path) + + if Line.startswith(u'//'): + continue + elif Line.startswith(u'#langdef'): + if len(Line.split()) == 2: + NewLines.append(Line) + continue + elif len(Line.split()) > 2 and Line.find(u'"') > 0: + NewLines.append(Line[:Line.find(u'"')].strip()) + NewLines.append(Line[Line.find(u'"'):]) + else: + EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path) + elif Line.startswith(u'#string'): + if len(Line.split()) == 2: + StrName = Line + if StrName: + if StrName.split()[1] not in ExistStrNameList: + ExistStrNameList.append(StrName.split()[1].strip()) + elif StrName.split()[1] in [DT.TAB_INF_ABSTRACT, DT.TAB_INF_DESCRIPTION, \ + DT.TAB_INF_BINARY_ABSTRACT, DT.TAB_INF_BINARY_DESCRIPTION, \ + DT.TAB_DEC_PACKAGE_ABSTRACT, DT.TAB_DEC_PACKAGE_DESCRIPTION, \ + DT.TAB_DEC_BINARY_ABSTRACT, DT.TAB_DEC_BINARY_DESCRIPTION]: + EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \ + Message=ST.ERR_UNIPARSE_MULTI_ENTRY_EXIST % StrName.split()[1], \ + ExtraData=File.Path) + continue + elif len(Line.split()) == 4 and Line.find(u'#language') > 0: + if Line[Line.find(u'#language')-1] != ' ' or \ + Line[Line.find(u'#language')+len(u'#language')] != u' ': + EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path) + + if Line.find(u'"') > 0: + EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path) + + StrName = Line.split()[0] + u' ' + Line.split()[1] + if StrName: + if StrName.split()[1] not in ExistStrNameList: + ExistStrNameList.append(StrName.split()[1].strip()) + elif StrName.split()[1] in [DT.TAB_INF_ABSTRACT, DT.TAB_INF_DESCRIPTION, \ + DT.TAB_INF_BINARY_ABSTRACT, DT.TAB_INF_BINARY_DESCRIPTION, \ + DT.TAB_DEC_PACKAGE_ABSTRACT, DT.TAB_DEC_PACKAGE_DESCRIPTION, \ + DT.TAB_DEC_BINARY_ABSTRACT, DT.TAB_DEC_BINARY_DESCRIPTION]: + EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \ + Message=ST.ERR_UNIPARSE_MULTI_ENTRY_EXIST % StrName.split()[1], \ + ExtraData=File.Path) + if IsIncludeFile: + if StrName not in NewLines: + NewLines.append((Line[:Line.find(u'#language')]).strip()) + else: + NewLines.append((Line[:Line.find(u'#language')]).strip()) + NewLines.append((Line[Line.find(u'#language'):]).strip()) + elif len(Line.split()) > 4 and Line.find(u'#language') > 0 and Line.find(u'"') > 0: + if Line[Line.find(u'#language')-1] != u' ' or \ + Line[Line.find(u'#language')+len(u'#language')] != u' ': + EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path) + + if Line[Line.find(u'"')-1] != u' ': + EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path) + + StrName = Line.split()[0] + u' ' + Line.split()[1] + if StrName: + if StrName.split()[1] not in ExistStrNameList: + ExistStrNameList.append(StrName.split()[1].strip()) + elif StrName.split()[1] in [DT.TAB_INF_ABSTRACT, DT.TAB_INF_DESCRIPTION, \ + DT.TAB_INF_BINARY_ABSTRACT, DT.TAB_INF_BINARY_DESCRIPTION, \ + DT.TAB_DEC_PACKAGE_ABSTRACT, DT.TAB_DEC_PACKAGE_DESCRIPTION, \ + DT.TAB_DEC_BINARY_ABSTRACT, DT.TAB_DEC_BINARY_DESCRIPTION]: + EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \ + Message=ST.ERR_UNIPARSE_MULTI_ENTRY_EXIST % StrName.split()[1], \ + ExtraData=File.Path) + if IsIncludeFile: + if StrName not in NewLines: + NewLines.append((Line[:Line.find(u'#language')]).strip()) + else: + NewLines.append((Line[:Line.find(u'#language')]).strip()) + NewLines.append((Line[Line.find(u'#language'):Line.find(u'"')]).strip()) + NewLines.append((Line[Line.find(u'"'):]).strip()) + else: + EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path) + elif Line.startswith(u'#language'): + if len(Line.split()) == 2: + if IsIncludeFile: + if StrName not in NewLines: + NewLines.append(StrName) + else: + NewLines.append(StrName) + NewLines.append(Line) + elif len(Line.split()) > 2 and Line.find(u'"') > 0: + if IsIncludeFile: + if StrName not in NewLines: + NewLines.append(StrName) + else: + NewLines.append(StrName) + NewLines.append((Line[:Line.find(u'"')]).strip()) + NewLines.append((Line[Line.find(u'"'):]).strip()) + else: + EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path) + elif Line.startswith(u'"'): + if u'#string' in Line or u'#language' in Line: + EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path) + NewLines.append(Line) + else: + print Line + EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path) + + if StrName and not StrName.split()[1].startswith(u'STR_'): + EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \ + Message=ST.ERR_UNIPARSE_STRNAME_FORMAT_ERROR % StrName.split()[1], \ + ExtraData=File.Path) + + if StrName and not NewLines: + EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \ + Message=ST.ERR_UNI_MISS_LANGENTRY % StrName, \ + ExtraData=File.Path) + + # + # Check Abstract, Description, BinaryAbstract and BinaryDescription order, + # should be Abstract, Description, BinaryAbstract, BinaryDesctiption + AbstractPosition = -1 + DescriptionPosition = -1 + BinaryAbstractPosition = -1 + BinaryDescriptionPosition = -1 + for StrName in ExistStrNameList: + if DT.TAB_HEADER_ABSTRACT.upper() in StrName: + if 'BINARY' in StrName: + BinaryAbstractPosition = ExistStrNameList.index(StrName) + else: + AbstractPosition = ExistStrNameList.index(StrName) + if DT.TAB_HEADER_DESCRIPTION.upper() in StrName: + if 'BINARY' in StrName: + BinaryDescriptionPosition = ExistStrNameList.index(StrName) + else: + DescriptionPosition = ExistStrNameList.index(StrName) + + OrderList = sorted([AbstractPosition, DescriptionPosition]) + BinaryOrderList = sorted([BinaryAbstractPosition, BinaryDescriptionPosition]) + Min = OrderList[0] + Max = OrderList[1] + BinaryMin = BinaryOrderList[0] + BinaryMax = BinaryOrderList[1] + if BinaryDescriptionPosition > -1: + if not(BinaryDescriptionPosition == BinaryMax and BinaryAbstractPosition == BinaryMin and \ + BinaryMax > Max): + EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \ + Message=ST.ERR_UNIPARSE_ENTRY_ORDER_WRONG, \ + ExtraData=File.Path) + elif BinaryAbstractPosition > -1: + if not(BinaryAbstractPosition > Max): + EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \ + Message=ST.ERR_UNIPARSE_ENTRY_ORDER_WRONG, \ + ExtraData=File.Path) + + if DescriptionPosition > -1: + if not(DescriptionPosition == Max and AbstractPosition == Min and \ + DescriptionPosition > AbstractPosition): + EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \ + Message=ST.ERR_UNIPARSE_ENTRY_ORDER_WRONG, \ + ExtraData=File.Path) + + if not self.UniFileHeader: + EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, + Message = ST.ERR_NO_SOURCE_HEADER, + ExtraData=File.Path) + + return NewLines + + # + # Load a .uni file + # + def LoadUniFile(self, File = None): + if File == None: + EdkLogger.Error("Unicode File Parser", + ToolError.PARSER_ERROR, + Message='No unicode file is given', + ExtraData=File.Path) + + self.File = File + + # + # Process special char in file + # + Lines = self.PreProcess(File) + + # + # Get Unicode Information + # + for IndexI in range(len(Lines)): + Line = Lines[IndexI] + if (IndexI + 1) < len(Lines): + SecondLine = Lines[IndexI + 1] + if (IndexI + 2) < len(Lines): + ThirdLine = Lines[IndexI + 2] + + # + # Get Language def information + # + if Line.find(u'#langdef ') >= 0: + self.GetLangDef(File, Line + u' ' + SecondLine) + continue + + Name = '' + Language = '' + Value = '' + CombineToken = False + # + # Get string def information format as below + # + # #string MY_STRING_1 + # #language eng + # "My first English string line 1" + # "My first English string line 2" + # #string MY_STRING_1 + # #language spa + # "Mi segunda secuencia 1" + # "Mi segunda secuencia 2" + # + if Line.find(u'#string ') >= 0 and Line.find(u'#language ') < 0 and \ + SecondLine.find(u'#string ') < 0 and SecondLine.find(u'#language ') >= 0 and \ + ThirdLine.find(u'#string ') < 0 and ThirdLine.find(u'#language ') < 0: + if Line.find('"') > 0 or SecondLine.find('"') > 0: + EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, + Message=ST.ERR_UNIPARSE_DBLQUOTE_UNMATCHED, + ExtraData=File.Path) + + Name = Line[Line.find(u'#string ') + len(u'#string ') : ].strip(' ') + Language = SecondLine[SecondLine.find(u'#language ') + len(u'#language ') : ].strip(' ') + for IndexJ in range(IndexI + 2, len(Lines)): + if Lines[IndexJ].find(u'#string ') < 0 and Lines[IndexJ].find(u'#language ') < 0 and \ + Lines[IndexJ].strip().startswith(u'"') and Lines[IndexJ].strip().endswith(u'"'): + if Lines[IndexJ][-2] == ' ': + CombineToken = True + if CombineToken: + if Lines[IndexJ].strip()[1:-1].strip(): + Value = Value + Lines[IndexJ].strip()[1:-1].rstrip() + ' ' + else: + Value = Value + Lines[IndexJ].strip()[1:-1] + CombineToken = False + else: + Value = Value + Lines[IndexJ].strip()[1:-1] + os.linesep + else: + IndexI = IndexJ + break + if Value.endswith(os.linesep): + Value = Value[: Value.rfind(os.linesep)] + Language = GetLanguageCode(Language, self.IsCompatibleMode, self.File) + self.AddStringToList(Name, Language, Value) + continue + + # + # Load multiple .uni files + # + def LoadUniFiles(self, FileList): + if len(FileList) > 0: + for File in FileList: + FilePath = File.Path.strip() + if FilePath.endswith('.uni') or FilePath.endswith('.UNI') or FilePath.endswith('.Uni'): + self.LoadUniFile(File) + + # + # Add a string to list + # + def AddStringToList(self, Name, Language, Value, Token = 0, Referenced = False, UseOtherLangDef = '', Index = -1): + for LangNameItem in self.LanguageDef: + if Language == LangNameItem[0]: + break + + if Language not in self.OrderedStringList: + self.OrderedStringList[Language] = [] + self.OrderedStringDict[Language] = {} + + IsAdded = True + if Name in self.OrderedStringDict[Language]: + IsAdded = False + if Value != None: + ItemIndexInList = self.OrderedStringDict[Language][Name] + Item = self.OrderedStringList[Language][ItemIndexInList] + Item.UpdateValue(Value) + Item.UseOtherLangDef = '' + + if IsAdded: + Token = len(self.OrderedStringList[Language]) + if Index == -1: + self.OrderedStringList[Language].append(StringDefClassObject(Name, + Value, + Referenced, + Token, + UseOtherLangDef)) + self.OrderedStringDict[Language][Name] = Token + for LangName in self.LanguageDef: + # + # New STRING token will be added into all language string lists. + # so that the unique STRING identifier is reserved for all languages in the package list. + # + if LangName[0] != Language: + if UseOtherLangDef != '': + OtherLangDef = UseOtherLangDef + else: + OtherLangDef = Language + self.OrderedStringList[LangName[0]].append(StringDefClassObject(Name, + '', + Referenced, + Token, + OtherLangDef)) + self.OrderedStringDict[LangName[0]][Name] = len(self.OrderedStringList[LangName[0]]) - 1 + else: + self.OrderedStringList[Language].insert(Index, StringDefClassObject(Name, + Value, + Referenced, + Token, + UseOtherLangDef)) + self.OrderedStringDict[Language][Name] = Index + + # + # Set the string as referenced + # + def SetStringReferenced(self, Name): + # + # String stoken are added in the same order in all language string lists. + # So, only update the status of string stoken in first language string list. + # + Lang = self.LanguageDef[0][0] + if Name in self.OrderedStringDict[Lang]: + ItemIndexInList = self.OrderedStringDict[Lang][Name] + Item = self.OrderedStringList[Lang][ItemIndexInList] + Item.Referenced = True + + # + # Search the string in language definition by Name + # + def FindStringValue(self, Name, Lang): + if Name in self.OrderedStringDict[Lang]: + ItemIndexInList = self.OrderedStringDict[Lang][Name] + return self.OrderedStringList[Lang][ItemIndexInList] + + return None + + # + # Search the string in language definition by Token + # + def FindByToken(self, Token, Lang): + for Item in self.OrderedStringList[Lang]: + if Item.Token == Token: + return Item + + return None + + # + # Re-order strings and re-generate tokens + # + def ReToken(self): + if len(self.LanguageDef) == 0: + return None + # + # Retoken all language strings according to the status of string stoken in the first language string. + # + FirstLangName = self.LanguageDef[0][0] + + # Convert the OrderedStringList to be OrderedStringListByToken in order to faciliate future search by token + for LangNameItem in self.LanguageDef: + self.OrderedStringListByToken[LangNameItem[0]] = {} + + # + # Use small token for all referred string stoken. + # + RefToken = 0 + for Index in range (0, len (self.OrderedStringList[FirstLangName])): + FirstLangItem = self.OrderedStringList[FirstLangName][Index] + if FirstLangItem.Referenced == True: + for LangNameItem in self.LanguageDef: + LangName = LangNameItem[0] + OtherLangItem = self.OrderedStringList[LangName][Index] + OtherLangItem.Referenced = True + OtherLangItem.Token = RefToken + self.OrderedStringListByToken[LangName][OtherLangItem.Token] = OtherLangItem + RefToken = RefToken + 1 + + # + # Use big token for all unreferred string stoken. + # + UnRefToken = 0 + for Index in range (0, len (self.OrderedStringList[FirstLangName])): + FirstLangItem = self.OrderedStringList[FirstLangName][Index] + if FirstLangItem.Referenced == False: + for LangNameItem in self.LanguageDef: + LangName = LangNameItem[0] + OtherLangItem = self.OrderedStringList[LangName][Index] + OtherLangItem.Token = RefToken + UnRefToken + self.OrderedStringListByToken[LangName][OtherLangItem.Token] = OtherLangItem + UnRefToken = UnRefToken + 1 + + # + # Show the instance itself + # + def ShowMe(self): + print self.LanguageDef + #print self.OrderedStringList + for Item in self.OrderedStringList: + print Item + for Member in self.OrderedStringList[Item]: + print str(Member) + + # + # Read content from '!include' UNI file + # + def ReadIncludeUNIfile(self, FilaPath): + if self.File: + pass + + if not os.path.exists(FilaPath) or not os.path.isfile(FilaPath): + EdkLogger.Error("Unicode File Parser", + ToolError.FILE_NOT_FOUND, + ExtraData=FilaPath) + try: + FileIn = codecs.open(FilaPath, mode='rb', encoding='utf_16').readlines() + except UnicodeError: + FileIn = codecs.open(FilaPath, mode='rb', encoding='utf_16_le').readlines() + except: + EdkLogger.Error("Unicode File Parser", ToolError.FILE_OPEN_FAILURE, ExtraData=FilaPath) + return FileIn + diff --git a/BaseTools/Source/Python/UPT/Library/Xml/XmlRoutines.py b/BaseTools/Source/Python/UPT/Library/Xml/XmlRoutines.py index 7029e59889..d7614b8849 100644 --- a/BaseTools/Source/Python/UPT/Library/Xml/XmlRoutines.py +++ b/BaseTools/Source/Python/UPT/Library/Xml/XmlRoutines.py @@ -2,7 +2,7 @@ # This is an XML API that uses a syntax similar to XPath, but it is written in # standard python so that no extra python packages are required to use it. # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -22,6 +22,7 @@ XmlRoutines # import xml.dom.minidom import re +import codecs from Logger.ToolError import PARSER_ERROR import Logger.Log as Logger @@ -219,7 +220,7 @@ def XmlNodeName(Dom): # def XmlParseFile(FileName): try: - XmlFile = open(FileName) + XmlFile = codecs.open(FileName, 'rb') Dom = xml.dom.minidom.parse(XmlFile) XmlFile.close() return Dom diff --git a/BaseTools/Source/Python/UPT/Logger/StringTable.py b/BaseTools/Source/Python/UPT/Logger/StringTable.py index 6275a3ef58..5b6973c944 100644 --- a/BaseTools/Source/Python/UPT/Logger/StringTable.py +++ b/BaseTools/Source/Python/UPT/Logger/StringTable.py @@ -1,7 +1,7 @@ ## @file # This file is used to define strings used in the UPT tool # -# Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -42,9 +42,9 @@ MSG_USAGE_STRING = _("\n" MSG_VERSION_NUMBER = _("1.0") MSG_VERSION = _("Intel(r) UEFI Packaging Tool (Intel(r) UEFIPT) - Revision " + \ MSG_VERSION_NUMBER) -MSG_COPYRIGHT = _("Copyright (c) 2011 - 2013 Intel Corporation All Rights Reserved.") +MSG_COPYRIGHT = _("Copyright (c) 2011 Intel Corporation All Rights Reserved.") MSG_VERSION_COPYRIGHT = _("\n %s\n %s" % (MSG_VERSION, MSG_COPYRIGHT)) -MSG_USAGE = _("%s [options]\n%s" % ("upt.exe", MSG_VERSION_COPYRIGHT)) +MSG_USAGE = _("%s [options]\n%s" % ("UPT", MSG_VERSION_COPYRIGHT)) MSG_DESCRIPTION = _("The Intel(r) UEFIUPT is used to create, " + \ "install or remove a UEFI Distribution Package.") @@ -64,21 +64,23 @@ ERR_INF_PARSER_BUILD_OPTION_FORMAT_INVALID = \ _("Build Option format incorrect.") ERR_INF_PARSER_BINARY_ITEM_FORMAT_INVALID = _( "The format of binary %s item is incorrect. " - "It should contain at least 2 elements.") + "It should contain at least %d elements.") ERR_INF_PARSER_BINARY_ITEM_FORMAT_INVALID_MAX = _( "The format of binary %s item is invalid, " - "it should contain not more than %d elements.") + "it should contain not more than %d elements.") ERR_INF_PARSER_BINARY_ITEM_INVALID_FILETYPE = _( "The Binary FileType is incorrect. It should in %s") ERR_INF_PARSER_BINARY_ITEM_FILE_NOT_EXIST = _( "The Binary File: %s not exist.") +ERR_INF_PARSER_BINARY_ITEM_FILENAME_NOT_EXIST = _( + "The Binary File Name item not exist") ERR_INF_PARSER_BINARY_VER_TYPE = _( "Only this type is allowed: \"%s\".") ERR_INF_PARSER_MULTI_DEFINE_SECTION = \ _("Multiple define sections found. " "It must be corrected before continuing.") ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND = \ - _("More then 1 %s is defined in DEFINES section. " + _("More than 1 %s is defined in DEFINES section. " "It must be corrected before continuing.") ERR_INF_PARSER_DEFINE_NAME_INVALID = \ _("Incorrect name format for : %s") @@ -88,8 +90,8 @@ ERR_INF_PARSER_DEFINE_MODULETYPE_INVALID = _("Incorrect MODULE_TYPE: %s") ERR_INF_PARSER_DEFINE_FROMAT_INVALID = _("Incorrect format: %s") ERR_INF_PARSER_FILE_NOT_EXIST = _("This file does not exist: %s") ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID = \ - _("The file does not exist or has an incorrect file name or not in " - "sub-directories of the directory containing the INF file: %s. " + _("The file does not exist or not in sub-directories " + "or has an incorrect file name of the directory containing the INF or DEC file: %s. " "It must be corrected before continuing") ERR_INF_PARSER_DEFINE_SHADOW_INVALID = \ _("The SHADOW keyword is only valid for" @@ -98,6 +100,8 @@ ERR_INF_PARSER_DEFINE_SECTION_HEADER_INVALID = \ _("The format of the section header is incorrect") ERR_INF_PARSER_DEPEX_SECTION_INVALID = \ _("A module can't have a Depex section when its module type is %s") +ERR_INF_PARSER_DEPEX_SECTION_INVALID_FOR_BASE_LIBRARY_CLASS = \ + _("A base type library class can't have a Depex section with module type not defined.") ERR_INF_PARSER_DEPEX_SECTION_INVALID_FOR_LIBRARY_CLASS = \ _("A library class can't have a Depex section when its supported module type list is not defined.") ERR_INF_PARSER_DEPEX_SECTION_INVALID_FOR_DRIVER = \ @@ -212,6 +216,8 @@ ERR_INF_NO_PKG_DEPENDENCY_INFO = _("There are no packages defined that use the A # # Item duplicate # +ERR_INF_PARSER_ITEM_DUPLICATE_IN_DEC = \ +_('"%s" is redefined in its dependent DEC files') ERR_INF_PARSER_ITEM_DUPLICATE = _("%s define duplicated! " "It must be corrected before continuing.") ERR_INF_PARSER_ITEM_DUPLICATE_COMMON = _("%s define duplicated! Item listed" @@ -246,7 +252,7 @@ ERR_BO_CONTATIN_ASBUILD_AND_COMMON = _("A binary INF file should contain either ERR_ASBUILD_PCD_SECTION_TYPE = _("The AsBuilt INF file contains a PCD section type that is not permitted: %s.") ERR_ASBUILD_PATCHPCD_FORMAT_INVALID = _("The AsBuilt PatchPcd entry must contain 3 elements: PcdName|Value|Offset") -ERR_ASBUILD_PCDEX_FORMAT_INVALID = _("The AsBuilt PcdEx entry must contain 2 elements: PcdName|Value") +ERR_ASBUILD_PCDEX_FORMAT_INVALID = _("The AsBuilt PcdEx entry must contain one element: PcdName") ERR_ASBUILD_PCD_VALUE_INVALID = \ _("The AsBuilt PCD value %s is incorrect or not align with it's datum type %s. " "It must be corrected before continuing.") @@ -349,7 +355,13 @@ MSG_NEW_FILE_NAME = _( MSG_RELATIVE_PATH_ONLY = _("Please specify a relative path, full path is not allowed: %s") MSG_NEW_PKG_PATH = _( "Select package location. To quit with no input, press [Enter].") - +MSG_CHECK_DP_FOR_REPLACE = _("Verifying the dependency rule for replacement of distributions:\n %s replaces %s") +MSG_CHECK_DP_FOR_INSTALL = _("Verifying the dependency rule for installation of distribution:\n %s") +MSG_REPLACE_ALREADY_INSTALLED_DP = _("Distribution with the same GUID/Version is already installed, " + "replace would result in two instances, which is not allowed") +MSG_RECOVER_START = _('An error was detected, recovery started ...') +MSG_RECOVER_DONE = _('Recovery completed.') +MSG_RECOVER_FAIL = _('Recovery failed.') # # Error related strings. # @@ -378,6 +390,8 @@ ERR_PACKAGE_NOT_MATCH_DEPENDENCY = _( "This distribution package does not meet the dependency requirements") ERR_UNKNOWN_FATAL_INSTALL_ERR = \ _("Unknown unrecoverable error when installing: %s") +ERR_UNKNOWN_FATAL_REPLACE_ERR = \ +_("Unknown unrecoverable error during replacement of distributions: %s replaces %s") ERR_OPTION_NOT_FOUND = _("Options not found") ERR_INVALID_PACKAGE_NAME = _("Incorrect package name: %s. ") ERR_INVALID_PACKAGE_PATH = \ @@ -393,6 +407,7 @@ ERR_PACKAGE_NOT_INSTALLED = _( ERR_DISTRIBUTION_NOT_INSTALLED = _( "The distribution package is not installed.") ERR_UNKNOWN_FATAL_REMOVING_ERR = _("Unknown error when removing package") +ERR_UNKNOWN_FATAL_INVENTORYWS_ERR = _("Unknown error when inventorying WORKSPACE") ERR_NOT_CONFIGURE_WORKSPACE_ENV = _( "The WORKSPACE environment variable must be configured.") ERR_NO_TEMPLATE_FILE = _("This package information data file is not found: %s") @@ -400,6 +415,10 @@ ERR_DEBUG_LEVEL = _( "Not supported debug level. Use default level instead.") ERR_REQUIRE_T_OPTION = _( "Option -t is required during distribution creation.") +ERR_REQUIRE_O_OPTION = _( + "Option -o is required during distribution replacement.") +ERR_REQUIRE_U_OPTION = _( + "Option -u is required during distribution replacement.") ERR_REQUIRE_I_C_R_OPTION = _( "Options -i, -c and -r are mutually exclusive.") ERR_I_C_EXCLUSIVE = \ @@ -408,6 +427,11 @@ ERR_I_R_EXCLUSIVE = \ _("Option -i and -r are mutually exclusive.") ERR_C_R_EXCLUSIVE = \ _("Option -c and -r are mutually exclusive.") +ERR_U_ICR_EXCLUSIVE = \ +_("Option -u and -c/-i/-r are mutually exclusive.") + +ERR_L_OA_EXCLUSIVE = \ +_("Option -l and -c/-i/-r/-u are mutually exclusive.") ERR_FAILED_LOAD = _("Failed to load %s\n\t%s") ERR_PLACEHOLDER_DIFFERENT_REPEAT = _( @@ -551,32 +575,66 @@ ERR_INSTALL_FILE_DEC_FILE_ERROR = _("Could not obtain the TokenSpaceGuidCName an ERR_NOT_SUPPORTED_SA_MODULE = _("Stand-alone module distribution does not allow EDK 1 INF") ERR_INSTALL_DIST_NOT_FOUND = \ _("Distribution file to be installed is not found in current working directory or workspace: %s") +ERR_REPLACE_DIST_NOT_FOUND = \ +_("Distribution file for replace function was not found in the current working directory or workspace: %s") +ERR_DIST_FILENAME_ONLY_FOR_REPLACE_ORIG = \ +_("Only a distribution file name without a path is allowed for " + "the distribution to be replaced during replace. Current given: '%s'.") +ERR_UNIPARSE_DBLQUOTE_UNMATCHED = \ +_("Only Language entry can contain a couple of matched quote in one line") +ERR_UNIPARSE_NO_SECTION_EXIST = _("No PakcageDef or ModuleDef section exists in the UNI file.") +ERR_UNIPARSE_STRNAME_FORMAT_ERROR = _("The String Token Name %s must start with \"STR_\"") +ERR_UNIPARSE_SEP_LANGENTRY_LINE = _("Each should be in a separate line :%s.") +ERR_UNIPARSE_MULTI_ENTRY_EXIST = \ +_("There are same entries : %s in the UNI file, every kind of entry should be only one.") +ERR_UNIPARSE_ENTRY_ORDER_WRONG = \ +_("The string entry order in UNI file should be , , \ +, .") +ERR_UNIPARSE_STRTOKEN_FORMAT_ERROR = _("The String Token Type %s must be one of the '_PROMPT', '_HELP' and '_ERR_'.") +ERR_UNIPARSE_LINEFEED_UNDER_EXIST = _("Line feed should not exist under this line: %s.") +ERR_UNIPARSE_LINEFEED_UP_EXIST = _("Line feed should not exist up this line: %s.") +ERR_UNI_MISS_LANGENTRY = _("Language entry missed in this Entry, %s.") ERR_BINARY_HEADER_ORDER = _("Binary header must follow the file header.") ERR_NO_SOURCE_HEADER = _("File header statement \"## @file\" must exist at the first place.") +ERR_UNI_FILE_SUFFIX_WRONG = _("The UNI file must have an extension of '.uni', '.UNI' or '.Uni'") +ERR_UNI_FILE_NAME_INVALID = _("The use of '..', '../' and './' in the UNI file is prohibited.") +ERR_UNI_SUBGUID_VALUE_DEFINE_DEC_NOT_FOUND = _("There are no DEC file to define the GUID value for \ +this GUID CName: '%s'.") # # Expression error message # ERR_EXPR_RIGHT_PAREN = \ -_('Expected ")" in feature flag expression [%s]. Found: [%s].') +_('Missing ")" in expression "%s".') ERR_EXPR_FACTOR = \ -_('Expected HEX, integer, macro, quoted string or PcdName in ' - 'feature flag expression [%s]. Found: [%s].') +_('"%s" is expected to be HEX, integer, macro, quoted string or PcdName in ' + 'expression "%s".') ERR_EXPR_STRING_ITEM = \ -_('Expected quoted string, macro name or PcdName in feature flag ' - 'expression [%s]. Found: [%s].') +_('"%s" is expected to be HEX, integer, macro, quoted string or PcdName in ' + 'expression [%s].') ERR_EXPR_EQUALITY = \ -_('Expected ==, EQ, != or NE in feature flag expression [%s]. Found: [%s].') +_('"%s" is expected to be ==, EQ, != or NE in expression "%s".') ERR_EXPR_BOOLEAN = \ -_('The rest of string [%s] in feature flag ' - 'expression [%s] cannot be evaluated.') +_('The string "%s" in expression "%s" can not be recognized as a part of the logical expression.') ERR_EXPR_EMPTY = _('Boolean value cannot be empty.') +ERR_EXPRESS_EMPTY = _('Expression can not be empty.') ERR_EXPR_LOGICAL = \ -_('The following cannot be evaluated as a logical expression: [%s].') -ERR_EXPR_OR = _('The expression must be encapsulated in open "(" and close ")" ' +_('The following is not a valid logical expression: "%s".') +ERR_EXPR_OR = _('The expression: "%s" must be encapsulated in open "(" and close ")" ' 'parenthesis when using | or ||.') +ERR_EXPR_RANGE = \ +_('The following is not a valid range expression: "%s".') +ERR_EXPR_RANGE_FACTOR = \ +_('"%s" is expected to be HEX, integer in valid range expression "%s".') +ERR_EXPR_RANGE_DOUBLE_PAREN_NESTED = \ +_('Double parentheses nested is not allowed in valid range expression: "%s".') +ERR_EXPR_RANGE_EMPTY = _('Valid range can not be empty.') +ERR_EXPR_LIST_EMPTY = _('Valid list can not be empty.') +ERR_PAREN_NOT_USED = _('Parenthesis must be used on both sides of "OR", "AND" in valid range : %s.') +ERR_EXPR_LIST = \ +_('The following is not a valid list expression: "%s".') + -# # DEC parser error message # ERR_DECPARSE_STATEMENT_EMPTY = \ @@ -632,6 +690,8 @@ ERR_DECPARSE_PCD_VOID = \ _("Incorrect value [%s] of type [%s]. Value must be printable and in the " "form of{...} for array, or ""..."" for string, or L""...""" "for unicode string.") +ERR_DECPARSE_PCD_VALUE_EMPTY = \ +_("Pcd value can not be empty.") ERR_DECPARSE_PCD_BOOL = \ _("Invalid value [%s] of type [%s]; must be expression, TRUE, FALSE, 0 or 1.") ERR_DECPARSE_PCD_INT = _("Incorrect value [%s] of type [%s]."\ @@ -657,6 +717,7 @@ _("No GUID value specified, must be = .") ERR_DECPARSE_CGUID_GUIDFORMAT = \ _("Incorrect GUID value format, must be .") +ERR_DECPARSE_CGUID_NOT_FOUND = _("Unable to find the GUID value of this GUID CName : '%s'.") ERR_DECPARSE_FILEOPEN = _("Unable to open: [%s].") ERR_DECPARSE_SECTION_EMPTY = _("Empty sections are not allowed.") ERR_DECPARSE_SECTION_UE = _("Incorrect UserExtentions format. " @@ -697,7 +758,13 @@ ERR_DECPARSE_REDEFINE = _( ERR_DECPARSE_MACRO_RESOLVE = _("Macro %s in %s cannot be resolved.") ERR_DECPARSE_UE_DUPLICATE = \ _("Duplicated UserExtensions header found.") - +ERR_DECPARSE_PCDERRORMSG_MISS_VALUE_SPLIT = \ + _("Missing '|' between Pcd's error code and Pcd's error message.") +ERR_DECPARSE_PCD_MISS_ERRORMSG = \ + _("Missing Pcd's error message.") +ERR_DECPARSE_PCD_UNMATCHED_ERRORCODE = \ + _("There is no error message matched with this Pcd error code : %s in both DEC and UNI file.") +ERR_DECPARSE_PCD_NODEFINED = _("The PCD : %s used in the Expression is undefined.") # # Used to print the current line content which cause error raise. # Be attached to the end of every error message above. @@ -718,8 +785,11 @@ WRN_DIST_PKG_INSTALLED = _("This distribution package has been installed") WRN_DIST_NOT_FOUND = _( "Distribution is not found at location %s") WRN_MULTI_PCD_RANGES = _( - "A PCD can only have one each of @ValidRange, @ValidList, " - "and @Expression comment") + "A PCD can only have one type of @ValidRange, @ValidList, and @Expression comment") +WRN_MULTI_PCD_VALIDVALUE = _( + "A PCD can only have one of @ValidList comment") +WRN_MULTI_PCD_PROMPT = _( + "A PCD can only have one of @Prompt comment") WRN_MISSING_USAGE = _("Missing usage") WRN_INVALID_GUID_TYPE = _("This is and incorrect Guid type: %s") WRN_MISSING_GUID_TYPE = _("Missing Guid Type") @@ -742,6 +812,8 @@ WARN_SPECIAL_SECTION_LOCATION_WRONG = _("Warning. A special section should be " "at the end of a file or at the end of a section.") WARN_INSTALLED_PACKAGE_NOT_FOUND = \ _("File not found. The DEC file for a package cannot be found in GUID/Version/Install path: %s %s %s") +WARN_CUSTOMPATH_OVERRIDE_USEGUIDEDPATH = \ + _("option selection of --custom-path will override the option --use-guided-paths") # # Help related strings. @@ -766,11 +838,19 @@ HLP_SPECIFY_DEC_NAME_CREATE = _( "Specify dec file names to create package") HLP_SPECIFY_INF_NAME_CREATE = _( "Specify inf file names to create package") +HLP_LIST_DIST_INSTALLED = _( + "List the UEFI Distribution Packages that have been installed") HLP_NO_SUPPORT_GUI = _( "Starting the tool in graphical mode is not supported in this version") HLP_DISABLE_PROMPT = _( - "Disable all user prompts") + "Disable user prompts for removing modified files. Valid only when -r is present") HLP_CUSTOM_PATH_PROMPT = _( "Enable user prompting for alternate installation directories") HLP_SKIP_LOCK_CHECK = _( "Skip the check for multiple instances") +HLP_SPECIFY_PACKAGE_NAME_REPLACE = _( + "Specify the UEFI Distribution Package file name to replace the existing file name") +HLP_SPECIFY_PACKAGE_NAME_TO_BE_REPLACED = _( + "Specify the UEFI Distribution Package file name to be replaced") +HLP_USE_GUIDED_PATHS = _( + "Install packages to the following directory path by default: __") diff --git a/BaseTools/Source/Python/UPT/MkPkg.py b/BaseTools/Source/Python/UPT/MkPkg.py index b8b78e4515..2eb84588bd 100644 --- a/BaseTools/Source/Python/UPT/MkPkg.py +++ b/BaseTools/Source/Python/UPT/MkPkg.py @@ -1,7 +1,7 @@ ## @file # Install distribution package. # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -45,7 +45,6 @@ import Logger.Log as Logger from Xml.XmlParser import DistributionPackageXml from Xml.IniToXml import IniToXml -from Library.Misc import CheckEnvVariable from Library import GlobalData from Library.ParserValidate import IsValidPath @@ -78,7 +77,6 @@ def Main(Options = None): try: DataBase = GlobalData.gDB ContentFileClosed = True - CheckEnvVariable() WorkspaceDir = GlobalData.gWORKSPACE # diff --git a/BaseTools/Source/Python/UPT/Object/POM/CommonObject.py b/BaseTools/Source/Python/UPT/Object/POM/CommonObject.py index 1418a2f4bd..ec8a8d44ce 100644 --- a/BaseTools/Source/Python/UPT/Object/POM/CommonObject.py +++ b/BaseTools/Source/Python/UPT/Object/POM/CommonObject.py @@ -1,7 +1,7 @@ ## @file # This file is used to define common items of class object # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -14,7 +14,7 @@ ''' Common Object ''' -from Library.DataType import LANGUAGE_EN_US +from Library.DataType import TAB_LANGUAGE_EN_US ## HelpTextObject # @@ -44,6 +44,20 @@ class HelpTextListObject(object): def GetHelpTextList(self): return self.HelpTextList +## PromptListObject +# +# @param object: Inherited from object class +# +class PromptListObject(object): + def __init__(self): + self.PromptList = [] + + def SetPromptList(self, PromptList): + self.PromptList = PromptList + + def GetPromptList(self): + return self.PromptList + ## CommonPropertiesObject # # This class defined common attribution used in Module/Platform/Package files @@ -60,6 +74,7 @@ class CommonPropertiesObject(HelpTextObject, HelpTextListObject): self.Usage = [] self.FeatureFlag = '' self.SupArchList = [] + self.GuidValue = '' HelpTextObject.__init__(self) HelpTextListObject.__init__(self) @@ -80,6 +95,12 @@ class CommonPropertiesObject(HelpTextObject, HelpTextListObject): def GetSupArchList(self): return self.SupArchList + + def SetGuidValue(self, GuidValue): + self.GuidValue = GuidValue + + def GetGuidValue(self): + return self.GuidValue ## CommonHeaderObject # @@ -89,35 +110,96 @@ class CommonPropertiesObject(HelpTextObject, HelpTextListObject): # class CommonHeaderObject(object): def __init__(self): - self.Abstract = '' - self.Description = '' - self.Copyright = '' - self.License = '' + self.AbstractList = [] + self.DescriptionList = [] + self.CopyrightList = [] + self.LicenseList = [] def SetAbstract(self, Abstract): - self.Abstract = Abstract + if isinstance(Abstract, list): + self.AbstractList = Abstract + else: + self.AbstractList.append(Abstract) def GetAbstract(self): - return self.Abstract + return self.AbstractList def SetDescription(self, Description): - self.Description = Description + if isinstance(Description, list): + self.DescriptionList = Description + else: + self.DescriptionList.append(Description) def GetDescription(self): - return self.Description + return self.DescriptionList def SetCopyright(self, Copyright): - self.Copyright = Copyright + if isinstance(Copyright, list): + self.CopyrightList = Copyright + else: + self.CopyrightList.append(Copyright) def GetCopyright(self): - return self.Copyright + return self.CopyrightList def SetLicense(self, License): - self.License = License + if isinstance(License, list): + self.LicenseList = License + else: + self.LicenseList.append(License) def GetLicense(self): - return self.License + return self.LicenseList +## BinaryHeaderObject +# +# This class defined Binary header items used in Module/Platform/Package files +# +# @param object: Inherited from object class +# +class BinaryHeaderObject(object): + def __init__(self): + self.BinaryHeaderAbstractList = [] + self.BinaryHeaderDescriptionList = [] + self.BinaryHeaderCopyrightList = [] + self.BinaryHeaderLicenseList = [] + + def SetBinaryHeaderAbstract(self, Abstract): + if isinstance(Abstract, list) and Abstract: + self.BinaryHeaderAbstractList = Abstract + elif isinstance(Abstract, tuple) and Abstract[1]: + self.BinaryHeaderAbstractList.append(Abstract) + + def GetBinaryHeaderAbstract(self): + return self.BinaryHeaderAbstractList + + def SetBinaryHeaderDescription(self, Description): + if isinstance(Description, list) and Description: + self.BinaryHeaderDescriptionList = Description + elif isinstance(Description, tuple) and Description[1]: + self.BinaryHeaderDescriptionList.append(Description) + + def GetBinaryHeaderDescription(self): + return self.BinaryHeaderDescriptionList + + def SetBinaryHeaderCopyright(self, Copyright): + if isinstance(Copyright, list) and Copyright: + self.BinaryHeaderCopyrightList = Copyright + elif isinstance(Copyright, tuple) and Copyright[1]: + self.BinaryHeaderCopyrightList.append(Copyright) + + def GetBinaryHeaderCopyright(self): + return self.BinaryHeaderCopyrightList + + def SetBinaryHeaderLicense(self, License): + if isinstance(License, list) and License: + self.BinaryHeaderLicenseList = License + elif isinstance(License, tuple) and License[1]: + self.BinaryHeaderLicenseList.append(License) + + def GetBinaryHeaderLicense(self): + return self.BinaryHeaderLicenseList + ## ClonedRecordObject # # This class defined ClonedRecord items used in Module/Platform/Package files @@ -177,7 +259,7 @@ class ClonedRecordObject(object): # class TextObject(object): def __init__(self): - self.Lang = LANGUAGE_EN_US + self.Lang = TAB_LANGUAGE_EN_US self.String = '' def SetLang(self, Lang): @@ -224,10 +306,10 @@ class FileNameObject(CommonPropertiesObject): # class FileObject(object): def __init__(self): - self.Executable = '' + self.Executable = '' self.Uri = '' self.OsType = '' - + def SetExecutable(self, Executable): self.Executable = Executable @@ -478,6 +560,11 @@ class UserExtensionObject(object): def __init__(self): self.UserID = '' self.Identifier = '' + self.BinaryAbstractList = [] + self.BinaryDescriptionList = [] + self.BinaryCopyrightList = [] + self.BinaryLicenseList = [] + self.UniLangDefsList = [] # # { Statement : Arch , ... } # @@ -519,6 +606,60 @@ class UserExtensionObject(object): def GetIdentifier(self): return self.Identifier + def SetUniLangDefsList(self, UniLangDefsList): + self.UniLangDefsList = UniLangDefsList + + def GetUniLangDefsList(self): + return self.UniLangDefsList + + def SetBinaryAbstract(self, BinaryAbstractList): + self.BinaryAbstractList = BinaryAbstractList + + def GetBinaryAbstract(self, Lang=None): + if Lang: + for (Key, Value) in self.BinaryAbstractList: + if Key == Lang: + return Value + return None + else: + return self.BinaryAbstractList + + def SetBinaryDescription(self, BinaryDescriptionList): + self.BinaryDescriptionList = BinaryDescriptionList + + def GetBinaryDescription(self, Lang=None): + if Lang: + for (Key, Value) in self.BinaryDescriptionList: + if Key == Lang: + return Value + return None + else: + return self.BinaryDescriptionList + + def SetBinaryCopyright(self, BinaryCopyrightList): + self.BinaryCopyrightList = BinaryCopyrightList + + def GetBinaryCopyright(self, Lang=None): + if Lang: + for (Key, Value) in self.BinaryCopyrightList: + if Key == Lang: + return Value + return None + else: + return self.BinaryCopyrightList + + def SetBinaryLicense(self, BinaryLicenseList): + self.BinaryLicenseList = BinaryLicenseList + + def GetBinaryLicense(self, Lang=None): + if Lang: + for (Key, Value) in self.BinaryLicenseList: + if Key == Lang: + return Value + return None + else: + return self.BinaryLicenseList + def SetDefinesDict(self, DefinesDict): self.DefinesDict = DefinesDict @@ -600,6 +741,10 @@ class PcdErrorObject(object): self.Expression = '' self.ErrorNumber = '' self.ErrorMessageList = [] + self.TokenSpaceGuidCName = '' + self.CName = '' + self.FileLine = '' + self.LineNum = 0 def SetValidValue(self, ValidValue): self.ValidValue = ValidValue @@ -637,7 +782,31 @@ class PcdErrorObject(object): def GetErrorMessageList(self): return self.ErrorMessageList - + def SetTokenSpaceGuidCName(self, TokenSpaceGuidCName): + self.TokenSpaceGuidCName = TokenSpaceGuidCName + + def GetTokenSpaceGuidCName(self): + return self.TokenSpaceGuidCName + + def SetCName(self, CName): + self.CName = CName + + def GetCName(self): + return self.CName + + def SetFileLine(self, FileLine): + self.FileLine = FileLine + + def GetFileLine(self): + return self.FileLine + + def SetLineNum(self, LineNum): + self.LineNum = LineNum + + def GetLineNum(self): + return self.LineNum + + ## IncludeObject # # This class defined Include item used in Module/Platform/Package files @@ -692,7 +861,7 @@ class IncludeObject(CommonPropertiesObject): # @param SkuInfoList: Input value for SkuInfoList, default is {} # @param SupModuleList: Input value for SupModuleList, default is [] # -class PcdObject(CommonPropertiesObject, HelpTextListObject): +class PcdObject(CommonPropertiesObject, HelpTextListObject, PromptListObject): def __init__(self): self.PcdCName = '' self.CName = '' @@ -709,6 +878,7 @@ class PcdObject(CommonPropertiesObject, HelpTextListObject): self.SupModuleList = [] CommonPropertiesObject.__init__(self) HelpTextListObject.__init__(self) + PromptListObject.__init__(self) def SetPcdCName(self, PcdCName): self.PcdCName = PcdCName diff --git a/BaseTools/Source/Python/UPT/Object/POM/ModuleObject.py b/BaseTools/Source/Python/UPT/Object/POM/ModuleObject.py index 620bbb411f..e85b8fa010 100644 --- a/BaseTools/Source/Python/UPT/Object/POM/ModuleObject.py +++ b/BaseTools/Source/Python/UPT/Object/POM/ModuleObject.py @@ -1,7 +1,7 @@ ## @file # This file is used to define a class object to describe a module # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -21,6 +21,7 @@ ModuleObject from Object.POM.CommonObject import CommonPropertiesObject from Object.POM.CommonObject import IdentificationObject from Object.POM.CommonObject import CommonHeaderObject +from Object.POM.CommonObject import BinaryHeaderObject from Object.POM.CommonObject import HelpTextListObject from Object.POM.CommonObject import GuidVersionObject @@ -94,7 +95,7 @@ class SpecObject(object): # # This class defined header items used in Module file # -class ModuleHeaderObject(IdentificationObject, CommonHeaderObject): +class ModuleHeaderObject(IdentificationObject, CommonHeaderObject, BinaryHeaderObject): def __init__(self): self.IsLibrary = False self.IsLibraryModList = [] @@ -103,6 +104,7 @@ class ModuleHeaderObject(IdentificationObject, CommonHeaderObject): self.PcdIsDriver = '' self.PiSpecificationVersion = '' self.UefiSpecificationVersion = '' + self.UNIFlag = False # # SpecObject # @@ -126,6 +128,7 @@ class ModuleHeaderObject(IdentificationObject, CommonHeaderObject): self.SupArchList = [] IdentificationObject.__init__(self) CommonHeaderObject.__init__(self) + BinaryHeaderObject.__init__(self) def SetIsLibrary(self, IsLibrary): self.IsLibrary = IsLibrary @@ -277,6 +280,7 @@ class AsBuildLibraryClassObject(object): def __init__(self): self.LibGuid = '' self.LibVersion = '' + self.SupArchList = [] def SetLibGuid(self, LibGuid): self.LibGuid = LibGuid @@ -288,6 +292,11 @@ class AsBuildLibraryClassObject(object): def GetLibVersion(self): return self.LibVersion + def SetSupArchList(self, SupArchList): + self.SupArchList = SupArchList + def GetSupArchList(self): + return self.SupArchList + ## # AsBuiltObject # @@ -308,7 +317,7 @@ class AsBuiltObject(object): # # List of BinaryBuildFlag object # - self.BinaryBuildFlagList = '' + self.BinaryBuildFlagList = [] def SetPatchPcdList(self, PatchPcdList): self.PatchPcdList = PatchPcdList diff --git a/BaseTools/Source/Python/UPT/Object/POM/PackageObject.py b/BaseTools/Source/Python/UPT/Object/POM/PackageObject.py index 098954d4ed..57bdcf96a3 100644 --- a/BaseTools/Source/Python/UPT/Object/POM/PackageObject.py +++ b/BaseTools/Source/Python/UPT/Object/POM/PackageObject.py @@ -1,7 +1,7 @@ ## @file # This file is used to define a class object to describe a package # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -21,6 +21,7 @@ PackageObject from Object.POM.CommonObject import CommonPropertiesObject from Object.POM.CommonObject import IdentificationObject from Object.POM.CommonObject import CommonHeaderObject +from Object.POM.CommonObject import BinaryHeaderObject from Library.Misc import Sdict ## StandardIncludeFileObject @@ -44,10 +45,11 @@ class PackageIncludeFileObject(StandardIncludeFileObject): ## # PackageObject # -class PackageObject(IdentificationObject, CommonHeaderObject): +class PackageObject(IdentificationObject, CommonHeaderObject, BinaryHeaderObject): def __init__(self): IdentificationObject.__init__(self) CommonHeaderObject.__init__(self) + BinaryHeaderObject.__init__(self) # # LibraryClassObject # @@ -85,8 +87,12 @@ class PackageObject(IdentificationObject, CommonHeaderObject): # self.PcdList = [] # - # UserExtensionObject + # {(PcdTokenSpaceGuidCName, PcdErrroNumber): PcdErrorMessageList} + # + self.PcdErrorCommentDict = {} # + # UserExtensionObject + # self.UserExtensionList = [] # # MiscFileObject @@ -104,6 +110,8 @@ class PackageObject(IdentificationObject, CommonHeaderObject): self.PcdChecks = [] + self.UNIFlag = False + def SetLibraryClassList(self, LibraryClassList): self.LibraryClassList = LibraryClassList diff --git a/BaseTools/Source/Python/UPT/Object/Parser/InfBinaryObject.py b/BaseTools/Source/Python/UPT/Object/Parser/InfBinaryObject.py index 3685fedd5c..f968beee60 100644 --- a/BaseTools/Source/Python/UPT/Object/Parser/InfBinaryObject.py +++ b/BaseTools/Source/Python/UPT/Object/Parser/InfBinaryObject.py @@ -2,7 +2,7 @@ # This file is used to define class objects of INF file [Binaries] section. # It will consumed by InfParser. # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -99,6 +99,7 @@ class InfBianryCommonItem(InfBianryItem, CurrentLine): self.CommonType = '' self.TagName = '' self.Family = '' + self.GuidValue = '' InfBianryItem.__init__(self) CurrentLine.__init__(self) @@ -116,6 +117,11 @@ class InfBianryCommonItem(InfBianryItem, CurrentLine): self.Family = Family def GetFamily(self): return self.Family + + def SetGuidValue(self, GuidValue): + self.GuidValue = GuidValue + def GetGuidValue(self): + return self.GuidValue ## # @@ -150,7 +156,7 @@ class InfBinariesObject(InfSectionCommonDef): if len(VerContent) < 2: Logger.Error("InfParser", ToolError.FORMAT_INVALID, - ST.ERR_INF_PARSER_BINARY_ITEM_FORMAT_INVALID % (VerContent[0]), + ST.ERR_INF_PARSER_BINARY_ITEM_FORMAT_INVALID % (VerContent[0], 2), File=VerCurrentLine.GetFileName(), Line=VerCurrentLine.GetLineNo(), ExtraData=VerCurrentLine.GetLineString()) @@ -291,18 +297,29 @@ class InfBinariesObject(InfSectionCommonDef): CurrentLineOfItem = Item[2] GlobalData.gINF_CURRENT_LINE = CurrentLineOfItem InfBianryCommonItemObj = None - if len(ItemContent) < 2: - Logger.Error("InfParser", - ToolError.FORMAT_INVALID, - ST.ERR_INF_PARSER_BINARY_ITEM_FORMAT_INVALID % (ItemContent[0]), - File=CurrentLineOfItem.GetFileName(), - Line=CurrentLineOfItem.GetLineNo(), - ExtraData=CurrentLineOfItem.GetLineString()) - return False - if len(ItemContent) > 6: + if ItemContent[0] == 'SUBTYPE_GUID': + if len(ItemContent) < 3: + Logger.Error("InfParser", + ToolError.FORMAT_INVALID, + ST.ERR_INF_PARSER_BINARY_ITEM_FORMAT_INVALID % (ItemContent[0], 3), + File=CurrentLineOfItem.GetFileName(), + Line=CurrentLineOfItem.GetLineNo(), + ExtraData=CurrentLineOfItem.GetLineString()) + return False + else: + if len(ItemContent) < 2: + Logger.Error("InfParser", + ToolError.FORMAT_INVALID, + ST.ERR_INF_PARSER_BINARY_ITEM_FORMAT_INVALID % (ItemContent[0], 2), + File=CurrentLineOfItem.GetFileName(), + Line=CurrentLineOfItem.GetLineNo(), + ExtraData=CurrentLineOfItem.GetLineString()) + return False + + if len(ItemContent) > 7: Logger.Error("InfParser", ToolError.FORMAT_INVALID, - ST.ERR_INF_PARSER_BINARY_ITEM_FORMAT_INVALID_MAX % (ItemContent[0], 6), + ST.ERR_INF_PARSER_BINARY_ITEM_FORMAT_INVALID_MAX % (ItemContent[0], 7), File=CurrentLineOfItem.GetFileName(), Line=CurrentLineOfItem.GetLineNo(), ExtraData=CurrentLineOfItem.GetLineString()) @@ -318,7 +335,7 @@ class InfBinariesObject(InfSectionCommonDef): BinaryFileType = ItemContent[0].strip() if BinaryFileType == 'RAW' or BinaryFileType == 'ACPI' or BinaryFileType == 'ASL': BinaryFileType = 'BIN' - + if BinaryFileType not in DT.BINARY_FILE_TYPE_LIST: Logger.Error("InfParser", ToolError.FORMAT_INVALID, @@ -342,44 +359,64 @@ class InfBinariesObject(InfSectionCommonDef): InfBianryCommonItemObj.SetType(BinaryFileType) InfBianryCommonItemObj.SetCommonType(ItemContent[0]) + FileName = '' + if BinaryFileType == 'FREEFORM': + InfBianryCommonItemObj.SetGuidValue(ItemContent[1]) + if len(ItemContent) >= 3: + FileName = ItemContent[2] + else: + Logger.Error("InfParser", + ToolError.FORMAT_INVALID, + ST.ERR_INF_PARSER_BINARY_ITEM_FILENAME_NOT_EXIST, + File=CurrentLineOfItem.GetFileName(), + Line=CurrentLineOfItem.GetLineNo(), + ExtraData=CurrentLineOfItem.GetLineString()) + else: + FileName = ItemContent[1] # # Verify File exist or not # FullFileName = os.path.normpath(os.path.realpath(os.path.join(GlobalData.gINF_MODULE_DIR, - ItemContent[1]))) - if not (ValidFile(FullFileName) or ValidFile(ItemContent[1])): + FileName))) + if not (ValidFile(FullFileName) or ValidFile(FileName)): Logger.Error("InfParser", ToolError.FORMAT_INVALID, - ST.ERR_INF_PARSER_BINARY_ITEM_FILE_NOT_EXIST % (ItemContent[1]), + ST.ERR_INF_PARSER_BINARY_ITEM_FILE_NOT_EXIST % (FileName), File=CurrentLineOfItem.GetFileName(), Line=CurrentLineOfItem.GetLineNo(), ExtraData=CurrentLineOfItem.GetLineString()) # # Validate file exist/format. # - if IsValidPath(ItemContent[1], GlobalData.gINF_MODULE_DIR): + if IsValidPath(FileName, GlobalData.gINF_MODULE_DIR): IsValidFileFlag = True else: Logger.Error("InfParser", ToolError.FORMAT_INVALID, - ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID % (ItemContent[1]), + ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID % (FileName), File=CurrentLineOfItem.GetFileName(), Line=CurrentLineOfItem.GetLineNo(), ExtraData=CurrentLineOfItem.GetLineString()) return False if IsValidFileFlag: ItemContent[0] = ConvPathFromAbsToRel(ItemContent[0], GlobalData.gINF_MODULE_DIR) - InfBianryCommonItemObj.SetFileName(ItemContent[1]) + InfBianryCommonItemObj.SetFileName(FileName) if len(ItemContent) >= 3: # # Add Target information # - InfBianryCommonItemObj.SetTarget(ItemContent[2]) + if BinaryFileType != 'FREEFORM': + InfBianryCommonItemObj.SetTarget(ItemContent[2]) + if len(ItemContent) >= 4: # # Add Family information # - InfBianryCommonItemObj.SetFamily(ItemContent[3]) + if BinaryFileType != 'FREEFORM': + InfBianryCommonItemObj.SetFamily(ItemContent[3]) + else: + InfBianryCommonItemObj.SetTarget(ItemContent[3]) + if len(ItemContent) >= 5: # # TagName entries are build system specific. If there @@ -388,28 +425,62 @@ class InfBinariesObject(InfSectionCommonDef): # system specific content cannot be distributed using # the UDP # - if ItemContent[4].strip() != '': - Logger.Error("InfParser", - ToolError.FORMAT_INVALID, - ST.ERR_INF_PARSER_TAGNAME_NOT_PERMITTED % (ItemContent[4]), - File=CurrentLineOfItem.GetFileName(), - Line=CurrentLineOfItem.GetLineNo(), - ExtraData=CurrentLineOfItem.GetLineString()) - if len(ItemContent) == 6: + if BinaryFileType != 'FREEFORM': + if ItemContent[4].strip() != '': + Logger.Error("InfParser", + ToolError.FORMAT_INVALID, + ST.ERR_INF_PARSER_TAGNAME_NOT_PERMITTED % (ItemContent[4]), + File=CurrentLineOfItem.GetFileName(), + Line=CurrentLineOfItem.GetLineNo(), + ExtraData=CurrentLineOfItem.GetLineString()) + else: + InfBianryCommonItemObj.SetFamily(ItemContent[4]) + + if len(ItemContent) >= 6: # # Add FeatureFlagExp # - if ItemContent[5].strip() == '': + if BinaryFileType != 'FREEFORM': + if ItemContent[5].strip() == '': + Logger.Error("InfParser", + ToolError.FORMAT_INVALID, + ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_MISSING, + File=CurrentLineOfItem.GetFileName(), + Line=CurrentLineOfItem.GetLineNo(), + ExtraData=CurrentLineOfItem.GetLineString()) + # + # Validate Feature Flag Express + # + FeatureFlagRtv = IsValidFeatureFlagExp(ItemContent[5].strip()) + if not FeatureFlagRtv[0]: + Logger.Error("InfParser", + ToolError.FORMAT_INVALID, + ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID % (FeatureFlagRtv[1]), + File=CurrentLineOfItem.GetFileName(), + Line=CurrentLineOfItem.GetLineNo(), + ExtraData=CurrentLineOfItem.GetLineString()) + InfBianryCommonItemObj.SetFeatureFlagExp(ItemContent[5]) + else: + if ItemContent[5].strip() != '': + Logger.Error("InfParser", + ToolError.FORMAT_INVALID, + ST.ERR_INF_PARSER_TAGNAME_NOT_PERMITTED % (ItemContent[5]), + File=CurrentLineOfItem.GetFileName(), + Line=CurrentLineOfItem.GetLineNo(), + ExtraData=CurrentLineOfItem.GetLineString()) + + if len(ItemContent) == 7: + if ItemContent[6].strip() == '': Logger.Error("InfParser", - ToolError.FORMAT_INVALID, - ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_MISSING, - File=CurrentLineOfItem.GetFileName(), - Line=CurrentLineOfItem.GetLineNo(), - ExtraData=CurrentLineOfItem.GetLineString()) + ToolError.FORMAT_INVALID, + ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_MISSING, + File=CurrentLineOfItem.GetFileName(), + Line=CurrentLineOfItem.GetLineNo(), + ExtraData=CurrentLineOfItem.GetLineString()) # # Validate Feature Flag Express # - FeatureFlagRtv = IsValidFeatureFlagExp(ItemContent[5].strip()) + FeatureFlagRtv = IsValidFeatureFlagExp(ItemContent[6].strip()) if not FeatureFlagRtv[0]: Logger.Error("InfParser", ToolError.FORMAT_INVALID, @@ -417,7 +488,7 @@ class InfBinariesObject(InfSectionCommonDef): File=CurrentLineOfItem.GetFileName(), Line=CurrentLineOfItem.GetLineNo(), ExtraData=CurrentLineOfItem.GetLineString()) - InfBianryCommonItemObj.SetFeatureFlagExp(ItemContent[5]) + InfBianryCommonItemObj.SetFeatureFlagExp(ItemContent[6]) InfBianryCommonItemObj.SetSupArchList(__SupArchList) @@ -489,7 +560,7 @@ class InfBinariesObject(InfSectionCommonDef): if len(UiContent) < 2: Logger.Error("InfParser", ToolError.FORMAT_INVALID, - ST.ERR_INF_PARSER_BINARY_ITEM_FORMAT_INVALID % (UiContent[0]), + ST.ERR_INF_PARSER_BINARY_ITEM_FORMAT_INVALID % (UiContent[0], 2), File=UiCurrentLine.GetFileName(), Line=UiCurrentLine.GetLineNo(), ExtraData=UiCurrentLine.GetLineString()) diff --git a/BaseTools/Source/Python/UPT/Object/Parser/InfBuildOptionObject.py b/BaseTools/Source/Python/UPT/Object/Parser/InfBuildOptionObject.py index 5549525a6c..391669fe64 100644 --- a/BaseTools/Source/Python/UPT/Object/Parser/InfBuildOptionObject.py +++ b/BaseTools/Source/Python/UPT/Object/Parser/InfBuildOptionObject.py @@ -2,7 +2,7 @@ # This file is used to define class objects of INF file [BuildOptions] section. # It will consumed by InfParser. # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -84,8 +84,8 @@ class InfBuildOptionsObject(InfSectionCommonDef): if len(BuildOptCont) >= 1: InfBuildOptionItemObj = InfBuildOptionItem() InfBuildOptionItemObj.SetAsBuildList(BuildOptCont) + InfBuildOptionItemObj.SetSupArchList(ArchList) self.BuildOptions.append(InfBuildOptionItemObj) - return True diff --git a/BaseTools/Source/Python/UPT/Object/Parser/InfDefineObject.py b/BaseTools/Source/Python/UPT/Object/Parser/InfDefineObject.py index c7883e6980..be9a0e196e 100644 --- a/BaseTools/Source/Python/UPT/Object/Parser/InfDefineObject.py +++ b/BaseTools/Source/Python/UPT/Object/Parser/InfDefineObject.py @@ -2,7 +2,7 @@ # This file is used to define class objects of [Defines] section for INF file. # It will consumed by InfParser # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -27,6 +27,7 @@ from Library.String import GetSplitValueList from Library.Misc import CheckGuidRegFormat from Library.Misc import Sdict from Library.Misc import ConvPathFromAbsToRel +from Library.Misc import ValidateUNIFilePath from Library.ExpressionValidate import IsValidFeatureFlagExp from Library.ParserValidate import IsValidWord from Library.ParserValidate import IsValidInfMoudleType @@ -185,6 +186,7 @@ class InfDefSection(InfDefSectionOptionRomInfo): self.BaseName = None self.FileGuid = None self.ModuleType = None + self.ModuleUniFileName = None self.InfVersion = None self.EdkReleaseVersion = None self.UefiSpecificationVersion = None @@ -216,8 +218,7 @@ class InfDefSection(InfDefSectionOptionRomInfo): if self.BaseName != None: ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND%(DT.TAB_INF_DEFINES_BASE_NAME), LineInfo=self.CurrentLine) - return False - + return False if not (BaseName == '' or BaseName == None): if IsValidWord(BaseName) and not BaseName.startswith("_"): self.BaseName = InfDefMember() @@ -301,6 +302,23 @@ class InfDefSection(InfDefSectionOptionRomInfo): def GetModuleType(self): return self.ModuleType + ## SetModuleUniFileName + # + # @param ModuleUniFileName: ModuleUniFileName + # + def SetModuleUniFileName(self, ModuleUniFileName, Comments): + if Comments: + pass + if self.ModuleUniFileName != None: + ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND%(DT.TAB_INF_DEFINES_MODULE_UNI_FILE), + LineInfo=self.CurrentLine) + self.ModuleUniFileName = ModuleUniFileName + + ## GetModuleType + # + def GetModuleUniFileName(self): + return self.ModuleUniFileName + ## SetInfVersion # # @param InfVersion: InfVersion @@ -520,10 +538,8 @@ class InfDefSection(InfDefSectionOptionRomInfo): # It can be a list # ValueList = [] - TokenList = GetSplitValueList(EntryPoint, DT.TAB_VALUE_SPLIT) ValueList[0:len(TokenList)] = TokenList - InfDefineEntryPointItemObj = InfDefineEntryPointItem() if not IsValidCVariableName(ValueList[0]): ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%\ @@ -542,13 +558,11 @@ class InfDefSection(InfDefSectionOptionRomInfo): if not FeatureFlagRtv[0]: ErrorInInf(ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID%\ (FeatureFlagRtv[1]), - LineInfo=self.CurrentLine) - + LineInfo=self.CurrentLine) InfDefineEntryPointItemObj.SetFeatureFlagExp(ValueList[1]) if len(ValueList) > 2: ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(EntryPoint), LineInfo=self.CurrentLine) - InfDefineEntryPointItemObj.Comments = Comments self.EntryPoint.append(InfDefineEntryPointItemObj) @@ -563,10 +577,8 @@ class InfDefSection(InfDefSectionOptionRomInfo): # It can be a list # ValueList = [] - TokenList = GetSplitValueList(UnloadImages, DT.TAB_VALUE_SPLIT) ValueList[0:len(TokenList)] = TokenList - InfDefineUnloadImageItemObj = InfDefineUnloadImageItem() if not IsValidCVariableName(ValueList[0]): ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(ValueList[0]), @@ -588,7 +600,6 @@ class InfDefSection(InfDefSectionOptionRomInfo): if len(ValueList) > 2: ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(UnloadImages), LineInfo=self.CurrentLine) - InfDefineUnloadImageItemObj.Comments = Comments self.UnloadImages.append(InfDefineUnloadImageItemObj) @@ -603,10 +614,8 @@ class InfDefSection(InfDefSectionOptionRomInfo): # It can be a list # ValueList = [] - TokenList = GetSplitValueList(Constructor, DT.TAB_VALUE_SPLIT) ValueList[0:len(TokenList)] = TokenList - InfDefineConstructorItemObj = InfDefineConstructorItem() if not IsValidCVariableName(ValueList[0]): ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(ValueList[0]), @@ -638,7 +647,6 @@ class InfDefSection(InfDefSectionOptionRomInfo): if len(ValueList) > 3: ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(Constructor), LineInfo=self.CurrentLine) - InfDefineConstructorItemObj.Comments = Comments self.Constructor.append(InfDefineConstructorItemObj) @@ -653,10 +661,8 @@ class InfDefSection(InfDefSectionOptionRomInfo): # It can be a list and only 1 set to TRUE # ValueList = [] - TokenList = GetSplitValueList(Destructor, DT.TAB_VALUE_SPLIT) ValueList[0:len(TokenList)] = TokenList - InfDefineDestructorItemObj = InfDefineDestructorItem() if not IsValidCVariableName(ValueList[0]): ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(ValueList[0]), @@ -715,8 +721,6 @@ class InfDefSection(InfDefSectionOptionRomInfo): def GetShadow(self): return self.Shadow - - # # ::= {"MSFT"} {"GCC"} # ::= [ "|"] @@ -788,8 +792,7 @@ class InfDefSection(InfDefSectionOptionRomInfo): else: ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(Name), LineInfo=self.CurrentLine) - return False - + return False return True def GetSpecification(self): @@ -860,6 +863,7 @@ gFUNCTION_MAPPING_FOR_DEFINE_SECTION = { # # Optional Fields # + DT.TAB_INF_DEFINES_MODULE_UNI_FILE : InfDefSection.SetModuleUniFileName, DT.TAB_INF_DEFINES_EDK_RELEASE_VERSION : InfDefSection.SetEdkReleaseVersion, DT.TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION : InfDefSection.SetUefiSpecificationVersion, DT.TAB_INF_DEFINES_PI_SPECIFICATION_VERSION : InfDefSection.SetPiSpecificationVersion, @@ -891,7 +895,6 @@ class InfDefMember(): self.Name = Name self.Value = Value self.CurrentLine = CurrentLine() - def GetName(self): return self.Name def SetName(self, Name): @@ -914,8 +917,7 @@ class InfDefObject(InfSectionCommonDef): # HasFoundInfVersionFalg = False LineInfo = ['', -1, ''] - ArchListString = ' '.join(Arch) - + ArchListString = ' '.join(Arch) # # Parse Define items. # @@ -923,6 +925,15 @@ class InfDefObject(InfSectionCommonDef): ProcessFunc = None Name = InfDefMemberObj.GetName() Value = InfDefMemberObj.GetValue() + if Name == DT.TAB_INF_DEFINES_MODULE_UNI_FILE: + ValidateUNIFilePath(Value) + Value = os.path.join(os.path.dirname(InfDefMemberObj.CurrentLine.FileName), Value) + if not os.path.isfile(Value) or not os.path.exists(Value): + LineInfo[0] = InfDefMemberObj.CurrentLine.GetFileName() + LineInfo[1] = InfDefMemberObj.CurrentLine.GetLineNo() + LineInfo[2] = InfDefMemberObj.CurrentLine.GetLineString() + ErrorInInf(ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID%(Name), + LineInfo=LineInfo) InfLineCommentObj = InfLineCommentObject() InfLineCommentObj.SetHeaderComments(InfDefMemberObj.Comments.GetHeaderComments()) InfLineCommentObj.SetTailComments(InfDefMemberObj.Comments.GetTailComments()) @@ -932,7 +943,6 @@ class InfDefObject(InfSectionCommonDef): RaiseError=True) if Name == DT.TAB_INF_DEFINES_INF_VERSION: HasFoundInfVersionFalg = True - if not (Name == '' or Name == None): # # Process "SPEC" Keyword definition. @@ -953,8 +963,7 @@ class InfDefObject(InfSectionCommonDef): # if Name not in gFUNCTION_MAPPING_FOR_DEFINE_SECTION.keys(): ErrorInInf(ST.ERR_INF_PARSER_DEFINE_SECTION_KEYWORD_INVALID%(Name), - LineInfo=LineInfo) - + LineInfo=LineInfo) else: ProcessFunc = gFUNCTION_MAPPING_FOR_DEFINE_SECTION[Name] if (ProcessFunc != None): @@ -980,7 +989,6 @@ class InfDefObject(InfSectionCommonDef): if (ProcessFunc != None): ProcessFunc(DefineList, Value, InfLineCommentObj) self.Defines[ArchListString] = DefineList - # # After set, check whether INF_VERSION defined. # diff --git a/BaseTools/Source/Python/UPT/Object/Parser/InfGuidObject.py b/BaseTools/Source/Python/UPT/Object/Parser/InfGuidObject.py index 4f1a3f4e81..23125552e0 100644 --- a/BaseTools/Source/Python/UPT/Object/Parser/InfGuidObject.py +++ b/BaseTools/Source/Python/UPT/Object/Parser/InfGuidObject.py @@ -2,7 +2,7 @@ # This file is used to define class objects of INF file [Guids] section. # It will consumed by InfParser. # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -156,7 +156,6 @@ def ParseGuidComment(CommentsList, InfGuidItemObj): # if CommentItemUsage == CommentItemGuidType == PreUsage == PreGuidType == DT.ITEM_UNDEFINED: CommentItemHelpText = PreHelpText + DT.END_OF_LINE + CommentItemHelpText - PreHelpText = CommentItemHelpText if BlockFlag == 4: @@ -164,6 +163,8 @@ def ParseGuidComment(CommentsList, InfGuidItemObj): CommentItemIns.SetUsageItem(CommentItemUsage) CommentItemIns.SetGuidTypeItem(CommentItemGuidType) CommentItemIns.SetVariableNameItem(CommentItemVarString) + if CommentItemHelpText == '' or CommentItemHelpText.endswith(DT.END_OF_LINE): + CommentItemHelpText = CommentItemHelpText.strip(DT.END_OF_LINE) CommentItemIns.SetHelpStringItem(CommentItemHelpText) CommentInsList.append(CommentItemIns) @@ -180,7 +181,7 @@ def ParseGuidComment(CommentsList, InfGuidItemObj): CommentItemIns.SetUsageItem(DT.ITEM_UNDEFINED) CommentItemIns.SetGuidTypeItem(DT.ITEM_UNDEFINED) if PreHelpText == '' or PreHelpText.endswith(DT.END_OF_LINE): - PreHelpText += DT.END_OF_LINE + PreHelpText = PreHelpText.strip(DT.END_OF_LINE) CommentItemIns.SetHelpStringItem(PreHelpText) CommentInsList.append(CommentItemIns) # @@ -190,6 +191,8 @@ def ParseGuidComment(CommentsList, InfGuidItemObj): CommentItemIns.SetUsageItem(CommentItemUsage) CommentItemIns.SetGuidTypeItem(CommentItemGuidType) CommentItemIns.SetVariableNameItem(CommentItemVarString) + if CommentItemHelpText == '' or CommentItemHelpText.endswith(DT.END_OF_LINE): + CommentItemHelpText = CommentItemHelpText.strip(DT.END_OF_LINE) CommentItemIns.SetHelpStringItem(CommentItemHelpText) CommentInsList.append(CommentItemIns) diff --git a/BaseTools/Source/Python/UPT/Object/Parser/InfLibraryClassesObject.py b/BaseTools/Source/Python/UPT/Object/Parser/InfLibraryClassesObject.py index a37692ee23..b18c4c381b 100644 --- a/BaseTools/Source/Python/UPT/Object/Parser/InfLibraryClassesObject.py +++ b/BaseTools/Source/Python/UPT/Object/Parser/InfLibraryClassesObject.py @@ -2,7 +2,7 @@ # This file is used to define class objects of INF file [LibraryClasses] section. # It will consumed by InfParser. # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -236,6 +236,7 @@ class InfLibraryClassObject(): # LibItemObj.SetFileGuid(LibItem[0]) LibItemObj.SetVersion(LibItem[1]) + LibItemObj.SetSupArchList(__SupArchList) if self.LibraryClasses.has_key((LibItemObj)): LibraryList = self.LibraryClasses[LibItemObj] diff --git a/BaseTools/Source/Python/UPT/Object/Parser/InfPcdObject.py b/BaseTools/Source/Python/UPT/Object/Parser/InfPcdObject.py index fc5227451a..7b07036f91 100644 --- a/BaseTools/Source/Python/UPT/Object/Parser/InfPcdObject.py +++ b/BaseTools/Source/Python/UPT/Object/Parser/InfPcdObject.py @@ -2,7 +2,7 @@ # This file is used to define class objects of INF file [Pcds] section. # It will consumed by InfParser. # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -21,12 +21,12 @@ import re from Logger import StringTable as ST from Logger import ToolError import Logger.Log as Logger -from Library import GlobalData +from Library import GlobalData from Library import DataType as DT from Library.Misc import Sdict from Library.Misc import GetHelpStringByRemoveHashKey -from Library.ParserValidate import IsValidPcdType +from Library.ParserValidate import IsValidPcdType from Library.ParserValidate import IsValidCVariableName from Library.ParserValidate import IsValidPcdValue from Library.ParserValidate import IsValidArch @@ -45,21 +45,21 @@ def ValidateArch(ArchItem, PcdTypeItem1, LineNo, SupArchDict, SupArchList): # if (ArchItem == '' or ArchItem == None): ArchItem = 'COMMON' - + if PcdTypeItem1.upper != DT.TAB_INF_FEATURE_PCD.upper(): ArchList = GetSplitValueList(ArchItem, ' ') for ArchItemNew in ArchList: if not IsValidArch(ArchItemNew): - Logger.Error("InfParser", + Logger.Error("InfParser", ToolError.FORMAT_INVALID, - ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(ArchItemNew), + ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID % (ArchItemNew), File=GlobalData.gINF_MODULE_NAME, - Line=LineNo, + Line=LineNo, ExtraData=ArchItemNew) - SupArchDict[PcdTypeItem1] = ArchList + SupArchDict[PcdTypeItem1] = ArchList else: SupArchList.append(ArchItem) - + return SupArchList, SupArchDict def ParsePcdComment(CommentList, PcdTypeItem, PcdItemObj): @@ -68,47 +68,47 @@ def ParsePcdComment(CommentList, PcdTypeItem, PcdItemObj): PreHelpText = '' BlockFlag = -1 FFEHelpText = '' - CommentItemHelpText = '' - Count = 0 + CommentItemHelpText = '' + Count = 0 for CommentItem in CommentList: Count = Count + 1 - CommentItemUsage, CommentType, CommentString, CommentItemHelpText = ParseComment(CommentItem, - DT.ALL_USAGE_TOKENS, - {}, + CommentItemUsage, CommentType, CommentString, CommentItemHelpText = ParseComment(CommentItem, + DT.ALL_USAGE_TOKENS, + {}, [], False) if CommentType and CommentString: - pass - + pass + if PcdTypeItem == 'FeaturePcd': CommentItemUsage = DT.USAGE_ITEM_CONSUMES if CommentItemHelpText == None: CommentItemHelpText = '' - + if Count == 1: FFEHelpText = CommentItemHelpText else: FFEHelpText = FFEHelpText + DT.END_OF_LINE + CommentItemHelpText - + if Count == len(CommentList): CommentItemHelpText = FFEHelpText BlockFlag = 4 else: continue - + if CommentItemHelpText == None: CommentItemHelpText = '' if Count == len(CommentList) and CommentItemUsage == DT.ITEM_UNDEFINED: CommentItemHelpText = DT.END_OF_LINE - + if Count == len(CommentList) and (BlockFlag == 1 or BlockFlag == 2): if CommentItemUsage == DT.ITEM_UNDEFINED: BlockFlag = 4 else: BlockFlag = 3 elif BlockFlag == -1 and Count == len(CommentList): - BlockFlag = 4 - + BlockFlag = 4 + if BlockFlag == -1 or BlockFlag == 1 or BlockFlag == 2: if CommentItemUsage == DT.ITEM_UNDEFINED: if BlockFlag == -1: @@ -125,19 +125,19 @@ def ParsePcdComment(CommentList, PcdTypeItem, PcdItemObj): # if CommentItemUsage == PreUsage == DT.ITEM_UNDEFINED: CommentItemHelpText = PreHelpText + DT.END_OF_LINE + CommentItemHelpText - + PreHelpText = CommentItemHelpText - - if BlockFlag == 4: + + if BlockFlag == 4: CommentItemIns = InfPcdItemCommentContent() CommentItemIns.SetUsageItem(CommentItemUsage) CommentItemIns.SetHelpStringItem(CommentItemHelpText) CommentInsList.append(CommentItemIns) - + BlockFlag = -1 PreUsage = None PreHelpText = '' - + elif BlockFlag == 3: # # Add previous help string @@ -145,7 +145,7 @@ def ParsePcdComment(CommentList, PcdTypeItem, PcdItemObj): CommentItemIns = InfPcdItemCommentContent() CommentItemIns.SetUsageItem(DT.ITEM_UNDEFINED) if PreHelpText == '' or PreHelpText.endswith(DT.END_OF_LINE): - PreHelpText += DT.END_OF_LINE + PreHelpText += DT.END_OF_LINE CommentItemIns.SetHelpStringItem(PreHelpText) CommentInsList.append(CommentItemIns) # @@ -155,18 +155,18 @@ def ParsePcdComment(CommentList, PcdTypeItem, PcdItemObj): CommentItemIns.SetUsageItem(CommentItemUsage) CommentItemIns.SetHelpStringItem(CommentItemHelpText) CommentInsList.append(CommentItemIns) - + BlockFlag = -1 PreUsage = None - PreHelpText = '' - + PreHelpText = '' + else: PreUsage = CommentItemUsage PreHelpText = CommentItemHelpText - + PcdItemObj.SetHelpStringList(CommentInsList) - - return PcdItemObj + + return PcdItemObj class InfPcdItemCommentContent(): def __init__(self): @@ -178,17 +178,17 @@ class InfPcdItemCommentContent(): # Help String # self.HelpStringItem = '' - + def SetUsageItem(self, UsageItem): self.UsageItem = UsageItem def GetUsageItem(self): return self.UsageItem - + def SetHelpStringItem(self, HelpStringItem): self.HelpStringItem = HelpStringItem def GetHelpStringItem(self): return self.HelpStringItem - + ## InfPcdItem # # This class defined Pcd item used in Module files @@ -211,88 +211,94 @@ class InfPcdItem(): self.Token = '' self.TokenSpaceGuidCName = '' self.TokenSpaceGuidValue = '' - self.DatumType = '' - self.MaxDatumSize = '' - self.DefaultValue = '' - self.Offset = '' - self.ValidUsage = '' - self.ItemType = '' - self.SupModuleList = [] + self.DatumType = '' + self.MaxDatumSize = '' + self.DefaultValue = '' + self.Offset = '' + self.ValidUsage = '' + self.ItemType = '' + self.SupModuleList = [] self.HelpStringList = [] self.FeatureFlagExp = '' - self.SupArchList = [] + self.SupArchList = [] self.PcdErrorsList = [] - + def SetCName(self, CName): - self.CName = CName + self.CName = CName def GetCName(self): return self.CName - + def SetToken(self, Token): - self.Token = Token + self.Token = Token def GetToken(self): return self.Token - + def SetTokenSpaceGuidCName(self, TokenSpaceGuidCName): - self.TokenSpaceGuidCName = TokenSpaceGuidCName + self.TokenSpaceGuidCName = TokenSpaceGuidCName def GetTokenSpaceGuidCName(self): return self.TokenSpaceGuidCName - + def SetTokenSpaceGuidValue(self, TokenSpaceGuidValue): - self.TokenSpaceGuidValue = TokenSpaceGuidValue + self.TokenSpaceGuidValue = TokenSpaceGuidValue def GetTokenSpaceGuidValue(self): return self.TokenSpaceGuidValue - + def SetDatumType(self, DatumType): - self.DatumType = DatumType + self.DatumType = DatumType def GetDatumType(self): return self.DatumType - + def SetMaxDatumSize(self, MaxDatumSize): - self.MaxDatumSize = MaxDatumSize + self.MaxDatumSize = MaxDatumSize def GetMaxDatumSize(self): return self.MaxDatumSize def SetDefaultValue(self, DefaultValue): - self.DefaultValue = DefaultValue + self.DefaultValue = DefaultValue def GetDefaultValue(self): return self.DefaultValue - + def SetPcdErrorsList(self, PcdErrorsList): - self.PcdErrorsList = PcdErrorsList + self.PcdErrorsList = PcdErrorsList def GetPcdErrorsList(self): return self.PcdErrorsList def SetItemType(self, ItemType): - self.ItemType = ItemType + self.ItemType = ItemType def GetItemType(self): return self.ItemType def SetSupModuleList(self, SupModuleList): - self.SupModuleList = SupModuleList + self.SupModuleList = SupModuleList def GetSupModuleList(self): return self.SupModuleList - + def SetHelpStringList(self, HelpStringList): self.HelpStringList = HelpStringList def GetHelpStringList(self): return self.HelpStringList - + def SetFeatureFlagExp(self, FeatureFlagExp): self.FeatureFlagExp = FeatureFlagExp def GetFeatureFlagExp(self): return self.FeatureFlagExp - + def SetSupportArchList(self, ArchList): self.SupArchList = ArchList def GetSupportArchList(self): return self.SupArchList - + def SetOffset(self, Offset): self.Offset = Offset def GetOffset(self): return self.Offset + def SetValidUsage(self, ValidUsage): + self.ValidUsage = ValidUsage + + def GetValidUsage(self): + return self.ValidUsage + ## # # @@ -301,13 +307,13 @@ class InfPcdObject(): def __init__(self, FileName): self.Pcds = Sdict() self.FileName = FileName - - def SetPcds(self, PcdContent, KeysList = None, PackageInfo = None): - + + def SetPcds(self, PcdContent, KeysList=None, PackageInfo=None): + if GlobalData.gIS_BINARY_INF: self.SetAsBuildPcds(PcdContent, KeysList, PackageInfo) return True - + # # Validate Arch # @@ -316,7 +322,7 @@ class InfPcdObject(): PcdTypeItem = '' for (PcdTypeItem1, ArchItem, LineNo) in KeysList: SupArchList, SupArchDict = ValidateArch(ArchItem, PcdTypeItem1, LineNo, SupArchDict, SupArchList) - + # # Validate PcdType # @@ -324,32 +330,32 @@ class InfPcdObject(): return False else: if not IsValidPcdType(PcdTypeItem1): - Logger.Error("InfParser", - ToolError.FORMAT_INVALID, - ST.ERR_INF_PARSER_PCD_SECTION_TYPE_ERROR%(DT.PCD_USAGE_TYPE_LIST_OF_MODULE), - File=GlobalData.gINF_MODULE_NAME, - Line=LineNo, + Logger.Error("InfParser", + ToolError.FORMAT_INVALID, + ST.ERR_INF_PARSER_PCD_SECTION_TYPE_ERROR % (DT.PCD_USAGE_TYPE_LIST_OF_MODULE), + File=GlobalData.gINF_MODULE_NAME, + Line=LineNo, ExtraData=PcdTypeItem1) return False - + PcdTypeItem = PcdTypeItem1 - + for PcdItem in PcdContent: PcdItemObj = InfPcdItem() CommentList = PcdItem[1] CurrentLineOfPcdItem = PcdItem[2] PcdItem = PcdItem[0] - + if CommentList != None and len(CommentList) != 0: PcdItemObj = ParsePcdComment(CommentList, PcdTypeItem, PcdItemObj) else: CommentItemIns = InfPcdItemCommentContent() CommentItemIns.SetUsageItem(DT.ITEM_UNDEFINED) PcdItemObj.SetHelpStringList([CommentItemIns]) - + if len(PcdItem) >= 1 and len(PcdItem) <= 3: PcdItemObj = SetPcdName(PcdItem, CurrentLineOfPcdItem, PcdItemObj) - + if len(PcdItem) >= 2 and len(PcdItem) <= 3: # # Contain PcdName and Value, validate value. @@ -357,13 +363,13 @@ class InfPcdObject(): if IsValidPcdValue(PcdItem[1]) or PcdItem[1].strip() == "": PcdItemObj.SetDefaultValue(PcdItem[1]) else: - Logger.Error("InfParser", - ToolError.FORMAT_INVALID, + Logger.Error("InfParser", + ToolError.FORMAT_INVALID, ST.ERR_INF_PARSER_PCD_VALUE_INVALID, - File=CurrentLineOfPcdItem[2], - Line=CurrentLineOfPcdItem[1], + File=CurrentLineOfPcdItem[2], + Line=CurrentLineOfPcdItem[1], ExtraData=PcdItem[1]) - + if len(PcdItem) == 3: # # Contain PcdName, value, and FeatureFlag express @@ -372,40 +378,40 @@ class InfPcdObject(): # Validate Feature Flag Express # if PcdItem[2].strip() == '': - Logger.Error("InfParser", - ToolError.FORMAT_INVALID, + Logger.Error("InfParser", + ToolError.FORMAT_INVALID, ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_MISSING, - File=CurrentLineOfPcdItem[2], - Line=CurrentLineOfPcdItem[1], + File=CurrentLineOfPcdItem[2], + Line=CurrentLineOfPcdItem[1], ExtraData=CurrentLineOfPcdItem[0]) # # Validate FFE # FeatureFlagRtv = IsValidFeatureFlagExp(PcdItem[2].strip()) if not FeatureFlagRtv[0]: - Logger.Error("InfParser", - ToolError.FORMAT_INVALID, - ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID%(FeatureFlagRtv[1]), - File=CurrentLineOfPcdItem[2], - Line=CurrentLineOfPcdItem[1], + Logger.Error("InfParser", + ToolError.FORMAT_INVALID, + ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID % (FeatureFlagRtv[1]), + File=CurrentLineOfPcdItem[2], + Line=CurrentLineOfPcdItem[1], ExtraData=CurrentLineOfPcdItem[0]) PcdItemObj.SetFeatureFlagExp(PcdItem[2]) - + if len(PcdItem) < 1 or len(PcdItem) > 3: - Logger.Error("InfParser", - ToolError.FORMAT_INVALID, + Logger.Error("InfParser", + ToolError.FORMAT_INVALID, ST.ERR_INF_PARSER_PCD_SECTION_CONTENT_ERROR, - File=CurrentLineOfPcdItem[2], - Line=CurrentLineOfPcdItem[1], + File=CurrentLineOfPcdItem[2], + Line=CurrentLineOfPcdItem[1], ExtraData=CurrentLineOfPcdItem[0]) - return False - + return False + if PcdTypeItem.upper != DT.TAB_INF_FEATURE_PCD.upper(): PcdItemObj.SetSupportArchList(SupArchDict[PcdTypeItem]) else: PcdItemObj.SetSupportArchList(SupArchList) - - if self.Pcds.has_key((PcdTypeItem, PcdItemObj)): + + if self.Pcds.has_key((PcdTypeItem, PcdItemObj)): PcdsList = self.Pcds[PcdTypeItem, PcdItemObj] PcdsList.append(PcdItemObj) self.Pcds[PcdTypeItem, PcdItemObj] = PcdsList @@ -413,56 +419,64 @@ class InfPcdObject(): PcdsList = [] PcdsList.append(PcdItemObj) self.Pcds[PcdTypeItem, PcdItemObj] = PcdsList - + return True - - def SetAsBuildPcds(self, PcdContent, KeysList = None, PackageInfo = None): + + def SetAsBuildPcds(self, PcdContent, KeysList=None, PackageInfo=None): for PcdItem in PcdContent: PcdItemObj = InfPcdItem() CommentList = PcdItem[1] CurrentLineOfPcdItem = PcdItem[2] PcdItem = PcdItem[0] CommentString = '' - for CommmentLine in CommentList: - CommentString += GetHelpStringByRemoveHashKey(CommmentLine) - - PcdItemObj.SetHelpStringList(CommentString) + + for CommentLine in CommentList: + CommentString = GetHelpStringByRemoveHashKey(CommentLine) + CommentItemIns = InfPcdItemCommentContent() + CommentItemIns.SetHelpStringItem(CommentString) + CommentItemIns.SetUsageItem(CommentString) + PcdItemObj.SetHelpStringList(PcdItemObj.GetHelpStringList() + [CommentItemIns]) + if PcdItemObj.GetValidUsage(): + PcdItemObj.SetValidUsage(PcdItemObj.GetValidUsage() + DT.TAB_VALUE_SPLIT + CommentString) + else: + PcdItemObj.SetValidUsage(CommentString) + PcdItemObj.SetItemType(KeysList[0][0]) # # Set PcdTokenSpaceCName and CName # - PcdItemObj = SetPcdName(PcdItem, CurrentLineOfPcdItem, PcdItemObj) + PcdItemObj = SetPcdName(PcdItem, CurrentLineOfPcdItem, PcdItemObj) # - # Set Value/DatumType/MaxDatumSize/Token + # Set Value/DatumType/OffSet/Token # - PcdItemObj = SetValueDatumTypeMaxSizeToken(PcdItem, - CurrentLineOfPcdItem, + PcdItemObj = SetValueDatumTypeMaxSizeToken(PcdItem, + CurrentLineOfPcdItem, PcdItemObj, KeysList[0][1], PackageInfo) - + PcdTypeItem = KeysList[0][0] - if self.Pcds.has_key((PcdTypeItem, PcdItemObj)): + if self.Pcds.has_key((PcdTypeItem, PcdItemObj)): PcdsList = self.Pcds[PcdTypeItem, PcdItemObj] PcdsList.append(PcdItemObj) self.Pcds[PcdTypeItem, PcdItemObj] = PcdsList else: PcdsList = [] PcdsList.append(PcdItemObj) - self.Pcds[PcdTypeItem, PcdItemObj] = PcdsList - + self.Pcds[PcdTypeItem, PcdItemObj] = PcdsList + def GetPcds(self): return self.Pcds def ParserPcdInfoInDec(String): ValueList = GetSplitValueList(String, DT.TAB_VALUE_SPLIT, 3) - + # # DatumType, Token # return ValueList[2], ValueList[3] -def SetValueDatumTypeMaxSizeToken(PcdItem, CurrentLineOfPcdItem, PcdItemObj, Arch, PackageInfo = None): +def SetValueDatumTypeMaxSizeToken(PcdItem, CurrentLineOfPcdItem, PcdItemObj, Arch, PackageInfo=None): # # Package information not been generated currently, we need to parser INF file to get information. # @@ -484,8 +498,14 @@ def SetValueDatumTypeMaxSizeToken(PcdItem, CurrentLineOfPcdItem, PcdItemObj, Arc # Open DEC file to get information # FullFileName = os.path.normpath(os.path.realpath(os.path.join(GlobalData.gWORKSPACE, PackageName))) - - DecParser = Dec(FullFileName) + + DecParser = None + if FullFileName not in GlobalData.gPackageDict: + DecParser = Dec(FullFileName) + GlobalData.gPackageDict[FullFileName] = DecParser + else: + DecParser = GlobalData.gPackageDict[FullFileName] + # # Find PCD information. # @@ -499,7 +519,8 @@ def SetValueDatumTypeMaxSizeToken(PcdItem, CurrentLineOfPcdItem, PcdItemObj, Arc PcdItemObj.SetToken(PcdInDec.TokenValue) PcdItemObj.SetDatumType(PcdInDec.DatumType) PcdItemObj.SetSupportArchList([Arch]) - + PcdItemObj.SetDefaultValue(PcdInDec.DefaultValue) + if (Key[0] == 'PCDSPATCHABLEINMODULE' and PcdItemObj.GetItemType() == 'PatchPcd') and \ (Key[1] == 'COMMON' or Key[1] == Arch): for PcdInDec in DecPcdsDict[Key]: @@ -507,11 +528,12 @@ def SetValueDatumTypeMaxSizeToken(PcdItem, CurrentLineOfPcdItem, PcdItemObj, Arc PcdInDec.TokenSpaceGuidCName == PcdItemObj.TokenSpaceGuidCName: PcdItemObj.SetToken(PcdInDec.TokenValue) PcdItemObj.SetDatumType(PcdInDec.DatumType) - PcdItemObj.SetSupportArchList([Arch]) - + PcdItemObj.SetSupportArchList([Arch]) + if PcdItemObj.GetDatumType() == 'VOID*': - PcdItemObj.SetMaxDatumSize('%s'%(len(GetSplitValueList(PcdItem[1], DT.TAB_COMMA_SPLIT)))) - + if len(PcdItem) > 1: + PcdItemObj.SetMaxDatumSize('%s' % (len(GetSplitValueList(PcdItem[1], DT.TAB_COMMA_SPLIT)))) + DecGuidsDict = DecParser.GetGuidSectionObject().ValueDict for Key in DecGuidsDict.keys(): if Key == 'COMMON' or Key == Arch: @@ -519,51 +541,64 @@ def SetValueDatumTypeMaxSizeToken(PcdItem, CurrentLineOfPcdItem, PcdItemObj, Arc if GuidInDec.GuidCName == PcdItemObj.TokenSpaceGuidCName: PcdItemObj.SetTokenSpaceGuidValue(GuidInDec.GuidString) - # - # Validate Value. - # - if ValidatePcdValueOnDatumType(PcdItem[1], PcdItemObj.GetDatumType()): - PcdItemObj.SetDefaultValue(PcdItem[1]) - else: - Logger.Error("InfParser", - ToolError.FORMAT_INVALID, - ST.ERR_ASBUILD_PCD_VALUE_INVALID%("\"" + PcdItem[1] + "\"", "\"" + - PcdItemObj.GetDatumType() + "\""), - File=CurrentLineOfPcdItem[2], - Line=CurrentLineOfPcdItem[1], - ExtraData=CurrentLineOfPcdItem[0]) - # - # validate offset - # if PcdItemObj.GetItemType().upper() == DT.TAB_INF_PATCH_PCD.upper(): - if not IsHexDigitUINT32(PcdItem[2]): - Logger.Error("InfParser", - ToolError.FORMAT_INVALID, - ST.ERR_ASBUILD_PCD_OFFSET_FORMAT_INVALID%("\"" + PcdItem[2] + "\""), - File=CurrentLineOfPcdItem[2], - Line=CurrentLineOfPcdItem[1], - ExtraData=CurrentLineOfPcdItem[0]) - PcdItemObj.SetOffset(PcdItem[2]) - + # + # Validate Value. + # + # convert the value from a decimal 0 to a formatted hex value. + if PcdItem[1] == "0": + DatumType = PcdItemObj.GetDatumType() + if DatumType == "UINT8": + PcdItem[1] = "0x00" + if DatumType == "UINT16": + PcdItem[1] = "0x0000" + if DatumType == "UINT32": + PcdItem[1] = "0x00000000" + if DatumType == "UINT64": + PcdItem[1] = "0x0000000000000000" + + if ValidatePcdValueOnDatumType(PcdItem[1], PcdItemObj.GetDatumType()): + PcdItemObj.SetDefaultValue(PcdItem[1]) + else: + Logger.Error("InfParser", + ToolError.FORMAT_INVALID, + ST.ERR_ASBUILD_PCD_VALUE_INVALID % ("\"" + PcdItem[1] + "\"", "\"" + + PcdItemObj.GetDatumType() + "\""), + File=CurrentLineOfPcdItem[2], + Line=CurrentLineOfPcdItem[1], + ExtraData=CurrentLineOfPcdItem[0]) + # + # validate offset + # + if PcdItemObj.GetItemType().upper() == DT.TAB_INF_PATCH_PCD.upper(): + if not IsHexDigitUINT32(PcdItem[2]): + Logger.Error("InfParser", + ToolError.FORMAT_INVALID, + ST.ERR_ASBUILD_PCD_OFFSET_FORMAT_INVALID % ("\"" + PcdItem[2] + "\""), + File=CurrentLineOfPcdItem[2], + Line=CurrentLineOfPcdItem[1], + ExtraData=CurrentLineOfPcdItem[0]) + PcdItemObj.SetOffset(PcdItem[2]) + if PcdItemObj.GetToken() == '' or PcdItemObj.GetDatumType() == '': - Logger.Error("InfParser", - ToolError.FORMAT_INVALID, - ST.ERR_ASBUILD_PCD_DECLARITION_MISS%("\"" + PcdItem[0] + "\""), - File=CurrentLineOfPcdItem[2], - Line=CurrentLineOfPcdItem[1], + Logger.Error("InfParser", + ToolError.FORMAT_INVALID, + ST.ERR_ASBUILD_PCD_DECLARITION_MISS % ("\"" + PcdItem[0] + "\""), + File=CurrentLineOfPcdItem[2], + Line=CurrentLineOfPcdItem[1], ExtraData=CurrentLineOfPcdItem[0]) - + return PcdItemObj def ValidatePcdValueOnDatumType(Value, Type): - + Value = Value.strip() # # Boolean type only allow 0x00 or 0x01 as value per INF spec # if Type == 'BOOLEAN': if not (Value == '0x00' or Value == '0x01'): - return False + return False elif Type == 'VOID*': if not Value.startswith("{"): return False @@ -572,23 +607,23 @@ def ValidatePcdValueOnDatumType(Value, Type): # # Strip "{" at head and "}" at tail. # - Value = Value[1:-1] + Value = Value[1:-1] ValueList = GetSplitValueList(Value, DT.TAB_COMMA_SPLIT) - + ReIsValidHexByte = re.compile("^0x[0-9a-f]{1,2}$", re.IGNORECASE) for ValueItem in ValueList: if not ReIsValidHexByte.match(ValueItem): return False - + elif Type == 'UINT8' or Type == 'UINT16' or Type == 'UINT32' or Type == 'UINT64': - + ReIsValidUint8z = re.compile('^0[x|X][a-fA-F0-9]{2}$') ReIsValidUint16z = re.compile('^0[x|X][a-fA-F0-9]{4}$') ReIsValidUint32z = re.compile('^0[x|X][a-fA-F0-9]{8}$') ReIsValidUint64z = re.compile('^0[x|X][a-fA-F0-9]{16}$') - + if not ReIsValidUint8z.match(Value) and Type == 'UINT8': - return False + return False elif not ReIsValidUint16z.match(Value) and Type == 'UINT16': return False elif not ReIsValidUint32z.match(Value) and Type == 'UINT32': @@ -600,41 +635,41 @@ def ValidatePcdValueOnDatumType(Value, Type): # Since we assume the DEC file always correct, should never go to here. # pass - - return True - + + return True + def SetPcdName(PcdItem, CurrentLineOfPcdItem, PcdItemObj): # # Only PCD Name specified # ::= "." # PcdId = GetSplitValueList(PcdItem[0], DT.TAB_SPLIT) - if len(PcdId) != 2: - Logger.Error("InfParser", - ToolError.FORMAT_INVALID, + if len(PcdId) != 2: + Logger.Error("InfParser", + ToolError.FORMAT_INVALID, ST.ERR_INF_PARSER_PCD_NAME_FORMAT_ERROR, - File=CurrentLineOfPcdItem[2], - Line=CurrentLineOfPcdItem[1], + File=CurrentLineOfPcdItem[2], + Line=CurrentLineOfPcdItem[1], ExtraData=CurrentLineOfPcdItem[0]) else: # # Validate PcdTokenSpaceGuidCName # if not IsValidCVariableName(PcdId[0]): - Logger.Error("InfParser", - ToolError.FORMAT_INVALID, + Logger.Error("InfParser", + ToolError.FORMAT_INVALID, ST.ERR_INF_PARSER_PCD_CVAR_GUID, - File=CurrentLineOfPcdItem[2], - Line=CurrentLineOfPcdItem[1], + File=CurrentLineOfPcdItem[2], + Line=CurrentLineOfPcdItem[1], ExtraData=PcdId[0]) if not IsValidCVariableName(PcdId[1]): - Logger.Error("InfParser", - ToolError.FORMAT_INVALID, + Logger.Error("InfParser", + ToolError.FORMAT_INVALID, ST.ERR_INF_PARSER_PCD_CVAR_PCDCNAME, - File=CurrentLineOfPcdItem[2], - Line=CurrentLineOfPcdItem[1], + File=CurrentLineOfPcdItem[2], + Line=CurrentLineOfPcdItem[1], ExtraData=PcdId[1]) PcdItemObj.SetTokenSpaceGuidCName(PcdId[0]) PcdItemObj.SetCName(PcdId[1]) - - return PcdItemObj \ No newline at end of file + + return PcdItemObj diff --git a/BaseTools/Source/Python/UPT/Parser/DecParser.py b/BaseTools/Source/Python/UPT/Parser/DecParser.py index 060b9274f3..25407f9a2d 100644 --- a/BaseTools/Source/Python/UPT/Parser/DecParser.py +++ b/BaseTools/Source/Python/UPT/Parser/DecParser.py @@ -1,7 +1,7 @@ ## @file # This file is used to parse DEC file. It will consumed by DecParser # -# Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -60,6 +60,7 @@ from Library.String import ReplaceMacro from Library.String import GetSplitValueList from Library.String import gMACRO_PATTERN from Library.String import ConvertSpecialChar +from Library.CommentParsing import ParsePcdErrorCode ## # _DecBase class for parsing @@ -77,6 +78,9 @@ class _DecBase: def GetDataObject(self): return self.ItemObject + def GetLocalMacro(self): + return self._LocalMacro + ## BlockStart # # Called if a new section starts @@ -184,7 +188,7 @@ class _DecBase: self._LocalMacro[TokenList[0]] = '' else: self._LocalMacro[TokenList[0]] = self._ReplaceMacro(TokenList[1]) - + ## _ParseItem # # Parse specified item, this function must be derived by subclass @@ -395,6 +399,7 @@ class _DecDefine(_DecBase): DT.TAB_DEC_DEFINES_PACKAGE_NAME : self._SetPackageName, DT.TAB_DEC_DEFINES_PACKAGE_GUID : self._SetPackageGuid, DT.TAB_DEC_DEFINES_PACKAGE_VERSION : self._SetPackageVersion, + DT.TAB_DEC_DEFINES_PKG_UNI_FILE : self._SetPackageUni, } def BlockStart(self): @@ -429,7 +434,7 @@ class _DecDefine(_DecBase): Line = self._RawData.CurrentLine TokenList = GetSplitValueList(Line, DT.TAB_EQUAL_SPLIT, 1) if TokenList[0] == DT.TAB_DEC_DEFINES_PKG_UNI_FILE: - pass + self.DefineValidation[TokenList[0]](TokenList[1]) elif len(TokenList) < 2: self._LoggerError(ST.ERR_DECPARSE_DEFINE_FORMAT) elif TokenList[0] not in self.DefineValidation: @@ -438,10 +443,9 @@ class _DecDefine(_DecBase): self.DefineValidation[TokenList[0]](TokenList[1]) DefineItem = DecDefineItemObject() - if TokenList[0] != DT.TAB_DEC_DEFINES_PKG_UNI_FILE: - DefineItem.Key = TokenList[0] - DefineItem.Value = TokenList[1] - self.ItemObject.AddItem(DefineItem, self._RawData.CurrentScope) + DefineItem.Key = TokenList[0] + DefineItem.Value = TokenList[1] + self.ItemObject.AddItem(DefineItem, self._RawData.CurrentScope) return DefineItem def _SetDecSpecification(self, Token): @@ -473,7 +477,12 @@ class _DecDefine(_DecBase): else: if not DT.TAB_SPLIT in Token: Token = Token + '.0' - self.ItemObject._PkgVersion = Token + self.ItemObject.SetPackageVersion(Token) + + def _SetPackageUni(self, Token): + if self.ItemObject.GetPackageUniFile(): + self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PKG_UNI_FILE) + self.ItemObject.SetPackageUniFile(Token) ## _DecInclude # @@ -727,7 +736,7 @@ class _DecUserExtension(_DecBase): class Dec(_DecBase, _DecComments): def __init__(self, DecFile, Parse = True): try: - Content = ConvertSpecialChar(open(DecFile, 'rb').readlines()) + Content = ConvertSpecialChar(open(DecFile, 'rb').readlines()) except BaseException: Logger.Error(TOOL_NAME, FILE_OPEN_FAILURE, File=DecFile, ExtraData=ST.ERR_DECPARSE_FILEOPEN % DecFile) @@ -736,7 +745,9 @@ class Dec(_DecBase, _DecComments): _DecComments.__init__(self) _DecBase.__init__(self, RawData) - self.BinaryHeadComment = [] + self.BinaryHeadComment = [] + self.PcdErrorCommentDict = {} + self._Define = _DecDefine(RawData) self._Include = _DecInclude(RawData) self._Guid = _DecGuid(RawData) @@ -775,7 +786,7 @@ class Dec(_DecBase, _DecComments): if not SectionParser.CheckRequiredFields(): return False return True - + ## # Parse DEC file # @@ -784,9 +795,47 @@ class Dec(_DecBase, _DecComments): IsBinaryHeader = False FileHeaderLineIndex = -1 BinaryHeaderLineIndex = -1 + TokenSpaceGuidCName = '' + + # + # Parse PCD error comment section + # while not self._RawData.IsEndOfFile(): - Line, Comment = CleanString(self._RawData.GetNextLine()) + self._RawData.CurrentLine = self._RawData.GetNextLine() + if self._RawData.CurrentLine.startswith(DT.TAB_COMMENT_SPLIT) and \ + DT.TAB_SECTION_START in self._RawData.CurrentLine and \ + DT.TAB_SECTION_END in self._RawData.CurrentLine: + self._RawData.CurrentLine = self._RawData.CurrentLine.replace(DT.TAB_COMMENT_SPLIT, '').strip() + if self._RawData.CurrentLine[0] == DT.TAB_SECTION_START and \ + self._RawData.CurrentLine[-1] == DT.TAB_SECTION_END: + RawSection = self._RawData.CurrentLine[1:-1].strip() + if RawSection.upper().startswith(DT.TAB_PCD_ERROR.upper()+'.'): + TokenSpaceGuidCName = RawSection.split(DT.TAB_PCD_ERROR+'.')[1].strip() + continue + + if TokenSpaceGuidCName and self._RawData.CurrentLine.startswith(DT.TAB_COMMENT_SPLIT): + self._RawData.CurrentLine = self._RawData.CurrentLine.replace(DT.TAB_COMMENT_SPLIT, '').strip() + if self._RawData.CurrentLine != '': + if DT.TAB_VALUE_SPLIT not in self._RawData.CurrentLine: + self._LoggerError(ST.ERR_DECPARSE_PCDERRORMSG_MISS_VALUE_SPLIT) + + PcdErrorNumber, PcdErrorMsg = GetSplitValueList(self._RawData.CurrentLine, DT.TAB_VALUE_SPLIT, 1) + PcdErrorNumber = ParsePcdErrorCode(PcdErrorNumber, self._RawData.Filename, self._RawData.LineIndex) + if not PcdErrorMsg.strip(): + self._LoggerError(ST.ERR_DECPARSE_PCD_MISS_ERRORMSG) + + self.PcdErrorCommentDict[(TokenSpaceGuidCName, PcdErrorNumber)] = PcdErrorMsg.strip() + else: + TokenSpaceGuidCName = '' + + self._RawData.LineIndex = 0 + self._RawData.CurrentLine = '' + self._RawData.NextLine = '' + + while not self._RawData.IsEndOfFile(): + Line, Comment = CleanString(self._RawData.GetNextLine()) + # # Header must be pure comment # @@ -840,9 +889,10 @@ class Dec(_DecBase, _DecComments): self._LoggerError(ST.ERR_BINARY_HEADER_ORDER) if FileHeaderLineIndex == -1: +# self._LoggerError(ST.ERR_NO_SOURCE_HEADER) Logger.Error(TOOL_NAME, FORMAT_INVALID, ST.ERR_NO_SOURCE_HEADER, - File=self._RawData.Filename) + File=self._RawData.Filename) return def _StopCurrentParsing(self, Line): @@ -852,19 +902,15 @@ class Dec(_DecBase, _DecComments): self._SectionHeaderParser() if len(self._RawData.CurrentScope) == 0: self._LoggerError(ST.ERR_DECPARSE_SECTION_EMPTY) - SectionObj = self._SectionParser[self._RawData.CurrentScope[0][0]] - SectionObj.BlockStart() SectionObj.Parse() - return SectionObj.GetDataObject() def _UserExtentionSectionParser(self): self._RawData.CurrentScope = [] ArchList = set() Section = self._RawData.CurrentLine[1:-1] - Par = ParserHelper(Section, self._RawData.Filename) while not Par.End(): # @@ -874,8 +920,8 @@ class Dec(_DecBase, _DecComments): if Token.upper() != DT.TAB_USER_EXTENSIONS.upper(): self._LoggerError(ST.ERR_DECPARSE_SECTION_UE) UserExtension = Token.upper() - - Par.AssertChar(DT.TAB_SPLIT, ST.ERR_DECPARSE_SECTION_UE, self._RawData.LineIndex) + Par.AssertChar(DT.TAB_SPLIT, ST.ERR_DECPARSE_SECTION_UE, self._RawData.LineIndex) + # # UserID # @@ -883,7 +929,6 @@ class Dec(_DecBase, _DecComments): if not IsValidUserId(Token): self._LoggerError(ST.ERR_DECPARSE_SECTION_UE_USERID) UserId = Token - Par.AssertChar(DT.TAB_SPLIT, ST.ERR_DECPARSE_SECTION_UE, self._RawData.LineIndex) # # IdString @@ -892,7 +937,6 @@ class Dec(_DecBase, _DecComments): if not IsValidIdString(Token): self._LoggerError(ST.ERR_DECPARSE_SECTION_UE_IDSTRING) IdString = Token - Arch = 'COMMON' if Par.Expect(DT.TAB_SPLIT): Token = Par.GetToken() @@ -900,20 +944,16 @@ class Dec(_DecBase, _DecComments): if not IsValidArch(Arch): self._LoggerError(ST.ERR_DECPARSE_ARCH) ArchList.add(Arch) - if [UserExtension, UserId, IdString, Arch] not in \ self._RawData.CurrentScope: self._RawData.CurrentScope.append( [UserExtension, UserId, IdString, Arch] ) - if not Par.Expect(DT.TAB_COMMA_SPLIT): break elif Par.End(): self._LoggerError(ST.ERR_DECPARSE_SECTION_COMMA) - Par.AssertEnd(ST.ERR_DECPARSE_SECTION_UE, self._RawData.LineIndex) - if 'COMMON' in ArchList and len(ArchList) > 1: self._LoggerError(ST.ERR_DECPARSE_SECTION_COMMON) @@ -928,7 +968,6 @@ class Dec(_DecBase, _DecComments): self._LoggerError(ST.ERR_DECPARSE_SECTION_IDENTIFY) RawSection = self._RawData.CurrentLine[1:-1].strip().upper() - # # Check defines section which is only allowed to occur once and # no arch can be followed @@ -936,13 +975,11 @@ class Dec(_DecBase, _DecComments): if RawSection.startswith(DT.TAB_DEC_DEFINES.upper()): if RawSection != DT.TAB_DEC_DEFINES.upper(): self._LoggerError(ST.ERR_DECPARSE_DEFINE_SECNAME) - # # Check user extension section # if RawSection.startswith(DT.TAB_USER_EXTENSIONS.upper()): return self._UserExtentionSectionParser() - self._RawData.CurrentScope = [] SectionNames = [] ArchList = set() @@ -951,17 +988,14 @@ class Dec(_DecBase, _DecComments): self._LoggerError(ST.ERR_DECPARSE_SECTION_SUBEMPTY % self._RawData.CurrentLine) ItemList = GetSplitValueList(Item, DT.TAB_SPLIT) - # # different types of PCD are permissible in one section # SectionName = ItemList[0] if SectionName not in self._SectionParser: self._LoggerError(ST.ERR_DECPARSE_SECTION_UNKNOW % SectionName) - if SectionName not in SectionNames: SectionNames.append(SectionName) - # # In DEC specification, all section headers have at most two part: # SectionName.Arch except UserExtention @@ -989,7 +1023,6 @@ class Dec(_DecBase, _DecComments): # if 'COMMON' in ArchList and len(ArchList) > 1: self._LoggerError(ST.ERR_DECPARSE_SECTION_COMMON) - if len(SectionNames) == 0: self._LoggerError(ST.ERR_DECPARSE_SECTION_SUBEMPTY % self._RawData.CurrentLine) if len(SectionNames) != 1: @@ -997,41 +1030,31 @@ class Dec(_DecBase, _DecComments): if not Sec.startswith(DT.TAB_PCDS.upper()): self._LoggerError(ST.ERR_DECPARSE_SECTION_NAME % str(SectionNames)) + def GetDefineSectionMacro(self): + return self._Define.GetLocalMacro() def GetDefineSectionObject(self): return self._Define.GetDataObject() - def GetIncludeSectionObject(self): return self._Include.GetDataObject() - def GetGuidSectionObject(self): return self._Guid.GetGuidObject() - def GetProtocolSectionObject(self): return self._Guid.GetProtocolObject() - def GetPpiSectionObject(self): return self._Guid.GetPpiObject() - def GetLibraryClassSectionObject(self): return self._LibClass.GetDataObject() - def GetPcdSectionObject(self): return self._Pcd.GetDataObject() - def GetUserExtensionSectionObject(self): return self._UserEx.GetDataObject() - def GetPackageSpecification(self): - return self._Define.GetDataObject().GetPackageSpecification() - + return self._Define.GetDataObject().GetPackageSpecification() def GetPackageName(self): - return self._Define.GetDataObject().GetPackageName() - + return self._Define.GetDataObject().GetPackageName() def GetPackageGuid(self): - return self._Define.GetDataObject().GetPackageGuid() - + return self._Define.GetDataObject().GetPackageGuid() def GetPackageVersion(self): return self._Define.GetDataObject().GetPackageVersion() - def GetPackageUniFile(self): return self._Define.GetDataObject().GetPackageUniFile() diff --git a/BaseTools/Source/Python/UPT/Parser/DecParserMisc.py b/BaseTools/Source/Python/UPT/Parser/DecParserMisc.py index 8d28979393..22a50680fb 100644 --- a/BaseTools/Source/Python/UPT/Parser/DecParserMisc.py +++ b/BaseTools/Source/Python/UPT/Parser/DecParserMisc.py @@ -1,7 +1,7 @@ ## @file # This file is used to define helper class and function for DEC parser # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -25,6 +25,7 @@ from Library.DataType import TAB_COMMENT_SPLIT from Library.DataType import TAB_COMMENT_EDK1_SPLIT from Library.ExpressionValidate import IsValidBareCString from Library.ParserValidate import IsValidCFormatGuid +from Library.ExpressionValidate import IsValidFeatureFlagExp from Library.ExpressionValidate import IsValidLogicalExpr from Library.ExpressionValidate import IsValidStringTest from Library.Misc import CheckGuidRegFormat @@ -134,26 +135,38 @@ def CleanString(Line, CommentCharacter=TAB_COMMENT_SPLIT, \ return Line, Comment -## IsValidHexByte +## IsValidNumValUint8 # -# Check if Token is HexByte: ::= 0x {1,2} +# Check if Token is NumValUint8: ::= {} {} {} # # @param Token: Token to be checked # -def IsValidHexByte(Token): +def IsValidNumValUint8(Token): + Valid = True + Cause = "" + TokenValue = None Token = Token.strip() - if not Token.lower().startswith('0x') or not (len(Token) < 5 and len(Token) > 2): - return False + if Token.lower().startswith('0x'): + Base = 16 + else: + Base = 10 try: - Token = long(Token, 0) + TokenValue = long(Token, Base) except BaseException: + Valid, Cause = IsValidLogicalExpr(Token, True) + if Cause: + pass + if not Valid: return False - return True + if TokenValue and (TokenValue < 0 or TokenValue > 0xFF): + return False + else: + return True ## IsValidNList # -# Check if Value has the format of ["," ]{0,} -# ::= "0x" {1,2} +# Check if Value has the format of ["," ]{0,} +# ::= {} {} {} # # @param Value: Value to be checked # @@ -162,8 +175,8 @@ def IsValidNList(Value): if Par.End(): return False while not Par.End(): - Token = Par.GetToken(',\t ') - if not IsValidHexByte(Token): + Token = Par.GetToken(',') + if not IsValidNumValUint8(Token): return False if Par.Expect(','): if Par.End(): @@ -186,11 +199,11 @@ def IsValidCArray(Array): if Par.End(): return False while not Par.End(): - Token = Par.GetToken(',}\t ') + Token = Par.GetToken(',}') # - # 0xa, 0xaa + # ShortNum, UINT8, Expression # - if not IsValidHexByte(Token): + if not IsValidNumValUint8(Token): return False if Par.Expect(','): if Par.End(): @@ -213,6 +226,10 @@ def IsValidCArray(Array): # @param Value: The pcd Value # def IsValidPcdDatum(Type, Value): + if not Value: + return False, ST.ERR_DECPARSE_PCD_VALUE_EMPTY + Valid = True + Cause = "" if Type not in ["UINT8", "UINT16", "UINT32", "UINT64", "VOID*", "BOOLEAN"]: return False, ST.ERR_DECPARSE_PCD_TYPE if Type == "VOID*": @@ -230,9 +247,9 @@ def IsValidPcdDatum(Type, Value): if Value in ['TRUE', 'FALSE', 'true', 'false', 'True', 'False', '0x1', '0x01', '1', '0x0', '0x00', '0']: return True, "" - Valid, Cause = IsValidStringTest(Value) + Valid, Cause = IsValidStringTest(Value, True) if not Valid: - Valid, Cause = IsValidLogicalExpr(Value) + Valid, Cause = IsValidFeatureFlagExp(Value, True) if not Valid: return False, Cause else: @@ -271,8 +288,10 @@ def IsValidPcdDatum(Type, Value): if TypeLenMap[Type] < len(HexStr) - 3: return False, ST.ERR_DECPARSE_PCD_INT_EXCEED % (StrVal, Type) except BaseException: - return False, ST.ERR_DECPARSE_PCD_INT % (Value, Type) - + Valid, Cause = IsValidLogicalExpr(Value, True) + if not Valid: + return False, Cause + return True, "" ## ParserHelper diff --git a/BaseTools/Source/Python/UPT/Parser/InfAsBuiltProcess.py b/BaseTools/Source/Python/UPT/Parser/InfAsBuiltProcess.py index 6bf070be41..498f2d7634 100644 --- a/BaseTools/Source/Python/UPT/Parser/InfAsBuiltProcess.py +++ b/BaseTools/Source/Python/UPT/Parser/InfAsBuiltProcess.py @@ -1,7 +1,7 @@ ## @file # This file is used to provide method for process AsBuilt INF file. It will consumed by InfParser # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -19,7 +19,6 @@ InfAsBuiltProcess import os import re from Library import GlobalData - import Logger.Log as Logger from Logger import StringTable as ST from Logger import ToolError @@ -74,7 +73,7 @@ def GetLibInstanceInfo(String, WorkSpace, LineNo, CurrentInfFileName): if VersionMatchedObj: Guid = GuidMatchedObj.group().strip() Version = VersionMatchedObj.group().strip() - return GetGuidVerFormLibInstance(Guid, Version, WorkSpace, CurrentInfFileName) + return Guid, Version # # To deal with library instance specified by file name @@ -106,47 +105,47 @@ def GetLibInstanceInfo(String, WorkSpace, LineNo, CurrentInfFileName): # @param WorkSpace. The WorkSpace directory used to combined with INF file path. # # @return GUID, Version -def GetPackageListInfo(FileNameString, WorkSpace, LineNo): +def GetPackageListInfo(FileNameString, WorkSpace, LineNo): PackageInfoList = [] DefineSectionMacros = {} PackageSectionMacros = {} - + FileLinesList = GetFileLineContent(FileNameString, WorkSpace, LineNo, '') - + RePackageHeader = re.compile('^\s*\[Packages.*\].*$') ReDefineHeader = re.compile('^\s*\[Defines].*$') - + PackageHederFlag = False DefineHeaderFlag = False LineNo = -1 for Line in FileLinesList: LineNo += 1 Line = Line.strip() - + if Line.startswith('['): PackageHederFlag = False - DefineHeaderFlag = False - + DefineHeaderFlag = False + if Line.startswith("#"): continue - + if not Line: - continue - + continue + # # Found [Packages] section # if RePackageHeader.match(Line): PackageHederFlag = True continue - + # # Found [Define] section # if ReDefineHeader.match(Line): DefineHeaderFlag = True continue - + if DefineHeaderFlag: # # Find Macro @@ -154,12 +153,12 @@ def GetPackageListInfo(FileNameString, WorkSpace, LineNo): Name, Value = MacroParser((Line, LineNo), FileNameString, DT.MODEL_META_DATA_HEADER, - DefineSectionMacros) - + DefineSectionMacros) + if Name != None: - DefineSectionMacros[Name] = Value + DefineSectionMacros[Name] = Value continue - + if PackageHederFlag: # @@ -170,22 +169,22 @@ def GetPackageListInfo(FileNameString, WorkSpace, LineNo): DT.MODEL_META_DATA_PACKAGE, DefineSectionMacros) if Name != None: - PackageSectionMacros[Name] = Value + PackageSectionMacros[Name] = Value continue - + # # Replace with Local section Macro and [Defines] section Macro. # Line = InfExpandMacro(Line, (FileNameString, Line, LineNo), DefineSectionMacros, PackageSectionMacros, True) - + Line = GetSplitValueList(Line, "#", 1)[0] Line = GetSplitValueList(Line, "|", 1)[0] PackageInfoList.append(Line) - - return PackageInfoList - + + return PackageInfoList + def GetFileLineContent(FileName, WorkSpace, LineNo, OriginalString): - + if not LineNo: LineNo = -1 @@ -194,26 +193,16 @@ def GetFileLineContent(FileName, WorkSpace, LineNo, OriginalString): # FullFileName = os.path.normpath(os.path.realpath(os.path.join(WorkSpace, FileName))) if not (ValidFile(FullFileName)): - Logger.Error("InfParser", - ToolError.FORMAT_INVALID, - ST.ERR_FILELIST_EXIST%(FileName), - File=GlobalData.gINF_MODULE_NAME, - Line=LineNo, - ExtraData=OriginalString) - + return [] + # # Validate file exist/format. # if not IsValidPath(FileName, WorkSpace): - Logger.Error("InfParser", - ToolError.FORMAT_INVALID, - ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID%(FileName), - File=GlobalData.gINF_MODULE_NAME, - Line=LineNo, - ExtraData=OriginalString) - + return [] + FileLinesList = [] - + try: FullFileName = FullFileName.replace('\\', '/') Inputfile = open(FullFileName, "rb", 0) @@ -228,9 +217,9 @@ def GetFileLineContent(FileName, WorkSpace, LineNo, OriginalString): ToolError.FILE_READ_FAILURE, ST.ERR_FILE_OPEN_FAILURE, File=FullFileName) - + FileLinesList = ProcessLineExtender(FileLinesList) - + return FileLinesList ## diff --git a/BaseTools/Source/Python/UPT/Parser/InfBinarySectionParser.py b/BaseTools/Source/Python/UPT/Parser/InfBinarySectionParser.py index 36142cf84a..f1d6943cbf 100644 --- a/BaseTools/Source/Python/UPT/Parser/InfBinarySectionParser.py +++ b/BaseTools/Source/Python/UPT/Parser/InfBinarySectionParser.py @@ -1,7 +1,7 @@ ## @file # This file contained the parser for [Binaries] sections in INF file # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -178,9 +178,15 @@ class InfBinarySectionParser(InfParserSectionRoot): CurrentLineObj)) else: if len(ValueList) == 2: - TokenList = GetSplitValueList(ValueList[1], - DT.TAB_VALUE_SPLIT, - 4) + if ValueList[0].strip() == 'SUBTYPE_GUID': + TokenList = GetSplitValueList(ValueList[1], + DT.TAB_VALUE_SPLIT, + 5) + else: + TokenList = GetSplitValueList(ValueList[1], + DT.TAB_VALUE_SPLIT, + 4) + NewValueList = [] NewValueList.append(ValueList[0]) for Item in TokenList: @@ -188,6 +194,15 @@ class InfBinarySectionParser(InfParserSectionRoot): ComBinaryList.append((NewValueList, LineComment, CurrentLineObj)) + elif len(ValueList) == 1: + NewValueList = [] + NewValueList.append(ValueList[0]) + ComBinaryList.append((NewValueList, + LineComment, + CurrentLineObj)) + + + ValueList = [] LineComment = None diff --git a/BaseTools/Source/Python/UPT/Parser/InfLibrarySectionParser.py b/BaseTools/Source/Python/UPT/Parser/InfLibrarySectionParser.py index 4540fe2754..210f973f1a 100644 --- a/BaseTools/Source/Python/UPT/Parser/InfLibrarySectionParser.py +++ b/BaseTools/Source/Python/UPT/Parser/InfLibrarySectionParser.py @@ -1,7 +1,7 @@ ## @file # This file contained the parser for [Libraries] sections in INF file # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -44,21 +44,21 @@ class InfLibrarySectionParser(InfParserSectionRoot): # Macro defined in this section # SectionMacros = {} - ValueList = [] - LibraryList = [] - LibStillCommentFalg = False - LibHeaderComments = [] - LibLineComment = None + ValueList = [] + LibraryList = [] + LibStillCommentFalg = False + LibHeaderComments = [] + LibLineComment = None # # Parse section content # for Line in SectionString: LibLineContent = Line[0] - LibLineNo = Line[1] - + LibLineNo = Line[1] + if LibLineContent.strip() == '': continue - + # # Found Header Comments # @@ -82,14 +82,14 @@ class InfLibrarySectionParser(InfParserSectionRoot): continue else: LibStillCommentFalg = False - + if len(LibHeaderComments) >= 1: LibLineComment = InfLineCommentObject() LineCommentContent = '' for Item in LibHeaderComments: LineCommentContent += Item[0] + DT.END_OF_LINE LibLineComment.SetHeaderComments(LineCommentContent) - + # # Find Tail comment. # @@ -98,8 +98,8 @@ class InfLibrarySectionParser(InfParserSectionRoot): LibLineContent = LibLineContent[:LibLineContent.find(DT.TAB_COMMENT_SPLIT)] if LibLineComment == None: LibLineComment = InfLineCommentObject() - LibLineComment.SetTailComments(LibTailComments) - + LibLineComment.SetTailComments(LibTailComments) + # # Find Macro # @@ -110,28 +110,28 @@ class InfLibrarySectionParser(InfParserSectionRoot): if Name != None: SectionMacros[Name] = Value LibLineComment = None - LibHeaderComments = [] + LibHeaderComments = [] continue - + TokenList = GetSplitValueList(LibLineContent, DT.TAB_VALUE_SPLIT, 1) ValueList[0:len(TokenList)] = TokenList - + # # Replace with Local section Macro and [Defines] section Macro. # - ValueList = [InfExpandMacro(Value, (FileName, LibLineContent, LibLineNo), + ValueList = [InfExpandMacro(Value, (FileName, LibLineContent, LibLineNo), self.FileLocalMacros, SectionMacros, True) for Value in ValueList] - - LibraryList.append((ValueList, LibLineComment, + + LibraryList.append((ValueList, LibLineComment, (LibLineContent, LibLineNo, FileName))) ValueList = [] LibLineComment = None LibTailComments = '' LibHeaderComments = [] - + continue - + # # Current section archs # @@ -139,36 +139,36 @@ class InfLibrarySectionParser(InfParserSectionRoot): for Item in self.LastSectionHeaderContent: if (Item[1], Item[2]) not in KeyList: KeyList.append((Item[1], Item[2])) - - if not InfSectionObject.SetLibraryClasses(LibraryList, KeyList = KeyList): - Logger.Error('InfParser', + + if not InfSectionObject.SetLibraryClasses(LibraryList, KeyList=KeyList): + Logger.Error('InfParser', FORMAT_INVALID, ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR % ("[Library]"), - File=FileName, + File=FileName, Line=Item[3]) # # For Binary INF # else: self.InfAsBuiltLibraryParser(SectionString, InfSectionObject, FileName) - + def InfAsBuiltLibraryParser(self, SectionString, InfSectionObject, FileName): LibraryList = [] LibInsFlag = False for Line in SectionString: LineContent = Line[0] - LineNo = Line[1] - + LineNo = Line[1] + if LineContent.strip() == '': LibInsFlag = False continue - + if not LineContent.strip().startswith("#"): - Logger.Error('InfParser', + Logger.Error('InfParser', FORMAT_INVALID, - ST.ERR_LIB_CONTATIN_ASBUILD_AND_COMMON, - File=FileName, - Line=LineNo, + ST.ERR_LIB_CONTATIN_ASBUILD_AND_COMMON, + File=FileName, + Line=LineNo, ExtraData=LineContent) if IsLibInstanceInfo(LineContent): @@ -185,13 +185,6 @@ class InfLibrarySectionParser(InfParserSectionRoot): if LibGuid != '': if (LibGuid, LibVer) not in LibraryList: LibraryList.append((LibGuid, LibVer)) - else: - Logger.Error('InfParser', - FORMAT_INVALID, - ST.ERR_LIB_INSTANCE_MISS_GUID, - File=FileName, - Line=LineNo, - ExtraData=LineContent) # # Current section archs @@ -201,10 +194,10 @@ class InfLibrarySectionParser(InfParserSectionRoot): for Item in self.LastSectionHeaderContent: if (Item[1], Item[2]) not in KeyList: KeyList.append((Item[1], Item[2])) - - if not InfSectionObject.SetLibraryClasses(LibraryList, KeyList = KeyList): - Logger.Error('InfParser', + + if not InfSectionObject.SetLibraryClasses(LibraryList, KeyList=KeyList): + Logger.Error('InfParser', FORMAT_INVALID, ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR % ("[Library]"), - File=FileName, - Line=Item[3]) \ No newline at end of file + File=FileName, + Line=Item[3]) diff --git a/BaseTools/Source/Python/UPT/Parser/InfParser.py b/BaseTools/Source/Python/UPT/Parser/InfParser.py index 8a41eca0a7..e7bef2e35e 100644 --- a/BaseTools/Source/Python/UPT/Parser/InfParser.py +++ b/BaseTools/Source/Python/UPT/Parser/InfParser.py @@ -1,7 +1,7 @@ ## @file # This file contained the parser for INF file # -# Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -210,7 +210,7 @@ class InfParser(InfSectionParser): SectionLines.append((Line, LineNo)) HeaderCommentStart = True continue - + # # Collect Header content. # @@ -227,18 +227,18 @@ class InfParser(InfSectionParser): HeaderCommentEnd = True BinaryHeaderCommentStart = False BinaryHeaderCommentEnd = False - HeaderCommentStart = False + HeaderCommentStart = False if Line.find(DT.TAB_BINARY_HEADER_COMMENT) > -1: self.InfHeaderParser(SectionLines, self.InfHeader, self.FileName) SectionLines = [] else: SectionLines.append((Line, LineNo)) - # - # Call Header comment parser. - # - self.InfHeaderParser(SectionLines, self.InfHeader, self.FileName) - SectionLines = [] - continue + # + # Call Header comment parser. + # + self.InfHeaderParser(SectionLines, self.InfHeader, self.FileName) + SectionLines = [] + continue # # check whether binary header comment section started @@ -254,9 +254,9 @@ class InfParser(InfSectionParser): BinaryHeaderStarLineNo = LineNo SectionLines.append((Line, LineNo)) BinaryHeaderCommentStart = True - HeaderCommentEnd = True - continue - + HeaderCommentEnd = True + continue + # # check whether there are more than one binary header exist # @@ -302,12 +302,12 @@ class InfParser(InfSectionParser): SectionLines.append((Line, LineNo)) if not LastSectionFalg: continue - + # # Encountered a section. start with '[' and end with ']' # if (Line.startswith(DT.TAB_SECTION_START) and \ - Line.find(DT.TAB_SECTION_END) > -1) or LastSectionFalg: + Line.find(DT.TAB_SECTION_END) > -1) or LastSectionFalg: HeaderCommentEnd = True BinaryHeaderCommentEnd = True @@ -324,13 +324,13 @@ class InfParser(InfSectionParser): File=self.FullPath, Line=LineNo, ExtraData=Line) - + # # Keep last time section header content for section parser # usage. # self.LastSectionHeaderContent = deepcopy(self.SectionHeaderContent) - + # # TailComments in section define. # @@ -357,11 +357,11 @@ class InfParser(InfSectionParser): # Compare the new section name with current # self.SectionHeaderParser(Line, self.FileName, LineNo) - + self._CheckSectionHeaders(Line, LineNo) SectionType = _ConvertSecNameToType(self.SectionHeaderContent[0][0]) - + if not FirstSectionStartFlag: CurrentSection = SectionType FirstSectionStartFlag = True @@ -370,10 +370,10 @@ class InfParser(InfSectionParser): else: SectionLines.append((Line, LineNo)) continue - + if LastSectionFalg: SectionLines, CurrentSection = self._ProcessLastSection(SectionLines, Line, LineNo, CurrentSection) - + # # End of section content collect. # Parser the section content collected previously. @@ -393,9 +393,9 @@ class InfParser(InfSectionParser): if HeaderStarLineNo == -1: Logger.Error("InfParser", - FORMAT_INVALID, - ST.ERR_NO_SOURCE_HEADER, - File=self.FullPath) + FORMAT_INVALID, + ST.ERR_NO_SOURCE_HEADER, + File=self.FullPath) if BinaryHeaderStarLineNo > -1 and HeaderStarLineNo > -1 and HeaderStarLineNo > BinaryHeaderStarLineNo: Logger.Error("InfParser", FORMAT_INVALID, diff --git a/BaseTools/Source/Python/UPT/Parser/InfParserMisc.py b/BaseTools/Source/Python/UPT/Parser/InfParserMisc.py index 7058e69da1..a416897d27 100644 --- a/BaseTools/Source/Python/UPT/Parser/InfParserMisc.py +++ b/BaseTools/Source/Python/UPT/Parser/InfParserMisc.py @@ -1,7 +1,7 @@ ## @file # This file contained the miscellaneous functions for INF parser # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -82,6 +82,10 @@ def InfExpandMacro(Content, LineInfo, GlobalMacros=None, SectionMacros=None, Fla LineContent = LineInfo[1] LineNo = LineInfo[2] + # Don't expand macros in comments + if LineContent.strip().startswith("#"): + return Content + NewLineInfo = (FileName, LineNo, LineContent) # diff --git a/BaseTools/Source/Python/UPT/Parser/InfPcdSectionParser.py b/BaseTools/Source/Python/UPT/Parser/InfPcdSectionParser.py index 1011559450..f4324cc2ff 100644 --- a/BaseTools/Source/Python/UPT/Parser/InfPcdSectionParser.py +++ b/BaseTools/Source/Python/UPT/Parser/InfPcdSectionParser.py @@ -1,7 +1,7 @@ ## @file # This file contained the parser for [Pcds] sections in INF file # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -160,13 +160,13 @@ class InfPcdSectionParser(InfParserSectionRoot): ExtraData=LineContent) # elif KeysList[0][0].upper() == DT.TAB_INF_PCD_EX.upper(): - if len(TokenList) != 2: + if len(TokenList) != 1: Logger.Error('InfParser', FORMAT_INVALID, ST.ERR_ASBUILD_PCDEX_FORMAT_INVALID, File=FileName, Line=LineNo, - ExtraData=LineContent) + ExtraData=LineContent) ValueList[0:len(TokenList)] = TokenList if len(ValueList) >= 1: PcdList.append((ValueList, CommentsList, (LineContent, LineNo, FileName))) diff --git a/BaseTools/Source/Python/UPT/Parser/InfSectionParser.py b/BaseTools/Source/Python/UPT/Parser/InfSectionParser.py index 879f924c45..727164c2c2 100644 --- a/BaseTools/Source/Python/UPT/Parser/InfSectionParser.py +++ b/BaseTools/Source/Python/UPT/Parser/InfSectionParser.py @@ -1,7 +1,7 @@ ## @file # This file contained the parser for sections in INF file # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -239,6 +239,7 @@ class InfSectionParser(InfDefinSectionParser, self.InfSmmDepexSection = InfDepexObject() self.InfBinariesSection = InfBinariesObject() self.InfHeader = InfHeaderObject() + self.InfBinaryHeader = InfHeaderObject() self.InfSpecialCommentSection = InfSpecialCommentObject() # @@ -253,8 +254,16 @@ class InfSectionParser(InfDefinSectionParser, # # File Header content parser # - def InfHeaderParser(self, Content, InfHeaderObject2, FileName): - (Abstract, Description, Copyright, License) = ParseHeaderCommentSection(Content, FileName) + def InfHeaderParser(self, Content, InfHeaderObject2, FileName, IsBinaryHeader = False): + if IsBinaryHeader: + (Abstract, Description, Copyright, License) = ParseHeaderCommentSection(Content, FileName, True) + if not Abstract or not Description or not Copyright or not License: + Logger.Error('Parser', + FORMAT_INVALID, + ST.ERR_INVALID_BINARYHEADER_FORMAT, + File=FileName) + else: + (Abstract, Description, Copyright, License) = ParseHeaderCommentSection(Content, FileName) # # Not process file name now, for later usage. # diff --git a/BaseTools/Source/Python/UPT/PomAdapter/DecPomAlignment.py b/BaseTools/Source/Python/UPT/PomAdapter/DecPomAlignment.py index cb8aa18788..11b0359176 100644 --- a/BaseTools/Source/Python/UPT/PomAdapter/DecPomAlignment.py +++ b/BaseTools/Source/Python/UPT/PomAdapter/DecPomAlignment.py @@ -1,7 +1,7 @@ ## @file DecPomAlignment.py # This file contained the adapter for convert INF parser object to POM Object # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -23,9 +23,11 @@ import os.path from os import sep import platform +import re import Logger.Log as Logger from Logger import StringTable as ST from Logger.ToolError import UPT_MUL_DEC_ERROR +from Logger.ToolError import FORMAT_INVALID from Library.Parsing import NormPath from Library.DataType import ARCH_LIST @@ -36,10 +38,9 @@ from Library.DataType import TAB_DEC_DEFINES_PACKAGE_NAME from Library.DataType import TAB_DEC_DEFINES_PACKAGE_GUID from Library.DataType import TAB_DEC_DEFINES_PACKAGE_VERSION from Library.DataType import TAB_DEC_DEFINES_DEC_SPECIFICATION +from Library.DataType import TAB_DEC_DEFINES_PKG_UNI_FILE from Library.DataType import TAB_ARCH_COMMON -from Library.CommentParsing import ParseHeaderCommentSection from Library.DataType import TAB_INCLUDES -from Library.CommentParsing import ParseGenericComment from Library.DataType import TAB_LIBRARY_CLASSES from Library.DataType import TAB_PCDS from Library.DataType import TAB_PCDS_FIXED_AT_BUILD_NULL @@ -49,12 +50,33 @@ from Library.DataType import TAB_PCDS_DYNAMIC_EX_NULL from Library.DataType import TAB_PCDS_DYNAMIC_NULL from Library.DataType import TAB_PTR_TYPE_PCD from Library.DataType import ITEM_UNDEFINED +from Library.DataType import TAB_DEC_BINARY_ABSTRACT +from Library.DataType import TAB_DEC_BINARY_DESCRIPTION +from Library.DataType import TAB_LANGUAGE_EN_US +from Library.DataType import TAB_BINARY_HEADER_IDENTIFIER +from Library.DataType import TAB_BINARY_HEADER_USERID +from Library.DataType import TAB_LANGUAGE_EN_X +from Library.DataType import TAB_LANGUAGE_EN +from Library.DataType import TAB_STR_TOKENCNAME +from Library.DataType import TAB_STR_TOKENPROMPT +from Library.DataType import TAB_STR_TOKENHELP +from Library.DataType import TAB_STR_TOKENERR +from Library.DataType import TAB_HEX_START +from Library.DataType import TAB_SPLIT +from Library.CommentParsing import ParseHeaderCommentSection +from Library.CommentParsing import ParseGenericComment from Library.CommentParsing import ParseDecPcdGenericComment from Library.CommentParsing import ParseDecPcdTailComment from Library.Misc import GetFiles from Library.Misc import Sdict +from Library.Misc import GetRelativePath +from Library.Misc import PathClass +from Library.Misc import ValidateUNIFilePath +from Library.UniClassObject import UniFileClassObject +from Library.UniClassObject import ConvertSpecialUnicodes +from Library.UniClassObject import GetLanguageCode1766 +from Library.ParserValidate import IsValidPath from Parser.DecParser import Dec - from Object.POM.PackageObject import PackageObject from Object.POM.CommonObject import UserExtensionObject from Object.POM.CommonObject import IncludeObject @@ -64,6 +86,8 @@ from Object.POM.CommonObject import PpiObject from Object.POM.CommonObject import LibraryClassObject from Object.POM.CommonObject import PcdObject from Object.POM.CommonObject import TextObject +from Object.POM.CommonObject import MiscFileObject +from Object.POM.CommonObject import FileObject ## DecPomAlignment @@ -78,6 +102,8 @@ class DecPomAlignment(PackageObject): self.SupArchList = ARCH_LIST self.CheckMulDec = CheckMulDec self.DecParser = None + self.UniFileClassObject = None + self.PcdDefaultValueDict = {} # # Load Dec file @@ -104,8 +130,8 @@ class DecPomAlignment(PackageObject): self.SetFullPath(Filename) self.SetRelaPath(Path) self.SetFileName(Name) - self.SetPackagePath(Path[Path.upper().find(self.WorkspaceDir.upper()) + len(self.WorkspaceDir) + 1:]) - self.SetCombinePath(Filename[Filename.upper().find(self.WorkspaceDir.upper()) + len(self.WorkspaceDir) + 1:]) + self.SetPackagePath(GetRelativePath(Path, self.WorkspaceDir)) + self.SetCombinePath(GetRelativePath(Filename, self.WorkspaceDir)) self.DecParser = Dec(Filename) @@ -164,8 +190,8 @@ class DecPomAlignment(PackageObject): # Generate user extensions # self.GenUserExtensions() - - ## Generate user extention + + ## Generate user extension # # def GenUserExtensions(self): @@ -182,6 +208,11 @@ class DecPomAlignment(PackageObject): Identifier = Item.IdString if Identifier.startswith('"') and Identifier.endswith('"'): Identifier = Identifier[1:-1] + # + # Generate miscellaneous files of DEC file + # + if UserId == 'TianoCore' and Identifier == 'ExtraFiles': + self.GenMiscFiles(Item.UserString) UserExtension.SetIdentifier(Identifier) UserExtension.SetStatement(Item.UserString) UserExtension.SetSupArchList( @@ -190,7 +221,31 @@ class DecPomAlignment(PackageObject): self.SetUserExtensionList( self.GetUserExtensionList() + [UserExtension] ) - + + ## Generate miscellaneous files on DEC file + # + # + def GenMiscFiles(self, Content): + MiscFileObj = MiscFileObject() + for Line in Content.splitlines(): + FileName = '' + if '#' in Line: + FileName = Line[:Line.find('#')] + else: + FileName = Line + if FileName: + if IsValidPath(FileName, self.GetRelaPath()): + FileObj = FileObject() + FileObj.SetURI(FileName) + MiscFileObj.SetFileList(MiscFileObj.GetFileList()+[FileObj]) + else: + Logger.Error("InfParser", + FORMAT_INVALID, + ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID%(Line), + File=self.GetFileName(), + ExtraData=Line) + self.SetMiscFileList(self.GetMiscFileList()+[MiscFileObj]) + ## Generate Package Header # # Gen Package Header of Dec as = @@ -210,7 +265,8 @@ class DecPomAlignment(PackageObject): # put items into Dict except for PackageName, Guid, Version, DEC_SPECIFICATION # SkipItemList = [TAB_DEC_DEFINES_PACKAGE_NAME, \ - TAB_DEC_DEFINES_PACKAGE_GUID, TAB_DEC_DEFINES_PACKAGE_VERSION, TAB_DEC_DEFINES_DEC_SPECIFICATION] + TAB_DEC_DEFINES_PACKAGE_GUID, TAB_DEC_DEFINES_PACKAGE_VERSION, \ + TAB_DEC_DEFINES_DEC_SPECIFICATION, TAB_DEC_DEFINES_PKG_UNI_FILE] if Item.Key in SkipItemList: continue DefinesDict['%s = %s' % (Item.Key, Item.Value)] = TAB_ARCH_COMMON @@ -221,6 +277,12 @@ class DecPomAlignment(PackageObject): # DefObj.GetPackageVersion()) self.SetName(os.path.splitext(self.GetFileName())[0]) self.SetGuid(DefObj.GetPackageGuid()) + if DefObj.GetPackageUniFile(): + ValidateUNIFilePath(DefObj.GetPackageUniFile()) + self.UniFileClassObject = \ + UniFileClassObject([PathClass(os.path.join(DefObj.GetPackagePath(), DefObj.GetPackageUniFile()))]) + else: + self.UniFileClassObject = None if DefinesDict: UserExtension = UserExtensionObject() @@ -232,16 +294,80 @@ class DecPomAlignment(PackageObject): ) # - # Get All header comment section information + # Get File header information # + if self.UniFileClassObject: + Lang = TAB_LANGUAGE_EN_X + else: + Lang = TAB_LANGUAGE_EN_US Abstract, Description, Copyright, License = \ ParseHeaderCommentSection(self.DecParser.GetHeadComment(), ContainerFile) - self.SetAbstract(Abstract) - self.SetDescription(Description) - self.SetCopyright(Copyright) - self.SetLicense(License) + if Abstract: + self.SetAbstract((Lang, Abstract)) + if Description: + self.SetDescription((Lang, Description)) + if Copyright: + self.SetCopyright(('', Copyright)) + if License: + self.SetLicense(('', License)) + # + # Get Binary header information + # + if self.DecParser.BinaryHeadComment: + Abstract, Description, Copyright, License = \ + ParseHeaderCommentSection(self.DecParser.BinaryHeadComment, + ContainerFile, True) + + if not Abstract or not Description or not Copyright or not License: + Logger.Error('MkPkg', + FORMAT_INVALID, + ST.ERR_INVALID_BINARYHEADER_FORMAT, + ContainerFile) + else: + self.SetBinaryHeaderAbstract((Lang, Abstract)) + self.SetBinaryHeaderDescription((Lang, Description)) + self.SetBinaryHeaderCopyright(('', Copyright)) + self.SetBinaryHeaderLicense(('', License)) + + BinaryAbstractList = [] + BinaryDescriptionList = [] + + #Get Binary header from UNI file + # Initialize the UniStrDict dictionary, top keys are language codes + UniStrDict = {} + if self.UniFileClassObject: + UniStrDict = self.UniFileClassObject.OrderedStringList + for Lang in UniStrDict: + for StringDefClassObject in UniStrDict[Lang]: + Lang = GetLanguageCode1766(Lang) + if StringDefClassObject.StringName == TAB_DEC_BINARY_ABSTRACT: + if (Lang, ConvertSpecialUnicodes(StringDefClassObject.StringValue)) \ + not in self.GetBinaryHeaderAbstract(): + BinaryAbstractList.append((Lang, ConvertSpecialUnicodes(StringDefClassObject.StringValue))) + if StringDefClassObject.StringName == TAB_DEC_BINARY_DESCRIPTION: + if (Lang, ConvertSpecialUnicodes(StringDefClassObject.StringValue)) \ + not in self.GetBinaryHeaderDescription(): + BinaryDescriptionList.append((Lang, + ConvertSpecialUnicodes(StringDefClassObject.StringValue))) + #Combine Binary header from DEC file and UNI file + BinaryAbstractList = self.GetBinaryHeaderAbstract() + BinaryAbstractList + BinaryDescriptionList = self.GetBinaryHeaderDescription() + BinaryDescriptionList + BinaryCopyrightList = self.GetBinaryHeaderCopyright() + BinaryLicenseList = self.GetBinaryHeaderLicense() + #Generate the UserExtensionObject for TianoCore."BinaryHeader" + if BinaryAbstractList or BinaryDescriptionList or BinaryCopyrightList or BinaryLicenseList: + BinaryUserExtension = UserExtensionObject() + BinaryUserExtension.SetBinaryAbstract(BinaryAbstractList) + BinaryUserExtension.SetBinaryDescription(BinaryDescriptionList) + BinaryUserExtension.SetBinaryCopyright(BinaryCopyrightList) + BinaryUserExtension.SetBinaryLicense(BinaryLicenseList) + BinaryUserExtension.SetIdentifier(TAB_BINARY_HEADER_IDENTIFIER) + BinaryUserExtension.SetUserID(TAB_BINARY_HEADER_USERID) + self.SetUserExtensionList(self.GetUserExtensionList() + [BinaryUserExtension]) + + ## GenIncludes # # Gen Includes of Dec @@ -257,7 +383,7 @@ class DecPomAlignment(PackageObject): IncObj = self.DecParser.GetIncludeSectionObject() for Item in IncObj.GetAllIncludes(): IncludePath = os.path.normpath(Item.File) - if platform.system() != 'Windows': + if platform.system() != 'Windows' and platform.system() != 'Microsoft': IncludePath = IncludePath.replace('\\', '/') if IncludePath in IncludesDict: if Item.GetArchList() == [TAB_ARCH_COMMON] or IncludesDict[IncludePath] == [TAB_ARCH_COMMON]: @@ -401,6 +527,8 @@ class DecPomAlignment(PackageObject): ListObject.SetGuid(Value) ListObject.SetSupArchList(Item.GetArchList()) if HelpTxt: + if self.UniFileClassObject: + HelpTxt.SetLang(TAB_LANGUAGE_EN_X) ListObject.SetHelpTextList([HelpTxt]) DeclarationsList.append(ListObject) @@ -437,6 +565,8 @@ class DecPomAlignment(PackageObject): HelpTxt = ParseGenericComment(Item.GetHeadComment() + \ Item.GetTailComment(), None, '@libraryclass') if HelpTxt: + if self.UniFileClassObject: + HelpTxt.SetLang(TAB_LANGUAGE_EN_X) LibraryClass.SetHelpTextList([HelpTxt]) LibraryClassDeclarations.append(LibraryClass) @@ -452,7 +582,6 @@ class DecPomAlignment(PackageObject): # def GenPcds(self, ContainerFile): Logger.Debug(2, "Generate %s ..." % TAB_PCDS) - PcdObj = self.DecParser.GetPcdSectionObject() # # Get all Pcds @@ -464,6 +593,37 @@ class DecPomAlignment(PackageObject): (TAB_PCDS_FEATURE_FLAG_NULL, 'FeaturePcd'), (TAB_PCDS_DYNAMIC_EX_NULL, 'PcdEx'), (TAB_PCDS_DYNAMIC_NULL, 'Pcd')] + + PromptStrList = [] + HelpStrList = [] + PcdErrStrList = [] + # Initialize UniStrDict dictionary, top keys are language codes + UniStrDict = {} + StrList = [] + + Language = '' + if self.UniFileClassObject: + Language = TAB_LANGUAGE_EN_X + else: + Language = TAB_LANGUAGE_EN_US + + if self.UniFileClassObject: + UniStrDict = self.UniFileClassObject.OrderedStringList + for Lang in UniStrDict: + for StringDefClassObject in UniStrDict[Lang]: + StrList = StringDefClassObject.StringName.split('_') + # StringName format is STR___PROMPT + if len(StrList) == 4 and StrList[0] == TAB_STR_TOKENCNAME and StrList[3] == TAB_STR_TOKENPROMPT: + PromptStrList.append((GetLanguageCode1766(Lang), StringDefClassObject.StringName, \ + StringDefClassObject.StringValue)) + # StringName format is STR___HELP + if len(StrList) == 4 and StrList[0] == TAB_STR_TOKENCNAME and StrList[3] == TAB_STR_TOKENHELP: + HelpStrList.append((GetLanguageCode1766(Lang), StringDefClassObject.StringName, \ + StringDefClassObject.StringValue)) + # StringName format is STR__ERR_## + if len(StrList) == 4 and StrList[0] == TAB_STR_TOKENCNAME and StrList[2] == TAB_STR_TOKENERR: + PcdErrStrList.append((GetLanguageCode1766(Lang), StringDefClassObject.StringName, \ + StringDefClassObject.StringValue)) # # For each PCD type # @@ -478,15 +638,234 @@ class DecPomAlignment(PackageObject): ContainerFile, (Item.TokenSpaceGuidCName, Item.TokenCName, Item.DefaultValue, Item.DatumType, Item.TokenValue, - Type, Item.GetHeadComment(), Item.GetTailComment(), - '') - ) + Type, Item.GetHeadComment(), Item.GetTailComment(),''), + Language, + self.DecParser.GetDefineSectionMacro() + ) PcdDeclaration.SetSupArchList(Item.GetArchListOfType(PcdType)) + + # + # Get PCD error message from PCD error comment section in DEC file + # + for PcdErr in PcdDeclaration.GetPcdErrorsList(): + if (PcdDeclaration.GetTokenSpaceGuidCName(), PcdErr.GetErrorNumber()) \ + in self.DecParser.PcdErrorCommentDict: + Key = (PcdDeclaration.GetTokenSpaceGuidCName(), PcdErr.GetErrorNumber()) + PcdErr.SetErrorMessageList(PcdErr.GetErrorMessageList() + \ + [(Language, self.DecParser.PcdErrorCommentDict[Key])]) + + for Index in range(0, len(PromptStrList)): + StrNameList = PromptStrList[Index][1].split('_') + if StrNameList[1].lower() == Item.TokenSpaceGuidCName.lower() and \ + StrNameList[2].lower() == Item.TokenCName.lower(): + TxtObj = TextObject() + TxtObj.SetLang(PromptStrList[Index][0]) + TxtObj.SetString(PromptStrList[Index][2]) + for Prompt in PcdDeclaration.GetPromptList(): + if Prompt.GetLang() == TxtObj.GetLang() and \ + Prompt.GetString() == TxtObj.GetString(): + break + else: + PcdDeclaration.SetPromptList(PcdDeclaration.GetPromptList() + [TxtObj]) + + for Index in range(0, len(HelpStrList)): + StrNameList = HelpStrList[Index][1].split('_') + if StrNameList[1].lower() == Item.TokenSpaceGuidCName.lower() and \ + StrNameList[2].lower() == Item.TokenCName.lower(): + TxtObj = TextObject() + TxtObj.SetLang(HelpStrList[Index][0]) + TxtObj.SetString(HelpStrList[Index][2]) + for HelpStrObj in PcdDeclaration.GetHelpTextList(): + if HelpStrObj.GetLang() == TxtObj.GetLang() and \ + HelpStrObj.GetString() == TxtObj.GetString(): + break + else: + PcdDeclaration.SetHelpTextList(PcdDeclaration.GetHelpTextList() + [TxtObj]) + + # + # Get PCD error message from UNI file + # + for Index in range(0, len(PcdErrStrList)): + StrNameList = PcdErrStrList[Index][1].split('_') + if StrNameList[1].lower() == Item.TokenSpaceGuidCName.lower() and \ + StrNameList[2].lower() == TAB_STR_TOKENERR.lower(): + for PcdErr in PcdDeclaration.GetPcdErrorsList(): + if PcdErr.GetErrorNumber().lower() == (TAB_HEX_START + StrNameList[3]).lower() and \ + (PcdErrStrList[Index][0], PcdErrStrList[Index][2]) not in PcdErr.GetErrorMessageList(): + PcdErr.SetErrorMessageList(PcdErr.GetErrorMessageList() + \ + [(PcdErrStrList[Index][0], PcdErrStrList[Index][2])]) + + # + # Check to prevent missing error message if a Pcd has the error code. + # + for PcdErr in PcdDeclaration.GetPcdErrorsList(): + if PcdErr.GetErrorNumber().strip(): + if not PcdErr.GetErrorMessageList(): + Logger.Error('UPT', + FORMAT_INVALID, + ST.ERR_DECPARSE_PCD_UNMATCHED_ERRORCODE % PcdErr.GetErrorNumber(), + ContainerFile, + PcdErr.GetLineNum(), + PcdErr.GetFileLine()) + PcdDeclarations.append(PcdDeclaration) - self.SetPcdList(self.GetPcdList() + PcdDeclarations) + self.CheckPcdValue() + + ## + # Get error message via language + # @param ErrorMessageList: Error message tuple list the language and its message + # @param Lang: the language of setting + # @return: the error message described in the related UNI file + def GetEnErrorMessage(self, ErrorMessageList): + if self.FullPath: + pass + Lang = TAB_LANGUAGE_EN_US + for (Language, Message) in ErrorMessageList: + if Language == Lang: + return Message + for (Language, Message) in ErrorMessageList: + if Language.find(TAB_LANGUAGE_EN) >= 0: + return Message + else: + try: + return ErrorMessageList[0][1] + except IndexError: + return '' + return '' + + ## + # Replace the strings for Python eval function. + # @param ReplaceValue: The string that needs to be replaced. + # @return: The string was replaced, then eval function is always making out it. + def ReplaceForEval(self, ReplaceValue, IsRange=False, IsExpr=False): + if self.FullPath: + pass + # + # deal with "NOT EQ", "NOT LT", "NOT GT", "NOT LE", "NOT GE", "NOT NOT" + # + NOTNOT_Pattern = '[\t\s]*NOT[\t\s]+NOT[\t\s]*' + NOTGE_Pattern = '[\t\s]*NOT[\t\s]+GE[\t\s]*' + NOTLE_Pattern = '[\t\s]*NOT[\t\s]+LE[\t\s]*' + NOTGT_Pattern = '[\t\s]*NOT[\t\s]+GT[\t\s]*' + NOTLT_Pattern = '[\t\s]*NOT[\t\s]+LT[\t\s]*' + NOTEQ_Pattern = '[\t\s]*NOT[\t\s]+EQ[\t\s]*' + ReplaceValue = re.compile(NOTNOT_Pattern).sub('', ReplaceValue) + ReplaceValue = re.compile(NOTLT_Pattern).sub('x >= ', ReplaceValue) + ReplaceValue = re.compile(NOTGT_Pattern).sub('x <= ', ReplaceValue) + ReplaceValue = re.compile(NOTLE_Pattern).sub('x > ', ReplaceValue) + ReplaceValue = re.compile(NOTGE_Pattern).sub('x < ', ReplaceValue) + ReplaceValue = re.compile(NOTEQ_Pattern).sub('x != ', ReplaceValue) + + if IsRange: + ReplaceValue = ReplaceValue.replace('EQ', 'x ==') + ReplaceValue = ReplaceValue.replace('LT', 'x <') + ReplaceValue = ReplaceValue.replace('LE', 'x <=') + ReplaceValue = ReplaceValue.replace('GT', 'x >') + ReplaceValue = ReplaceValue.replace('GE', 'x >=') + ReplaceValue = ReplaceValue.replace('XOR', 'x ^') + elif IsExpr: + ReplaceValue = ReplaceValue.replace('EQ', '==') + ReplaceValue = ReplaceValue.replace('NE', '!=') + ReplaceValue = ReplaceValue.replace('LT', '<') + ReplaceValue = ReplaceValue.replace('LE', '<=') + ReplaceValue = ReplaceValue.replace('GT', '>') + ReplaceValue = ReplaceValue.replace('GE', '>=') + ReplaceValue = ReplaceValue.replace('XOR', '^') + + ReplaceValue = ReplaceValue.replace('AND', 'and') + ReplaceValue = ReplaceValue.replace('&&', ' and ') + ReplaceValue = ReplaceValue.replace('xor', '^') + ReplaceValue = ReplaceValue.replace('OR', 'or') + ReplaceValue = ReplaceValue.replace('||', ' or ') + ReplaceValue = ReplaceValue.replace('NOT', 'not') + if ReplaceValue.find('!') >= 0 and ReplaceValue[ReplaceValue.index('!') + 1] != '=': + ReplaceValue = ReplaceValue.replace('!', ' not ') + if '.' in ReplaceValue: + Pattern = '[a-zA-Z0-9]{1,}\.[a-zA-Z0-9]{1,}' + MatchedList = re.findall(Pattern, ReplaceValue) + for MatchedItem in MatchedList: + if MatchedItem not in self.PcdDefaultValueDict: + Logger.Error("Dec File Parser", FORMAT_INVALID, Message=ST.ERR_DECPARSE_PCD_NODEFINED % MatchedItem, + File=self.FullPath) + + ReplaceValue = ReplaceValue.replace(MatchedItem, self.PcdDefaultValueDict[MatchedItem]) + + return ReplaceValue + + ## + # Check pcd's default value according to the pcd's description + # + def CheckPcdValue(self): + for Pcd in self.GetPcdList(): + self.PcdDefaultValueDict[TAB_SPLIT.join((Pcd.GetTokenSpaceGuidCName(), Pcd.GetCName())).strip()] = \ + Pcd.GetDefaultValue() + + for Pcd in self.GetPcdList(): + ValidationExpressions = [] + PcdGuidName = TAB_SPLIT.join((Pcd.GetTokenSpaceGuidCName(), Pcd.GetCName())) + Valids = Pcd.GetPcdErrorsList() + for Valid in Valids: + Expression = Valid.GetExpression() + if Expression: + # + # Delete the 'L' prefix of a quoted string, this operation is for eval() + # + QUOTED_PATTERN = '[\t\s]*L?"[^"]*"' + QuotedMatchedObj = re.search(QUOTED_PATTERN, Expression) + if QuotedMatchedObj: + MatchedStr = QuotedMatchedObj.group().strip() + if MatchedStr.startswith('L'): + Expression = Expression.replace(MatchedStr, MatchedStr[1:].strip()) + + Expression = self.ReplaceForEval(Expression, IsExpr=True) + Expression = Expression.replace(PcdGuidName, 'x') + Message = self.GetEnErrorMessage(Valid.GetErrorMessageList()) + ValidationExpressions.append((Expression, Message)) + + ValidList = Valid.GetValidValue() + if ValidList: + ValidValue = 'x in %s' % [eval(v) for v in ValidList.split(' ') if v] + Message = self.GetEnErrorMessage(Valid.GetErrorMessageList()) + ValidationExpressions.append((ValidValue, Message)) + + ValidValueRange = Valid.GetValidValueRange() + if ValidValueRange: + ValidValueRange = self.ReplaceForEval(ValidValueRange, IsRange=True) + if ValidValueRange.find('-') >= 0: + ValidValueRange = ValidValueRange.replace('-', '<= x <=') + elif not ValidValueRange.startswith('x ') and not ValidValueRange.startswith('not ') \ + and not ValidValueRange.startswith('not(') and not ValidValueRange.startswith('('): + ValidValueRange = 'x %s' % ValidValueRange + Message = self.GetEnErrorMessage(Valid.GetErrorMessageList()) + ValidationExpressions.append((ValidValueRange, Message)) + + DefaultValue = self.PcdDefaultValueDict[PcdGuidName.strip()] + # + # Delete the 'L' prefix of a quoted string, this operation is for eval() + # + QUOTED_PATTERN = '[\t\s]*L?"[^"]*"' + QuotedMatchedObj = re.search(QUOTED_PATTERN, DefaultValue) + if QuotedMatchedObj: + MatchedStr = QuotedMatchedObj.group().strip() + if MatchedStr.startswith('L'): + DefaultValue = DefaultValue.replace(MatchedStr, MatchedStr[1:].strip()) + + try: + DefaultValue = eval(DefaultValue.replace('TRUE', 'True').replace('true', 'True') + .replace('FALSE', 'False').replace('false', 'False')) + except BaseException: + pass + + for (Expression, Msg) in ValidationExpressions: + try: + if not eval(Expression, {'x':DefaultValue}): + Logger.Error("Dec File Parser", FORMAT_INVALID, ExtraData='%s, value = %s' %\ + (PcdGuidName, DefaultValue), Message=Msg, File=self.FullPath) + except TypeError: + Logger.Error("Dec File Parser", FORMAT_INVALID, ExtraData=PcdGuidName, \ + Message=Msg, File=self.FullPath) - ## GenModuleFileList # def GenModuleFileList(self, ContainerFile): @@ -562,9 +941,11 @@ class DecPomAlignment(PackageObject): # @param PcdInfo: Pcd information, of format (TokenGuidCName, # TokenName, Value, DatumType, Token, Type, # GenericComment, TailComment, Arch) +# @param Language: The language of HelpText, Prompt # -def GenPcdDeclaration(ContainerFile, PcdInfo): +def GenPcdDeclaration(ContainerFile, PcdInfo, Language, MacroReplaceDict): HelpStr = '' + PromptStr = '' TailHelpStr = '' TokenGuidCName, TokenName, Value, DatumType, Token, Type, \ GenericComment, TailComment, Arch = PcdInfo @@ -585,10 +966,13 @@ def GenPcdDeclaration(ContainerFile, PcdInfo): Pcd.SetSupArchList(SupArchList) if GenericComment: - HelpStr, PcdErr = ParseDecPcdGenericComment(GenericComment, - ContainerFile) - if PcdErr: - Pcd.SetPcdErrorsList([PcdErr]) + HelpStr, PcdErrList, PromptStr = ParseDecPcdGenericComment(GenericComment, + ContainerFile, + TokenGuidCName, + TokenName, + MacroReplaceDict) + if PcdErrList: + Pcd.SetPcdErrorsList(PcdErrList) if TailComment: SupModuleList, TailHelpStr = ParseDecPcdTailComment(TailComment, @@ -600,8 +984,14 @@ def GenPcdDeclaration(ContainerFile, PcdInfo): HelpStr += '\n' HelpStr += TailHelpStr if HelpStr: - HelpTxtObj = TextObject() + HelpTxtObj = TextObject() + HelpTxtObj.SetLang(Language) HelpTxtObj.SetString(HelpStr) Pcd.SetHelpTextList([HelpTxtObj]) + if PromptStr: + TxtObj = TextObject() + TxtObj.SetLang(Language) + TxtObj.SetString(PromptStr) + Pcd.SetPromptList([TxtObj]) return Pcd diff --git a/BaseTools/Source/Python/UPT/PomAdapter/InfPomAlignment.py b/BaseTools/Source/Python/UPT/PomAdapter/InfPomAlignment.py index a4a3107366..fa5f5af0e2 100644 --- a/BaseTools/Source/Python/UPT/PomAdapter/InfPomAlignment.py +++ b/BaseTools/Source/Python/UPT/PomAdapter/InfPomAlignment.py @@ -1,7 +1,7 @@ ## @file InfPomAlignment.py # This file contained the adapter for convert INF parser object to POM Object # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -18,10 +18,8 @@ InfPomAlignment # Import modules # import os.path - from Logger import StringTable as ST import Logger.Log as Logger - from Library.String import FORMAT_INVALID from Library.String import PARSER_ERROR from Library.String import NormPath @@ -29,10 +27,15 @@ from Library.String import GetSplitValueList from Library.Misc import ConvertVersionToDecimal from Library.Misc import GetHelpStringByRemoveHashKey from Library.Misc import ConvertArchList +from Library.Misc import GetRelativePath +from Library.Misc import PathClass from Library.Parsing import GetPkgInfoFromDec +from Library.UniClassObject import UniFileClassObject +from Library.UniClassObject import ConvertSpecialUnicodes +from Library.UniClassObject import GetLanguageCode1766 from Library import DataType as DT from Library import GlobalData - +from Library.ParserValidate import IsValidPath from Object.POM import CommonObject from Object.POM.ModuleObject import ModuleObject from Object.POM.ModuleObject import ExternObject @@ -47,7 +50,7 @@ from Object.POM.ModuleObject import AsBuiltObject from PomAdapter.InfPomAlignmentMisc import GenModuleHeaderUserExt from PomAdapter.InfPomAlignmentMisc import GenBinaryData from Parser import InfParser - +from PomAdapter.DecPomAlignment import DecPomAlignment ## InfPomAlignment @@ -62,7 +65,6 @@ class InfPomAlignment(ModuleObject): # def __init__(self, FileName, WorkSpace=None, PackagePath='', Skip=False): ModuleObject.__init__(self) - self.Parser = None self.FileName = FileName self.WorkSpace = WorkSpace @@ -72,7 +74,7 @@ class InfPomAlignment(ModuleObject): self.ModulePath = '' self.WorkspaceDir = " " self.CustomMakefile = [] - + self.UniFileClassObject = None self.SetPackagePath(PackagePath) # # Call GenInfPomObjects function to fill POM object. @@ -80,8 +82,10 @@ class InfPomAlignment(ModuleObject): if Skip: OrigConfig = Logger.SUPRESS_ERROR Logger.SUPRESS_ERROR = True - self._GenInfPomObjects(Skip) - Logger.SUPRESS_ERROR = OrigConfig + try: + self._GenInfPomObjects(Skip) + finally: + Logger.SUPRESS_ERROR = OrigConfig else: self._GenInfPomObjects(Skip) @@ -111,7 +115,6 @@ class InfPomAlignment(ModuleObject): self._GenGuidProtocolPpis(DT.TAB_PROTOCOLS) self._GenGuidProtocolPpis(DT.TAB_PPIS) self._GenDepexes() - self._GenMiscFiles(self.FullPath, Skip) ## Convert [Defines] section content to InfDefObject # @@ -134,7 +137,6 @@ class InfPomAlignment(ModuleObject): ArchList = GetSplitValueList(ArchString, ' ') ArchList = ConvertArchList(ArchList) HasCalledFlag = False - # # Get data from Sdict() # @@ -147,26 +149,21 @@ class InfPomAlignment(ModuleObject): # ModuleSurfaceArea.Header.Name element # self.SetName(os.path.splitext(os.path.basename(self.FileName))[0]) - self.WorkspaceDir = " " # # CombinePath and ModulePath # - PathCount = self.FullPath.upper().find(self.WorkSpace.upper()) + len(self.WorkSpace) + 1 - CombinePath = self.FullPath[PathCount:] + CombinePath = GetRelativePath(self.FullPath, self.WorkSpace) self.SetCombinePath(CombinePath) - ModulePath = os.path.split(CombinePath)[0] ModuleRelativePath = ModulePath if self.GetPackagePath() != '': - ModuleRelativePath = ModulePath[ModulePath.find(self.GetPackagePath()) + len(self.GetPackagePath()) + 1:] + ModuleRelativePath = GetRelativePath(ModulePath, self.GetPackagePath()) self.SetModulePath(ModuleRelativePath) - # # For Define Seciton Items. # DefineObj = ValueList - # # Convert UEFI/PI version to decimal number # @@ -179,7 +176,6 @@ class InfPomAlignment(ModuleObject): __PiVersion = ConvertVersionToDecimal(__PiVersion) self.SetPiSpecificationVersion(str(__PiVersion)) - SpecList = DefineObj.GetSpecification() NewSpecList = [] for SpecItem in SpecList: @@ -214,6 +210,10 @@ class InfPomAlignment(ModuleObject): ST.ERR_INF_PARSER_DEFINE_SECTION_MUST_ITEM_NOT_EXIST % ("BASE_NAME"), File=self.FullPath) else: self.SetBaseName(DefineObj.GetBaseName().GetValue()) + if DefineObj.GetModuleUniFileName(): + self.UniFileClassObject = UniFileClassObject([PathClass(DefineObj.GetModuleUniFileName())]) + else: + self.UniFileClassObject = None if DefineObj.GetInfVersion() == None: Logger.Error("InfParser", FORMAT_INVALID, ST.ERR_INF_PARSER_DEFINE_SECTION_MUST_ITEM_NOT_EXIST % ("INF_VERSION"), File=self.FullPath) @@ -247,7 +247,6 @@ class InfPomAlignment(ModuleObject): # Logger.Error("Parser", PARSER_ERROR, ST.ERR_INF_PARSER_NOT_SUPPORT_EDKI_INF, ExtraData=self.FullPath, RaiseError=Logger.IS_RAISE_ERROR) - # # if there is Shadow, Should judge the MODULE_TYPE in # SEC, PEI_CORE and PEIM @@ -259,12 +258,10 @@ class InfPomAlignment(ModuleObject): if DefineObj.GetPcdIsDriver() != None: self.SetPcdIsDriver(DefineObj.GetPcdIsDriver().GetValue()) - # # LIBRARY_CLASS # self._GenModuleHeaderLibClass(DefineObj, ArchList) - # # CUSTOM_MAKEFILE # @@ -276,7 +273,6 @@ class InfPomAlignment(ModuleObject): if not HasCalledFlag: self._GenModuleHeaderExterns(DefineObj) HasCalledFlag = True - # # each module has only one module header # @@ -289,28 +285,45 @@ class InfPomAlignment(ModuleObject): # put all define statement into user-extension sections # DefinesDictNew = GenModuleHeaderUserExt(DefineObj, ArchString) - if DefinesDictNew: UserExtension = CommonObject.UserExtensionObject() UserExtension.SetDefinesDict(DefinesDictNew) UserExtension.SetIdentifier('DefineModifiers') UserExtension.SetUserID('EDK2') self.SetUserExtensionList(self.GetUserExtensionList() + [UserExtension]) - # # Get all meta-file header information # the record is list of items formated: # [LineValue, Arch, StartLine, ID, Third] # - InfHeaderObj = self.Parser.InfHeader # # Put header information into POM object # - self.SetAbstract(InfHeaderObj.GetAbstract()) - self.SetDescription(InfHeaderObj.GetDescription()) - self.SetCopyright(InfHeaderObj.GetCopyright()) - self.SetLicense(InfHeaderObj.GetLicense()) + if self.UniFileClassObject: + Lang = DT.TAB_LANGUAGE_EN_X + else: + Lang = DT.TAB_LANGUAGE_EN_US + if InfHeaderObj.GetAbstract(): + self.SetAbstract((Lang, InfHeaderObj.GetAbstract())) + if InfHeaderObj.GetDescription(): + self.SetDescription((Lang, InfHeaderObj.GetDescription())) + if InfHeaderObj.GetCopyright(): + self.SetCopyright(('', InfHeaderObj.GetCopyright())) + if InfHeaderObj.GetLicense(): + self.SetLicense(('', InfHeaderObj.GetLicense())) + # + # Put Binary header information into POM object + # + InfBinaryHeaderObj = self.Parser.InfBinaryHeader + if InfBinaryHeaderObj.GetAbstract(): + self.SetBinaryHeaderAbstract((Lang, InfBinaryHeaderObj.GetAbstract())) + if InfBinaryHeaderObj.GetDescription(): + self.SetBinaryHeaderDescription((Lang, InfBinaryHeaderObj.GetDescription())) + if InfBinaryHeaderObj.GetCopyright(): + self.SetBinaryHeaderCopyright(('', InfBinaryHeaderObj.GetCopyright())) + if InfBinaryHeaderObj.GetLicense(): + self.SetBinaryHeaderLicense(('', InfBinaryHeaderObj.GetLicense())) ## GenModuleHeaderLibClass # @@ -390,6 +403,8 @@ class InfPomAlignment(ModuleObject): Hob.SetSupArchList(Item.GetSupArchList()) if Item.GetHelpString(): HelpTextObj = CommonObject.TextObject() + if self.UniFileClassObject: + HelpTextObj.SetLang(DT.TAB_LANGUAGE_EN_X) HelpTextObj.SetString(Item.GetHelpString()) Hob.SetHelpTextList([HelpTextObj]) HobList.append(Hob) @@ -402,6 +417,8 @@ class InfPomAlignment(ModuleObject): Event.SetUsage(Item.GetUsage()) if Item.GetHelpString(): HelpTextObj = CommonObject.TextObject() + if self.UniFileClassObject: + HelpTextObj.SetLang(DT.TAB_LANGUAGE_EN_X) HelpTextObj.SetString(Item.GetHelpString()) Event.SetHelpTextList([HelpTextObj]) EventList.append(Event) @@ -414,6 +431,8 @@ class InfPomAlignment(ModuleObject): BootMode.SetUsage(Item.GetUsage()) if Item.GetHelpString(): HelpTextObj = CommonObject.TextObject() + if self.UniFileClassObject: + HelpTextObj.SetLang(DT.TAB_LANGUAGE_EN_X) HelpTextObj.SetString(Item.GetHelpString()) BootMode.SetHelpTextList([HelpTextObj]) BootModeList.append(BootMode) @@ -433,18 +452,14 @@ class InfPomAlignment(ModuleObject): BuildOptionsList = self.Parser.InfBuildOptionSection.GetBuildOptions() if not GlobalData.gIS_BINARY_INF: BuildOptionDict = {} - for BuildOptionObj in BuildOptionsList: ArchList = BuildOptionObj.GetSupArchList() ArchList = ConvertArchList(ArchList) BuildOptionsContent = BuildOptionObj.GetContent() ArchString = ' '.join(ArchList) - if not BuildOptionsContent: continue - BuildOptionDict[ArchString] = BuildOptionsContent - if not BuildOptionDict: return UserExtension = CommonObject.UserExtensionObject() @@ -473,7 +488,6 @@ class InfPomAlignment(ModuleObject): # LibClassObj = self.Parser.InfLibraryClassSection.LibraryClasses Keys = LibClassObj.keys() - for Key in Keys: LibraryClassData = LibClassObj[Key] for Item in LibraryClassData: @@ -485,14 +499,14 @@ class InfPomAlignment(ModuleObject): LibraryClass.SetSupArchList(ConvertArchList(Item.GetSupArchList())) LibraryClass.SetSupModuleList(Item.GetSupModuleList()) HelpStringObj = Item.GetHelpString() - if HelpStringObj != None: CommentString = GetHelpStringByRemoveHashKey(HelpStringObj.HeaderComments + HelpStringObj.TailComments) HelpTextHeaderObj = CommonObject.TextObject() + if self.UniFileClassObject: + HelpTextHeaderObj.SetLang(DT.TAB_LANGUAGE_EN_X) HelpTextHeaderObj.SetString(CommentString) LibraryClass.SetHelpTextList([HelpTextHeaderObj]) - self.SetLibraryClassList(self.GetLibraryClassList() + [LibraryClass]) ## GenPackages @@ -508,7 +522,6 @@ class InfPomAlignment(ModuleObject): # Get all Packages # PackageObj = self.Parser.InfPackageSection.Packages - # # Go through each arch # @@ -546,13 +559,11 @@ class InfPomAlignment(ModuleObject): def _GenPcds(self): if not GlobalData.gIS_BINARY_INF: Logger.Debug(2, "Generate %s ..." % DT.TAB_PCDS) - # # Get all Pcds # PcdObj = self.Parser.InfPcdSection.Pcds KeysList = PcdObj.keys() - # # Go through each arch # @@ -571,6 +582,8 @@ class InfPomAlignment(ModuleObject): Pcd.SetFeatureFlag(PcdItemObj.GetFeatureFlagExp()) Pcd.SetSupArchList(ConvertArchList(PcdItemObj.GetSupportArchList())) HelpTextObj = CommonObject.TextObject() + if self.UniFileClassObject: + HelpTextObj.SetLang(DT.TAB_LANGUAGE_EN_X) HelpTextObj.SetString(CommentItem.GetHelpStringItem()) Pcd.SetHelpTextList([HelpTextObj]) PcdList = self.GetPcdList() @@ -636,11 +649,47 @@ class InfPomAlignment(ModuleObject): Identifier = UserExtensionDataObj.GetIdString() if Identifier.startswith('"') and Identifier.endswith('"'): Identifier = Identifier[1:-1] + # + # Generate miscellaneous files on INF file + # + if UserId == 'TianoCore' and Identifier == 'ExtraFiles': + self._GenMiscFiles(UserExtensionDataObj.GetContent()) UserExtension.SetIdentifier(Identifier) UserExtension.SetStatement(UserExtensionDataObj.GetContent()) UserExtension.SetSupArchList(ConvertArchList(UserExtensionDataObj.GetSupArchList())) self.SetUserExtensionList(self.GetUserExtensionList() + [UserExtension]) - + + # + # Gen UserExtensions of TianoCore."BinaryHeader" + # + + #Get Binary header from INF file + BinaryAbstractList = self.BinaryHeaderAbstractList + BinaryDescriptionList = self.BinaryHeaderDescriptionList + BinaryCopyrightList = self.BinaryHeaderCopyrightList + BinaryLicenseList = self.BinaryHeaderLicenseList + #Get Binary header from UNI file + # Initialize UniStrDict, the top keys are language codes + UniStrDict = {} + if self.UniFileClassObject: + UniStrDict = self.UniFileClassObject.OrderedStringList + for Lang in UniStrDict: + for StringDefClassObject in UniStrDict[Lang]: + Lang = GetLanguageCode1766(Lang) + if StringDefClassObject.StringName == DT.TAB_INF_BINARY_ABSTRACT: + BinaryAbstractList.append((Lang, ConvertSpecialUnicodes(StringDefClassObject.StringValue))) + if StringDefClassObject.StringName == DT.TAB_INF_BINARY_DESCRIPTION: + BinaryDescriptionList.append((Lang, ConvertSpecialUnicodes(StringDefClassObject.StringValue))) + if BinaryAbstractList or BinaryDescriptionList or BinaryCopyrightList or BinaryLicenseList: + BinaryUserExtension = CommonObject.UserExtensionObject() + BinaryUserExtension.SetBinaryAbstract(BinaryAbstractList) + BinaryUserExtension.SetBinaryDescription(BinaryDescriptionList) + BinaryUserExtension.SetBinaryCopyright(BinaryCopyrightList) + BinaryUserExtension.SetBinaryLicense(BinaryLicenseList) + BinaryUserExtension.SetIdentifier(DT.TAB_BINARY_HEADER_IDENTIFIER) + BinaryUserExtension.SetUserID(DT.TAB_BINARY_HEADER_USERID) + self.SetUserExtensionList(self.GetUserExtensionList() + [BinaryUserExtension]) + def _GenDepexesList(self, SmmDepexList, DxeDepexList, PeiDepexList): if SmmDepexList: self.SetSmmDepex(SmmDepexList) @@ -675,10 +724,14 @@ class InfPomAlignment(ModuleObject): ModuleType = Depex.GetModuleType() ModuleTypeList = [] if IsLibraryClass: - if not self.GetIsLibraryModList(): + if self.GetModuleType() == 'BASE' and not ModuleType: + Logger.Error("\nMkPkg", PARSER_ERROR, + ST.ERR_INF_PARSER_DEPEX_SECTION_INVALID_FOR_BASE_LIBRARY_CLASS, + self.GetFullPath(), RaiseError=True) + if self.GetModuleType() != 'BASE' and not self.GetIsLibraryModList(): Logger.Error("\nMkPkg", PARSER_ERROR, ST.ERR_INF_PARSER_DEPEX_SECTION_INVALID_FOR_LIBRARY_CLASS, self.GetFullPath(), RaiseError=True) - if ModuleType and ModuleType not in self.GetIsLibraryModList(): + if self.GetModuleType() != 'BASE' and ModuleType and ModuleType not in self.GetIsLibraryModList(): Logger.Error("\nMkPkg", PARSER_ERROR, ST.ERR_INF_PARSER_DEPEX_SECTION_NOT_DETERMINED, self.GetFullPath(), RaiseError=True) if ModuleType: @@ -713,6 +766,8 @@ class InfPomAlignment(ModuleObject): DepexIns.SetFeatureFlag(Depex.GetFeatureFlagExp()) if Depex.HelpString: HelpIns = CommonObject.TextObject() + if self.UniFileClassObject: + HelpIns.SetLang(DT.TAB_LANGUAGE_EN_X) HelpIns.SetString(GetHelpStringByRemoveHashKey(Depex.HelpString)) DepexIns.SetHelpText(HelpIns) @@ -771,6 +826,7 @@ class InfPomAlignment(ModuleObject): AsBuildLibIns = AsBuildLibraryClassObject() AsBuildLibIns.SetLibGuid(LibItem.GetFileGuid()) AsBuildLibIns.SetLibVersion(LibItem.GetVersion()) + AsBuildLibIns.SetSupArchList(LibItem.GetSupArchList()) AsBuildLibraryClassList.append(AsBuildLibIns) AsBuildIns.SetLibraryInstancesList(AsBuildLibraryClassList) @@ -778,7 +834,7 @@ class InfPomAlignment(ModuleObject): # BuildOption AsBuild Info # for BuildOptionItem in self.Parser.InfBuildOptionSection.GetBuildOptions(): - AsBuildBuildOptionList += BuildOptionItem.GetAsBuildList() + AsBuildBuildOptionList.append(BuildOptionItem) AsBuildIns.SetBuildFlagsList(AsBuildBuildOptionList) # @@ -786,13 +842,34 @@ class InfPomAlignment(ModuleObject): # AsBuildIns = self._GenAsBuiltPcds(self.Parser.InfPcdSection.GetPcds(), AsBuildIns) + # + # Parse the DEC file that contains the GUID value of the GUID CName which is used by + # SUBTYPE_GUID type binary file in the Binaries section in the INF file + # + DecObjList = [] + if not self.PackagePath: + WorkSpace = os.path.normpath(self.WorkSpace) + TempPath = ModulePath = os.path.normpath(self.ModulePath) + while ModulePath: + TempPath = ModulePath + ModulePath = os.path.dirname(ModulePath) + PackageName = TempPath + DecFilePath = os.path.normpath(os.path.join(WorkSpace, PackageName)) + if DecFilePath: + for File in os.listdir(DecFilePath): + if File.upper().endswith('.DEC'): + DecFileFullPath = os.path.normpath(os.path.join(DecFilePath, File)) + DecObjList.append(DecPomAlignment(DecFileFullPath, self.WorkSpace)) + + BinariesDict, AsBuildIns, BinaryFileObjectList = GenBinaryData(BinaryData, BinaryObj, BinariesDict, AsBuildIns, BinaryFileObjectList, self.GetSupArchList(), - self.BinaryModule) - + self.BinaryModule, + DecObjList) + BinariesDict2 = {} for Key in BinariesDict: ValueList = BinariesDict[Key] @@ -855,9 +932,13 @@ class InfPomAlignment(ModuleObject): Pcd.SetItemType(PcdItem[0]) Pcd.SetFeatureFlag(PcdItemObj.GetFeatureFlagExp()) Pcd.SetSupArchList(ConvertArchList(PcdItemObj.GetSupportArchList())) - HelpTextObj = CommonObject.TextObject() - HelpTextObj.SetString(PcdItemObj.GetHelpStringList()) - Pcd.SetHelpTextList([HelpTextObj]) + Pcd.SetValidUsage(PcdItemObj.GetValidUsage()) + for CommentItem in PcdItemObj.GetHelpStringList(): + HelpTextObj = CommonObject.TextObject() + if self.UniFileClassObject: + HelpTextObj.SetLang(DT.TAB_LANGUAGE_EN_X) + HelpTextObj.SetString(CommentItem.GetHelpStringItem()) + Pcd.SetHelpTextList(Pcd.GetHelpTextList() + [HelpTextObj]) AsBuildPatchPcdList.append(Pcd) else: PcdItemObj = PcdItem[1] @@ -870,9 +951,13 @@ class InfPomAlignment(ModuleObject): Pcd.SetItemType(PcdItem[0]) Pcd.SetFeatureFlag(PcdItemObj.GetFeatureFlagExp()) Pcd.SetSupArchList(ConvertArchList(PcdItemObj.GetSupportArchList())) - HelpTextObj = CommonObject.TextObject() - HelpTextObj.SetString(PcdItemObj.GetHelpStringList()) - Pcd.SetHelpTextList([HelpTextObj]) + Pcd.SetValidUsage(PcdItemObj.GetValidUsage()) + for CommentItem in PcdItemObj.GetHelpStringList(): + HelpTextObj = CommonObject.TextObject() + if self.UniFileClassObject: + HelpTextObj.SetLang(DT.TAB_LANGUAGE_EN_X) + HelpTextObj.SetString(CommentItem.GetHelpStringItem()) + Pcd.SetHelpTextList(Pcd.GetHelpTextList() + [HelpTextObj]) AsBuildPcdExList.append(Pcd) AsBuildIns.SetPatchPcdList(AsBuildPatchPcdList) AsBuildIns.SetPcdExList(AsBuildPcdExList) @@ -914,11 +999,13 @@ class InfPomAlignment(ModuleObject): ListObject.SetSupArchList(ConvertArchList(Item.GetSupArchList())) ListObject.SetFeatureFlag(Item.GetFeatureFlagExp()) HelpString = GuidComentItem.GetHelpStringItem() - HelpTxtTailObj = CommonObject.TextObject() - HelpTxtTailObj.SetString(HelpString) - - ListObject.SetHelpTextList([HelpTxtTailObj]) - + if HelpString.strip(): + HelpTxtTailObj = CommonObject.TextObject() + if self.UniFileClassObject: + HelpTxtTailObj.SetLang(DT.TAB_LANGUAGE_EN_X) + HelpTxtTailObj.SetString(HelpString) + ListObject.SetHelpTextList([HelpTxtTailObj]) + GuidProtocolPpiList.append(ListObject) elif Type == DT.TAB_PROTOCOLS: ProtocolData = ProtocolObj.keys() @@ -931,10 +1018,13 @@ class InfPomAlignment(ModuleObject): ListObject.SetFeatureFlag(Item.GetFeatureFlagExp()) ListObject.SetNotify(CommentItem.GetNotify()) ListObject.SetUsage(CommentItem.GetUsageItem()) - HelpTxtObj = CommonObject.TextObject() HelpString = CommentItem.GetHelpStringItem() - HelpTxtObj.SetString(HelpString) - ListObject.SetHelpTextList([HelpTxtObj]) + if HelpString.strip(): + HelpTxtObj = CommonObject.TextObject() + if self.UniFileClassObject: + HelpTxtObj.SetLang(DT.TAB_LANGUAGE_EN_X) + HelpTxtObj.SetString(HelpString) + ListObject.SetHelpTextList([HelpTxtObj]) GuidProtocolPpiList.append(ListObject) elif Type == DT.TAB_PPIS: PpiData = PpisObj.keys() @@ -947,10 +1037,13 @@ class InfPomAlignment(ModuleObject): ListObject.SetFeatureFlag(Item.GetFeatureFlagExp()) ListObject.SetNotify(CommentItem.GetNotify()) ListObject.SetUsage(CommentItem.GetUsage()) - HelpTextObj = CommonObject.TextObject() HelpString = CommentItem.GetHelpStringItem() - HelpTextObj.SetString(HelpString) - ListObject.SetHelpTextList([HelpTextObj]) + if HelpString.strip(): + HelpTextObj = CommonObject.TextObject() + if self.UniFileClassObject: + HelpTextObj.SetLang(DT.TAB_LANGUAGE_EN_X) + HelpTextObj.SetString(HelpString) + ListObject.SetHelpTextList([HelpTextObj]) GuidProtocolPpiList.append(ListObject) if Type == DT.TAB_GUIDS: @@ -966,6 +1059,24 @@ class InfPomAlignment(ModuleObject): # # @param ContainerFile: The Inf file full path # - def _GenMiscFiles(self, ContainerFile, Skip): - pass - + def _GenMiscFiles(self, Content): + MiscFileObj = CommonObject.MiscFileObject() + for Line in Content.splitlines(): + FileName = '' + if '#' in Line: + FileName = Line[:Line.find('#')] + else: + FileName = Line + if FileName: + if IsValidPath(FileName, GlobalData.gINF_MODULE_DIR): + FileObj = CommonObject.FileObject() + FileObj.SetURI(FileName) + MiscFileObj.SetFileList(MiscFileObj.GetFileList()+[FileObj]) + else: + Logger.Error("InfParser", + FORMAT_INVALID, + ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID%(Line), + File=GlobalData.gINF_MODULE_NAME, + ExtraData=Line) + self.SetMiscFileList(self.GetMiscFileList()+[MiscFileObj]) + diff --git a/BaseTools/Source/Python/UPT/PomAdapter/InfPomAlignmentMisc.py b/BaseTools/Source/Python/UPT/PomAdapter/InfPomAlignmentMisc.py index 7369d64672..042d4784c8 100644 --- a/BaseTools/Source/Python/UPT/PomAdapter/InfPomAlignmentMisc.py +++ b/BaseTools/Source/Python/UPT/PomAdapter/InfPomAlignmentMisc.py @@ -1,7 +1,7 @@ ## @file InfPomAlignmentMisc.py # This file contained the routines for InfPomAlignment # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -24,6 +24,10 @@ from Library import DataType as DT from Library.Misc import ConvertArchList from Object.POM.ModuleObject import BinaryFileObject from Object.POM import CommonObject +from Library.String import FORMAT_INVALID +from Library.Misc import CheckGuidRegFormat +from Logger import StringTable as ST + ## GenModuleHeaderUserExt # @@ -167,7 +171,8 @@ def _GenInfDefineStateMent(HeaderComment, Name, Value, TailComment): ## GenBinaryData # # -def GenBinaryData(BinaryData, BinaryObj, BinariesDict, AsBuildIns, BinaryFileObjectList, SupArchList, BinaryModule): +def GenBinaryData(BinaryData, BinaryObj, BinariesDict, AsBuildIns, BinaryFileObjectList, \ + SupArchList, BinaryModule, DecObjList=None): if BinaryModule: pass OriSupArchList = SupArchList @@ -179,6 +184,7 @@ def GenBinaryData(BinaryData, BinaryObj, BinariesDict, AsBuildIns, BinaryFileObj else: TagName = '' Family = '' + FFE = ItemObj.GetFeatureFlagExp() # @@ -200,6 +206,41 @@ def GenBinaryData(BinaryData, BinaryObj, BinariesDict, AsBuildIns, BinaryFileObj FileNameObj.SetFileType(ItemObj.GetType()) FileNameObj.SetFilename(ItemObj.GetFileName()) FileNameObj.SetFeatureFlag(FFE) + # + # Get GUID value of the GUID CName in the DEC file + # + if ItemObj.GetType() == DT.SUBTYPE_GUID_BINARY_FILE_TYPE: + if not CheckGuidRegFormat(ItemObj.GetGuidValue()): + if not DecObjList: + if DT.TAB_HORIZON_LINE_SPLIT in ItemObj.GetGuidValue() or \ + DT.TAB_COMMA_SPLIT in ItemObj.GetGuidValue(): + Logger.Error("\nMkPkg", + FORMAT_INVALID, + ST.ERR_DECPARSE_DEFINE_PKGGUID, + ExtraData=ItemObj.GetGuidValue(), + RaiseError=True) + else: + Logger.Error("\nMkPkg", + FORMAT_INVALID, + ST.ERR_UNI_SUBGUID_VALUE_DEFINE_DEC_NOT_FOUND % \ + (ItemObj.GetGuidValue()), + RaiseError=True) + else: + for DecObj in DecObjList: + for GuidObj in DecObj.GetGuidList(): + if GuidObj.GetCName() == ItemObj.GetGuidValue(): + FileNameObj.SetGuidValue(GuidObj.GetGuid()) + break + + if not FileNameObj.GetGuidValue(): + Logger.Error("\nMkPkg", + FORMAT_INVALID, + ST.ERR_DECPARSE_CGUID_NOT_FOUND % \ + (ItemObj.GetGuidValue()), + RaiseError=True) + else: + FileNameObj.SetGuidValue(ItemObj.GetGuidValue().strip()) + FileNameObj.SetSupArchList(SupArchList) FileNameList = [FileNameObj] diff --git a/BaseTools/Source/Python/UPT/ReplacePkg.py b/BaseTools/Source/Python/UPT/ReplacePkg.py new file mode 100644 index 0000000000..9f231f9bcd --- /dev/null +++ b/BaseTools/Source/Python/UPT/ReplacePkg.py @@ -0,0 +1,148 @@ +## @file +# Replace distribution package. +# +# Copyright (c) 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. +# +""" +Replace a distribution package +""" +## +# Import Modules +# +from shutil import rmtree +from traceback import format_exc +from platform import python_version +from sys import platform +from Logger import StringTable as ST +from Logger.ToolError import UNKNOWN_ERROR +from Logger.ToolError import FatalError +from Logger.ToolError import ABORT_ERROR +from Logger.ToolError import CODE_ERROR +from Logger.ToolError import UPT_ALREADY_INSTALLED_ERROR +import Logger.Log as Logger + +from Core.DependencyRules import DependencyRules +from Library import GlobalData +from InstallPkg import UnZipDp +from InstallPkg import InstallDp +from RmPkg import GetInstalledDpInfo +from RmPkg import RemoveDist + +## Tool entrance method +# +# This method mainly dispatch specific methods per the command line options. +# If no error found, return zero value so the caller of this tool can know +# if it's executed successfully or not. +# +# @param Options: command Options +# +def Main(Options = None): + ContentZipFile, DistFile = None, None + try: + DataBase = GlobalData.gDB + WorkspaceDir = GlobalData.gWORKSPACE + Dep = DependencyRules(DataBase) + DistPkg, ContentZipFile, DpPkgFileName, DistFile = UnZipDp(WorkspaceDir, Options.PackFileToReplace) + + StoredDistFile, OrigDpGuid, OrigDpVersion = GetInstalledDpInfo(Options.PackFileToBeReplaced, \ + Dep, DataBase, WorkspaceDir) + + # + # check dependency + # + CheckReplaceDpx(Dep, DistPkg, OrigDpGuid, OrigDpVersion) + + # + # Remove the old distribution + # + RemoveDist(OrigDpGuid, OrigDpVersion, StoredDistFile, DataBase, WorkspaceDir, Options.Yes) + + # + # Install the new distribution + # + InstallDp(DistPkg, DpPkgFileName, ContentZipFile, Options, Dep, WorkspaceDir, DataBase) + ReturnCode = 0 + + except FatalError, XExcept: + ReturnCode = XExcept.args[0] + if Logger.GetLevel() <= Logger.DEBUG_9: + Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), + platform) + format_exc()) + except KeyboardInterrupt: + ReturnCode = ABORT_ERROR + if Logger.GetLevel() <= Logger.DEBUG_9: + Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), + platform) + format_exc()) + except: + ReturnCode = CODE_ERROR + Logger.Error( + "\nReplacePkg", + CODE_ERROR, + ST.ERR_UNKNOWN_FATAL_REPLACE_ERR % (Options.PackFileToReplace, Options.PackFileToBeReplaced), + ExtraData=ST.MSG_SEARCH_FOR_HELP, + RaiseError=False + ) + Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), + platform) + format_exc()) + + finally: + Logger.Quiet(ST.MSG_REMOVE_TEMP_FILE_STARTED) + if DistFile: + DistFile.Close() + if ContentZipFile: + ContentZipFile.Close() + if GlobalData.gUNPACK_DIR: + rmtree(GlobalData.gUNPACK_DIR) + GlobalData.gUNPACK_DIR = None + Logger.Quiet(ST.MSG_REMOVE_TEMP_FILE_DONE) + + if ReturnCode == 0: + Logger.Quiet(ST.MSG_FINISH) + + return ReturnCode + +def CheckReplaceDpx(Dep, DistPkg, OrigDpGuid, OrigDpVersion): + NewDpPkgList = [] + for PkgInfo in DistPkg.PackageSurfaceArea: + Guid, Version = PkgInfo[0], PkgInfo[1] + NewDpPkgList.append((Guid, Version)) + + NewDpInfo = "%s %s" % (DistPkg.Header.GetGuid(), DistPkg.Header.GetVersion()) + OrigDpInfo = "%s %s" % (OrigDpGuid, OrigDpVersion) + + # + # check whether new distribution is already installed and not replacing itself + # + if (NewDpInfo != OrigDpInfo): + if Dep.CheckDpExists(DistPkg.Header.GetGuid(), DistPkg.Header.GetVersion()): + Logger.Error("\nReplacePkg", UPT_ALREADY_INSTALLED_ERROR, + ST.WRN_DIST_PKG_INSTALLED, + ExtraData=ST.MSG_REPLACE_ALREADY_INSTALLED_DP) + + # + # check whether the original distribution could be replaced by new distribution + # + Logger.Verbose(ST.MSG_CHECK_DP_FOR_REPLACE%(NewDpInfo, OrigDpInfo)) + DepInfoResult = Dep.CheckDpDepexForReplace(OrigDpGuid, OrigDpVersion, NewDpPkgList) + Replaceable = DepInfoResult[0] + if not Replaceable: + Logger.Error("\nReplacePkg", UNKNOWN_ERROR, + ST.ERR_PACKAGE_NOT_MATCH_DEPENDENCY) + + # + # check whether new distribution could be installed by dependency rule + # + Logger.Verbose(ST.MSG_CHECK_DP_FOR_INSTALL%str(NewDpInfo)) + if not Dep.ReplaceCheckNewDpDepex(DistPkg, OrigDpGuid, OrigDpVersion): + Logger.Error("\nReplacePkg", UNKNOWN_ERROR, + ST.ERR_PACKAGE_NOT_MATCH_DEPENDENCY, + ExtraData=DistPkg.Header.Name) + diff --git a/BaseTools/Source/Python/UPT/RmPkg.py b/BaseTools/Source/Python/UPT/RmPkg.py index 3817812168..ea842c1185 100644 --- a/BaseTools/Source/Python/UPT/RmPkg.py +++ b/BaseTools/Source/Python/UPT/RmPkg.py @@ -1,7 +1,7 @@ ## @file # Install distribution package. # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -28,7 +28,6 @@ from sys import stdin from sys import platform from Core.DependencyRules import DependencyRules -from Library.Misc import CheckEnvVariable from Library import GlobalData from Logger import StringTable as ST import Logger.Log as Logger @@ -133,89 +132,27 @@ def Main(Options = None): Logger.Error("RmPkg", OPTION_MISSING, ExtraData=ST.ERR_SPECIFY_PACKAGE) - CheckEnvVariable() WorkspaceDir = GlobalData.gWORKSPACE # # Prepare check dependency # Dep = DependencyRules(DataBase) - if Options.DistributionFile: - (Guid, Version, NewDpFileName) = \ - DataBase.GetDpByName(os.path.split(Options.DistributionFile)[1]) - if not Guid: - Logger.Error("RmPkg", UNKNOWN_ERROR, ST.ERR_PACKAGE_NOT_INSTALLED % Options.DistributionFile) - else: - Guid = Options.PackageGuid - Version = Options.PackageVersion - # - # Check Dp existing - # - if not Dep.CheckDpExists(Guid, Version): - Logger.Error("RmPkg", UNKNOWN_ERROR, ST.ERR_DISTRIBUTION_NOT_INSTALLED) # - # Check for Distribution files existence in /conf/upt, if not exist, - # Warn user and go on. + # Get the Dp information # - StoredDistFile = os.path.normpath(os.path.join(WorkspaceDir, GlobalData.gUPT_DIR, NewDpFileName)) - if not os.path.isfile(StoredDistFile): - Logger.Warn("RmPkg", ST.WRN_DIST_NOT_FOUND%StoredDistFile) - StoredDistFile = None - + StoredDistFile, Guid, Version = GetInstalledDpInfo(Options.DistributionFile, Dep, DataBase, WorkspaceDir) + # # Check Dp depex # CheckDpDepex(Dep, Guid, Version, WorkspaceDir) + # + # remove distribution # - # Get Current File List - # - NewFileList = GetCurrentFileList(DataBase, Guid, Version, WorkspaceDir) - - # - # Remove all files - # - MissingFileList = [] - for (Path, Md5Sum) in DataBase.GetDpFileList(Guid, Version): - if os.path.isfile(Path): - if Path in NewFileList: - NewFileList.remove(Path) - if not Options.Yes: - # - # check whether modified by users - # - Md5Sigature = md5.new(open(str(Path), 'rb').read()) - if Md5Sum != Md5Sigature.hexdigest(): - Logger.Info(ST.MSG_CONFIRM_REMOVE2 % Path) - Input = stdin.readline() - Input = Input.replace('\r', '').replace('\n', '') - if Input.upper() != 'Y': - continue - RemovePath(Path) - else: - MissingFileList.append(Path) - - for Path in NewFileList: - if os.path.isfile(Path): - if (not Options.Yes) and (not os.path.split(Path)[1].startswith('.')): - Logger.Info(ST.MSG_CONFIRM_REMOVE3 % Path) - Input = stdin.readline() - Input = Input.replace('\r', '').replace('\n', '') - if Input.upper() != 'Y': - continue - RemovePath(Path) - - # - # Remove distribution files in /Conf/.upt - # - if StoredDistFile is not None: - os.remove(StoredDistFile) + RemoveDist(Guid, Version, StoredDistFile, DataBase, WorkspaceDir, Options.Yes) - # - # update database - # - Logger.Quiet(ST.MSG_UPDATE_PACKAGE_DATABASE) - DataBase.RemoveDpObj(Guid, Version) Logger.Quiet(ST.MSG_FINISH) ReturnCode = 0 @@ -242,5 +179,98 @@ def Main(Options = None): format_exc()) ReturnCode = CODE_ERROR return ReturnCode - +## GetInstalledDpInfo method +# +# Get the installed distribution information +# +# @param DistributionFile: the name of the distribution +# @param Dep: the instance of DependencyRules +# @param DataBase: the internal database +# @param WorkspaceDir: work space directory +# @retval StoredDistFile: the distribution file that backed up +# @retval Guid: the Guid of the distribution +# @retval Version: the Version of distribution +# +def GetInstalledDpInfo(DistributionFile, Dep, DataBase, WorkspaceDir): + (Guid, Version, NewDpFileName) = DataBase.GetDpByName(os.path.split(DistributionFile)[1]) + if not Guid: + Logger.Error("RmPkg", UNKNOWN_ERROR, ST.ERR_PACKAGE_NOT_INSTALLED % DistributionFile) + + # + # Check Dp existing + # + if not Dep.CheckDpExists(Guid, Version): + Logger.Error("RmPkg", UNKNOWN_ERROR, ST.ERR_DISTRIBUTION_NOT_INSTALLED) + # + # Check for Distribution files existence in /conf/upt, if not exist, + # Warn user and go on. + # + StoredDistFile = os.path.normpath(os.path.join(WorkspaceDir, GlobalData.gUPT_DIR, NewDpFileName)) + if not os.path.isfile(StoredDistFile): + Logger.Warn("RmPkg", ST.WRN_DIST_NOT_FOUND%StoredDistFile) + StoredDistFile = None + + return StoredDistFile, Guid, Version + +## RemoveDist method +# +# remove a distribution +# +# @param Guid: the Guid of the distribution +# @param Version: the Version of distribution +# @param StoredDistFile: the distribution file that backed up +# @param DataBase: the internal database +# @param WorkspaceDir: work space directory +# @param ForceRemove: whether user want to remove file even it is modified +# +def RemoveDist(Guid, Version, StoredDistFile, DataBase, WorkspaceDir, ForceRemove): + # + # Get Current File List + # + NewFileList = GetCurrentFileList(DataBase, Guid, Version, WorkspaceDir) + + # + # Remove all files + # + MissingFileList = [] + for (Path, Md5Sum) in DataBase.GetDpFileList(Guid, Version): + if os.path.isfile(Path): + if Path in NewFileList: + NewFileList.remove(Path) + if not ForceRemove: + # + # check whether modified by users + # + Md5Sigature = md5.new(open(str(Path), 'rb').read()) + if Md5Sum != Md5Sigature.hexdigest(): + Logger.Info(ST.MSG_CONFIRM_REMOVE2 % Path) + Input = stdin.readline() + Input = Input.replace('\r', '').replace('\n', '') + if Input.upper() != 'Y': + continue + RemovePath(Path) + else: + MissingFileList.append(Path) + + for Path in NewFileList: + if os.path.isfile(Path): + if (not ForceRemove) and (not os.path.split(Path)[1].startswith('.')): + Logger.Info(ST.MSG_CONFIRM_REMOVE3 % Path) + Input = stdin.readline() + Input = Input.replace('\r', '').replace('\n', '') + if Input.upper() != 'Y': + continue + RemovePath(Path) + + # + # Remove distribution files in /Conf/.upt + # + if StoredDistFile is not None: + os.remove(StoredDistFile) + + # + # update database + # + Logger.Quiet(ST.MSG_UPDATE_PACKAGE_DATABASE) + DataBase.RemoveDpObj(Guid, Version) diff --git a/BaseTools/Source/Python/UPT/UPT.py b/BaseTools/Source/Python/UPT/UPT.py index b168a51daa..8ad0f2638f 100644 --- a/BaseTools/Source/Python/UPT/UPT.py +++ b/BaseTools/Source/Python/UPT/UPT.py @@ -2,7 +2,7 @@ # # This file is the main entry for UPT # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -19,10 +19,11 @@ UPT ## import modules # +from Core import FileHook import sys import os.path -from os import environ from sys import platform +import platform as pf from optparse import OptionParser from traceback import format_exc from platform import python_version @@ -37,10 +38,13 @@ from Logger.ToolError import OPTION_MISSING from Logger.ToolError import FILE_TYPE_MISMATCH from Logger.ToolError import OPTION_CONFLICT from Logger.ToolError import FatalError + import MkPkg import InstallPkg import RmPkg -from Library.Misc import CheckEnvVariable +import InventoryWs +import ReplacePkg +from Library.Misc import GetWorkspace from Library import GlobalData from Core.IpiDb import IpiDatabase from BuildVersion import gBUILD_VERSION @@ -57,7 +61,12 @@ from BuildVersion import gBUILD_VERSION # CheckConflictOption # def CheckConflictOption(Opt): - if (Opt.PackFileToCreate and Opt.PackFileToInstall and Opt.PackFileToRemove): + if (Opt.PackFileToCreate or Opt.PackFileToInstall or Opt.PackFileToRemove or Opt.PackFileToReplace) \ + and Opt.InventoryWs: + Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_L_OA_EXCLUSIVE) + elif Opt.PackFileToReplace and (Opt.PackFileToCreate or Opt.PackFileToInstall or Opt.PackFileToRemove): + Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_U_ICR_EXCLUSIVE) + elif (Opt.PackFileToCreate and Opt.PackFileToInstall and Opt.PackFileToRemove): Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_REQUIRE_I_C_R_OPTION) elif Opt.PackFileToCreate and Opt.PackFileToInstall: Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_I_C_EXCLUSIVE) @@ -66,6 +75,10 @@ def CheckConflictOption(Opt): elif Opt.PackFileToCreate and Opt.PackFileToRemove: Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_C_R_EXCLUSIVE) + if Opt.CustomPath and Opt.UseGuidedPkgPath: + Logger.Warn("UPT", ST.WARN_CUSTOMPATH_OVERRIDE_USEGUIDEDPATH) + Opt.UseGuidedPkgPath = False + ## SetLogLevel # def SetLogLevel(Opt): @@ -121,12 +134,23 @@ def Main(): Parser.add_option("-m", "--inf-filename", action="append", type="string", dest="EDK2_INF_Filename", help=ST.HLP_SPECIFY_INF_NAME_CREATE) + Parser.add_option("-l", "--list", action="store_true", dest="List_Dist_Installed", + help=ST.HLP_LIST_DIST_INSTALLED) + Parser.add_option("-f", "--force", action="store_true", dest="Yes", help=ST.HLP_DISABLE_PROMPT) Parser.add_option("-n", "--custom-path", action="store_true", dest="CustomPath", help=ST.HLP_CUSTOM_PATH_PROMPT) Parser.add_option("-x", "--free-lock", action="store_true", dest="SkipLock", help=ST.HLP_SKIP_LOCK_CHECK) + Parser.add_option("-u", "--replace", action="store", type="string", dest="Replace_Distribution_Package_File", + help=ST.HLP_SPECIFY_PACKAGE_NAME_REPLACE) + + Parser.add_option("-o", "--original", action="store", type="string", dest="Original_Distribution_Package_File", + help=ST.HLP_SPECIFY_PACKAGE_NAME_TO_BE_REPLACED) + + Parser.add_option("--use-guided-paths", action="store_true", dest="Use_Guided_Paths", help=ST.HLP_USE_GUIDED_PATHS) + Opt = Parser.parse_args()[0] Var2Var = [ @@ -135,24 +159,42 @@ def Main(): ("PackFileToCreate", Opt.Create_Distribution_Package_File), ("PackFileToRemove", Opt.Remove_Distribution_Package_File), ("PackageFileList", Opt.EDK2_DEC_Filename), - ("ModuleFileList", Opt.EDK2_INF_Filename) + ("ModuleFileList", Opt.EDK2_INF_Filename), + ("InventoryWs", Opt.List_Dist_Installed), + ("PackFileToReplace", Opt.Replace_Distribution_Package_File), + ("PackFileToBeReplaced", Opt.Original_Distribution_Package_File), + ("UseGuidedPkgPath", Opt.Use_Guided_Paths), ] + for Var in Var2Var: setattr(Opt, Var[0], Var[1]) try: - CheckEnvVariable() + GlobalData.gWORKSPACE = GetWorkspace() except FatalError, XExcept: if Logger.GetLevel() <= Logger.DEBUG_9: Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), platform) + format_exc()) return XExcept.args[0] - GlobalData.gWORKSPACE = os.path.normpath(environ["WORKSPACE"]) + # Start ********************************************* + # Support WORKSPACE is a long path + # Only work well on windows + # Linux Solution TBD + if pf.system() == 'Windows': + os.system('@echo off\nsubst b: /D') + os.system('subst b: "%s"' % GlobalData.gWORKSPACE) + GlobalData.gWORKSPACE = 'B:\\' + # End *********************************************** + WorkspaceDir = GlobalData.gWORKSPACE SetLogLevel(Opt) - GlobalData.gDB = IpiDatabase(os.path.normpath(os.path.join(WorkspaceDir, "Conf/DistributionPackageDatabase.db"))) + Mgr = FileHook.RecoverMgr(WorkspaceDir) + FileHook.SetRecoverMgr(Mgr) + + GlobalData.gDB = IpiDatabase(os.path.normpath(os.path.join(WorkspaceDir, \ + "Conf/DistributionPackageDatabase.db")), WorkspaceDir) GlobalData.gDB.InitDatabase(Opt.SkipLock) # @@ -179,27 +221,12 @@ def Main(): elif Opt.PackFileToInstall: if not Opt.PackFileToInstall.endswith('.dist'): Logger.Error("InstallPkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToInstall) - - # - # check file existence, if not absolute path, then try current working directory, then $(WORKSPACE) - # - Existed = True - if os.path.isabs(Opt.PackFileToInstall): - if not (os.path.exists(Opt.PackFileToInstall) and os.path.isfile(Opt.PackFileToInstall)): - Existed = False - else: - AbsPath = os.path.normpath(os.path.join(os.getcwd(), Opt.PackFileToInstall)) - if not (os.path.exists(AbsPath) and os.path.isfile(AbsPath)): - AbsPath = os.path.normpath(os.path.join(WorkspaceDir, Opt.PackFileToInstall)) - if not (os.path.exists(AbsPath) and os.path.isfile(AbsPath)): - Existed = False - - if Existed: - Opt.PackFileToInstall = AbsPath - - if not Existed: + + AbsPath = GetFullPathDist(Opt.PackFileToInstall, WorkspaceDir) + if not AbsPath: Logger.Error("InstallPkg", FILE_NOT_FOUND, ST.ERR_INSTALL_DIST_NOT_FOUND % Opt.PackFileToInstall) + Opt.PackFileToInstall = AbsPath setattr(Opt, 'PackageFile', Opt.PackFileToInstall) RunModule = InstallPkg.Main @@ -214,6 +241,35 @@ def Main(): setattr(Opt, 'DistributionFile', Opt.PackFileToRemove) RunModule = RmPkg.Main + elif Opt.InventoryWs: + RunModule = InventoryWs.Main + + elif Opt.PackFileToBeReplaced and not Opt.PackFileToReplace: + Logger.Error("ReplacePkg", OPTION_MISSING, ExtraData=ST.ERR_REQUIRE_U_OPTION) + + elif Opt.PackFileToReplace: + if not Opt.PackFileToReplace.endswith('.dist'): + Logger.Error("ReplacePkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToReplace) + if not Opt.PackFileToBeReplaced: + Logger.Error("ReplacePkg", OPTION_MISSING, ExtraData=ST.ERR_REQUIRE_O_OPTION) + if not Opt.PackFileToBeReplaced.endswith('.dist'): + Logger.Error("ReplacePkg", + FILE_TYPE_MISMATCH, + ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToBeReplaced) + + head, tail = os.path.split(Opt.PackFileToBeReplaced) + if head or not tail: + Logger.Error("ReplacePkg", + FILE_TYPE_MISMATCH, + ExtraData=ST.ERR_DIST_FILENAME_ONLY_FOR_REPLACE_ORIG % Opt.PackFileToBeReplaced) + + AbsPath = GetFullPathDist(Opt.PackFileToReplace, WorkspaceDir) + if not AbsPath: + Logger.Error("ReplacePkg", FILE_NOT_FOUND, ST.ERR_REPLACE_DIST_NOT_FOUND % Opt.PackFileToReplace) + + Opt.PackFileToReplace = AbsPath + RunModule = ReplacePkg.Main + else: Parser.print_usage() return OPTION_MISSING @@ -225,10 +281,47 @@ def Main(): Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), platform) + \ format_exc()) finally: + try: + if ReturnCode != 0: + Logger.Quiet(ST.MSG_RECOVER_START) + GlobalData.gDB.RollBack() + Mgr.rollback() + Logger.Quiet(ST.MSG_RECOVER_DONE) + else: + GlobalData.gDB.Commit() + Mgr.commit() + except StandardError: + Logger.Quiet(ST.MSG_RECOVER_FAIL) GlobalData.gDB.CloseDb() + if pf.system() == 'Windows': + os.system('subst b: /D') return ReturnCode +## GetFullPathDist +# +# This function will check DistFile existence, if not absolute path, then try current working directory, +# then $(WORKSPACE),and return the AbsPath. If file doesn't find, then return None +# +# @param DistFile: The distribution file in either relative path or absolute path +# @param WorkspaceDir: Workspace Directory +# @return AbsPath: The Absolute path of the distribution file if existed, None else +# +def GetFullPathDist(DistFile, WorkspaceDir): + if os.path.isabs(DistFile): + if not (os.path.exists(DistFile) and os.path.isfile(DistFile)): + return None + else: + return DistFile + else: + AbsPath = os.path.normpath(os.path.join(os.getcwd(), DistFile)) + if not (os.path.exists(AbsPath) and os.path.isfile(AbsPath)): + AbsPath = os.path.normpath(os.path.join(WorkspaceDir, DistFile)) + if not (os.path.exists(AbsPath) and os.path.isfile(AbsPath)): + return None + + return AbsPath + if __name__ == '__main__': RETVAL = Main() # diff --git a/BaseTools/Source/Python/UPT/UnitTest/CommentGeneratingUnitTest.py b/BaseTools/Source/Python/UPT/UnitTest/CommentGeneratingUnitTest.py index 72a909db0e..42a2ba3a6b 100644 --- a/BaseTools/Source/Python/UPT/UnitTest/CommentGeneratingUnitTest.py +++ b/BaseTools/Source/Python/UPT/UnitTest/CommentGeneratingUnitTest.py @@ -1,7 +1,7 @@ ## @file # This file contain unit test for CommentParsing # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -30,7 +30,8 @@ from Object.POM.ModuleObject import HobObject from Library.String import GetSplitValueList from Library.DataType import TAB_SPACE_SPLIT -from Library.DataType import LANGUAGE_EN_US +from Library.DataType import TAB_LANGUAGE_EN_US +from Library.DataType import TAB_LANGUAGE_ENG from Library.DataType import ITEM_UNDEFINED from Library.DataType import TAB_INF_FEATURE_PCD from Library import GlobalData @@ -52,7 +53,7 @@ class _GetHelpStrTest(unittest.TestCase): def testNormalCase1(self): HelpStr = 'Hello world' HelpTextObj = TextObject() - HelpTextObj.SetLang(LANGUAGE_EN_US) + HelpTextObj.SetLang(TAB_LANGUAGE_EN_US) HelpTextObj.SetString(HelpStr) HelpTextList = [HelpTextObj] @@ -65,14 +66,14 @@ class _GetHelpStrTest(unittest.TestCase): def testNormalCase2(self): HelpStr = 'Hello world' HelpTextObj = TextObject() - HelpTextObj.SetLang('eng') + HelpTextObj.SetLang(TAB_LANGUAGE_ENG) HelpTextObj.SetString(HelpStr) HelpTextList = [HelpTextObj] ExpectedStr = 'Hello world1' HelpTextObj = TextObject() - HelpTextObj.SetLang(LANGUAGE_EN_US) + HelpTextObj.SetLang(TAB_LANGUAGE_EN_US) HelpTextObj.SetString(ExpectedStr) HelpTextList.append(HelpTextObj) @@ -93,7 +94,7 @@ class _GetHelpStrTest(unittest.TestCase): ExpectedStr = 'Hello world1' HelpTextObj = TextObject() - HelpTextObj.SetLang('eng') + HelpTextObj.SetLang(TAB_LANGUAGE_ENG) HelpTextObj.SetString(ExpectedStr) HelpTextList.append(HelpTextObj) @@ -108,7 +109,7 @@ class _GetHelpStrTest(unittest.TestCase): ExpectedStr = 'Hello world1' HelpTextObj = TextObject() - HelpTextObj.SetLang('eng') + HelpTextObj.SetLang(TAB_LANGUAGE_ENG) HelpTextObj.SetString(ExpectedStr) HelpTextList = [HelpTextObj] @@ -128,7 +129,7 @@ class _GetHelpStrTest(unittest.TestCase): ExpectedStr = 'Hello world1' HelpTextObj = TextObject() - HelpTextObj.SetLang(LANGUAGE_EN_US) + HelpTextObj.SetLang(TAB_LANGUAGE_EN_US) HelpTextObj.SetString(ExpectedStr) HelpTextList = [HelpTextObj] diff --git a/BaseTools/Source/Python/UPT/UnitTest/CommentParsingUnitTest.py b/BaseTools/Source/Python/UPT/UnitTest/CommentParsingUnitTest.py index 3ed3345c6d..a114ff22a7 100644 --- a/BaseTools/Source/Python/UPT/UnitTest/CommentParsingUnitTest.py +++ b/BaseTools/Source/Python/UPT/UnitTest/CommentParsingUnitTest.py @@ -1,7 +1,7 @@ ## @file # This file contain unit test for CommentParsing # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -21,7 +21,7 @@ from Library.CommentParsing import ParseHeaderCommentSection, \ from Library.CommentParsing import _IsCopyrightLine from Library.String import GetSplitValueList from Library.DataType import TAB_SPACE_SPLIT -from Library.DataType import LANGUAGE_EN_US +from Library.DataType import TAB_LANGUAGE_EN_US # # Test ParseHeaderCommentSection @@ -467,7 +467,7 @@ class ParseGenericCommentTest(unittest.TestCase): HelptxtObj = ParseGenericComment(TestCommentLinesList, 'testNormalCase1') self.failIf(not HelptxtObj) self.assertEqual(HelptxtObj.GetString(), 'hello world') - self.assertEqual(HelptxtObj.GetLang(), LANGUAGE_EN_US) + self.assertEqual(HelptxtObj.GetLang(), TAB_LANGUAGE_EN_US) # # Normal case2: multiple lines of comment @@ -488,7 +488,7 @@ class ParseGenericCommentTest(unittest.TestCase): self.failIf(not HelptxtObj) self.assertEqual(HelptxtObj.GetString(), 'hello world\n' + 'second line') - self.assertEqual(HelptxtObj.GetLang(), LANGUAGE_EN_US) + self.assertEqual(HelptxtObj.GetLang(), TAB_LANGUAGE_EN_US) # # Normal case3: multiple lines of comment, non comment lines will be skipped @@ -509,7 +509,7 @@ class ParseGenericCommentTest(unittest.TestCase): self.failIf(not HelptxtObj) self.assertEqual(HelptxtObj.GetString(), 'hello world\n\n') - self.assertEqual(HelptxtObj.GetLang(), LANGUAGE_EN_US) + self.assertEqual(HelptxtObj.GetLang(), TAB_LANGUAGE_EN_US) # # Test ParseDecPcdGenericComment diff --git a/BaseTools/Source/Python/UPT/Xml/CommonXml.py b/BaseTools/Source/Python/UPT/Xml/CommonXml.py index 0369bfba4c..e28aec5b9b 100644 --- a/BaseTools/Source/Python/UPT/Xml/CommonXml.py +++ b/BaseTools/Source/Python/UPT/Xml/CommonXml.py @@ -1,7 +1,7 @@ ## @file # This file is used to parse a PCD file of .PKG file # -# Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -31,6 +31,8 @@ from Library.Xml.XmlRoutines import XmlAttribute from Library.Xml.XmlRoutines import XmlNode from Library.Xml.XmlRoutines import XmlList from Library.Xml.XmlRoutines import CreateXmlElement +from Library.UniClassObject import ConvertSpecialUnicodes +from Library.UniClassObject import GetLanguageCode1766 from Object.POM.CommonObject import FileObject from Object.POM.CommonObject import MiscFileObject from Object.POM.CommonObject import UserExtensionObject @@ -40,7 +42,6 @@ from Object.POM.CommonObject import FileNameObject from Object.POM.ModuleObject import ModuleObject from Xml.XmlParserMisc import IsRequiredItemListNull from Xml.XmlParserMisc import GetHelpTextList - import Library.DataType as DataType ## @@ -54,14 +55,11 @@ class ClonedFromXml(object): def FromXml(self, Item, Key): self.GUID = XmlElement(Item, '%s/GUID' % Key) self.Version = XmlAttribute(XmlNode(Item, '%s/GUID' % Key), 'Version') - if self.GUID == '' and self.Version == '': return None - ClonedFrom = ClonedRecordObject() ClonedFrom.SetPackageGuid(self.GUID) ClonedFrom.SetPackageVersion(self.Version) - return ClonedFrom def ToXml(self, ClonedFrom, Key): @@ -72,7 +70,6 @@ class ClonedFromXml(object): AttributeList = [] NodeList = [Element1] Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList) - return Root def __str__(self): @@ -99,7 +96,6 @@ class CommonDefinesXml(object): [Mod for Mod in GetSplitValueList(XmlAttribute(Item, 'SupModList'), DataType.TAB_SPACE_SPLIT) if Mod] self.FeatureFlag = ConvertNOTEQToNE(XmlAttribute(Item, 'FeatureFlag')) - def ToXml(self): pass @@ -107,7 +103,27 @@ class CommonDefinesXml(object): return "Usage = %s SupArchList = %s SupModList = %s FeatureFlag = %s" \ % (self.Usage, self.SupArchList, self.SupModList, self.FeatureFlag) +## +# PromptXml +# +class PromptXml(object): + def __init__(self): + self.Prompt = '' + self.Lang = '' + def FromXml(self, Item, Key): + if Key: + pass + self.Prompt = XmlElement2(Item, 'Prompt') + self.Lang = XmlAttribute(Item, 'Lang') + + def ToXml(self, Prompt, Key='Prompt'): + if self.Prompt: + pass + return CreateXmlElement('%s' % Key, Prompt.GetString(), [], [['Lang', Prompt.GetLang()]]) + def __str__(self): + return "Prompt = %s Lang = %s" % (self.Prompt, self.Lang) + ## # HelpTextXml # @@ -138,10 +154,10 @@ class HeaderXml(object): self.BaseName = '' self.GUID = '' self.Version = '' - self.Copyright = '' - self.License = '' - self.Abstract = '' - self.Description = '' + self.CopyrightList = [] + self.LicenseList = [] + self.AbstractList = [] + self.DescriptionList = [] def FromXml(self, Item, Key, IsRequiredCheck=False, IsStandAlongModule=False): if not Item and IsRequiredCheck: @@ -156,21 +172,28 @@ class HeaderXml(object): self.BaseName = XmlAttribute(XmlNode(Item, '%s/Name' % Key), 'BaseName') self.GUID = XmlElement(Item, '%s/GUID' % Key) self.Version = XmlAttribute(XmlNode(Item, '%s/GUID' % Key), 'Version') - self.Copyright = XmlElement(Item, '%s/Copyright' % Key) - self.License = XmlElement(Item, '%s/License' % Key) - self.Abstract = XmlElement(Item, '%s/Abstract' % Key) - self.Description = XmlElement(Item, '%s/Description' % Key) + for SubItem in XmlList(Item, '%s/Abstract' % Key): + HeaderAbstractLang = XmlAttribute(SubItem, 'Lang') + self.AbstractList.append((HeaderAbstractLang, XmlElement(SubItem, '%s/Abstract' % Key))) + for SubItem in XmlList(Item, '%s/Description' % Key): + HeaderDescriptionLang = XmlAttribute(SubItem, 'Lang') + self.DescriptionList.append((HeaderDescriptionLang, XmlElement(SubItem, '%s/Description' % Key))) + for SubItem in XmlList(Item, '%s/Copyright' % Key): + HeaderCopyrightLang = XmlAttribute(SubItem, 'Lang') + self.CopyrightList.append((HeaderCopyrightLang, XmlElement(SubItem, '%s/Copyright' % Key))) + for SubItem in XmlList(Item, '%s/License' % Key): + HeaderLicenseLang = XmlAttribute(SubItem, 'Lang') + self.LicenseList.append((HeaderLicenseLang, XmlElement(SubItem, '%s/License' % Key))) ModuleHeader = ModuleObject() ModuleHeader.SetName(self.Name) ModuleHeader.SetBaseName(self.BaseName) ModuleHeader.SetGuid(self.GUID) ModuleHeader.SetVersion(self.Version) - ModuleHeader.SetCopyright(self.Copyright) - ModuleHeader.SetLicense(self.License) - ModuleHeader.SetAbstract(self.Abstract) - ModuleHeader.SetDescription(self.Description) - + ModuleHeader.SetCopyright(self.CopyrightList) + ModuleHeader.SetLicense(self.LicenseList) + ModuleHeader.SetAbstract(self.AbstractList) + ModuleHeader.SetDescription(self.DescriptionList) return ModuleHeader def ToXml(self, Header, Key): @@ -178,23 +201,51 @@ class HeaderXml(object): pass Element1 = CreateXmlElement('Name', Header.GetName(), [], [['BaseName', Header.GetBaseName()]]) Element2 = CreateXmlElement('GUID', Header.GetGuid(), [], [['Version', Header.GetVersion()]]) - AttributeList = [] NodeList = [Element1, Element2, - ['Copyright', Header.GetCopyright()], - ['License', Header.GetLicense()], - ['Abstract', Header.GetAbstract()], - ['Description', Header.GetDescription()], ] - Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList) + UNIInfAbstractList = [] + UNIInfDescriptionList = [] + # Get Abstract and Description from Uni File + # if the Uni File exists + if Header.UniFileClassObject is not None: + UniStrDict = Header.UniFileClassObject.OrderedStringList + for Lang in UniStrDict: + for StringDefClassObject in UniStrDict[Lang]: + if not StringDefClassObject.StringValue: + continue + if StringDefClassObject.StringName == DataType.TAB_INF_ABSTRACT: + UNIInfAbstractList.append((GetLanguageCode1766(Lang), + ConvertSpecialUnicodes(StringDefClassObject.StringValue))) + + if StringDefClassObject.StringName == DataType.TAB_INF_DESCRIPTION: + UNIInfDescriptionList.append((GetLanguageCode1766(Lang), + ConvertSpecialUnicodes(StringDefClassObject.StringValue))) + + # Get Abstract and Description from INF File Header + for (Lang, Value) in Header.GetCopyright(): + if Value: + NodeList.append(CreateXmlElement('Copyright', Value, [], [])) + for (Lang, Value) in Header.GetLicense(): + if Value: + NodeList.append(CreateXmlElement('License', Value, [], [])) + for (Lang, Value) in Header.GetAbstract() + UNIInfAbstractList: + if Value: + NodeList.append(CreateXmlElement('Abstract', Value, [], [['Lang', Lang]])) + for (Lang, Value) in Header.GetDescription() + UNIInfDescriptionList: + if Value: + NodeList.append(CreateXmlElement('Description', Value, [], [['Lang', Lang]])) + + AttributeList = [] + Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList) return Root def __str__(self): return "Name = %s BaseName = %s GUID = %s Version = %s Copyright = %s \ License = %s Abstract = %s Description = %s" % \ - (self.Name, self.BaseName, self.GUID, self.Version, self.Copyright, \ - self.License, self.Abstract, self.Description) + (self.Name, self.BaseName, self.GUID, self.Version, self.CopyrightList, \ + self.LicenseList, self.AbstractList, self.DescriptionList) ## # DistributionPackageHeaderXml # @@ -218,13 +269,11 @@ class DistributionPackageHeaderXml(object): self.Signature = XmlElement(Item, '%s/Signature' % Key) self.XmlSpecification = XmlElement(Item, '%s/XmlSpecification' % Key) self.Header.FromXml(Item, Key) - DistributionPackageHeader = DistributionPackageHeaderObject() if self.ReadOnly.upper() == 'TRUE': DistributionPackageHeader.ReadOnly = True elif self.ReadOnly.upper() == 'FALSE': DistributionPackageHeader.ReadOnly = False - if self.RePackage.upper() == 'TRUE': DistributionPackageHeader.RePackage = True elif self.RePackage.upper() == 'FALSE': @@ -233,16 +282,14 @@ class DistributionPackageHeaderXml(object): DistributionPackageHeader.Date = self.Date DistributionPackageHeader.Signature = self.Signature DistributionPackageHeader.XmlSpecification = self.XmlSpecification - DistributionPackageHeader.SetName(self.Header.Name) DistributionPackageHeader.SetBaseName(self.Header.BaseName) DistributionPackageHeader.SetGuid(self.Header.GUID) DistributionPackageHeader.SetVersion(self.Header.Version) - DistributionPackageHeader.SetCopyright(self.Header.Copyright) - DistributionPackageHeader.SetLicense(self.Header.License) - DistributionPackageHeader.SetAbstract(self.Header.Abstract) - DistributionPackageHeader.SetDescription(self.Header.Description) - + DistributionPackageHeader.SetCopyright(self.Header.CopyrightList) + DistributionPackageHeader.SetLicense(self.Header.LicenseList) + DistributionPackageHeader.SetAbstract(self.Header.AbstractList) + DistributionPackageHeader.SetDescription(self.Header.DescriptionList) return DistributionPackageHeader def ToXml(self, DistributionPackageHeader, Key): @@ -261,22 +308,35 @@ class DistributionPackageHeaderXml(object): AttributeList.append(['ReadOnly', str(DistributionPackageHeader.ReadOnly).lower()]) if DistributionPackageHeader.RePackage != '': AttributeList.append(['RePackage', str(DistributionPackageHeader.RePackage).lower()]) - + if DistributionPackageHeader.GetAbstract(): + DPAbstract = DistributionPackageHeader.GetAbstract()[0][1] + else: + DPAbstract = '' + if DistributionPackageHeader.GetDescription(): + DPDescription = DistributionPackageHeader.GetDescription()[0][1] + else: + DPDescription = '' + if DistributionPackageHeader.GetCopyright(): + DPCopyright = DistributionPackageHeader.GetCopyright()[0][1] + else: + DPCopyright = '' + if DistributionPackageHeader.GetLicense(): + DPLicense = DistributionPackageHeader.GetLicense()[0][1] + else: + DPLicense = '' NodeList = [Element1, Element2, ['Vendor', DistributionPackageHeader.Vendor], ['Date', DistributionPackageHeader.Date], - ['Copyright', DistributionPackageHeader.GetCopyright()], - ['License', DistributionPackageHeader.GetLicense()], - ['Abstract', DistributionPackageHeader.GetAbstract()], - ['Description', \ - DistributionPackageHeader.GetDescription()], + ['Copyright', DPCopyright], + ['License', DPLicense], + ['Abstract', DPAbstract], + ['Description', DPDescription], ['Signature', DistributionPackageHeader.Signature], ['XmlSpecification', \ DistributionPackageHeader.XmlSpecification], ] Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList) - return Root def __str__(self): @@ -299,36 +359,63 @@ class PackageHeaderXml(object): IsRequiredItemListNull(CheckDict, XmlTreeLevel) self.PackagePath = XmlElement(Item, '%s/PackagePath' % Key) self.Header.FromXml(Item, Key) - PackageObject2.SetName(self.Header.Name) PackageObject2.SetBaseName(self.Header.BaseName) PackageObject2.SetGuid(self.Header.GUID) PackageObject2.SetVersion(self.Header.Version) - PackageObject2.SetCopyright(self.Header.Copyright) - PackageObject2.SetLicense(self.Header.License) - PackageObject2.SetAbstract(self.Header.Abstract) - PackageObject2.SetDescription(self.Header.Description) + PackageObject2.SetCopyright(self.Header.CopyrightList) + PackageObject2.SetLicense(self.Header.LicenseList) + PackageObject2.SetAbstract(self.Header.AbstractList) + PackageObject2.SetDescription(self.Header.DescriptionList) PackageObject2.SetPackagePath(self.PackagePath) def ToXml(self, PackageObject2, Key): if self.PackagePath: pass - Element1 = \ - CreateXmlElement('Name', PackageObject2.GetName(), [], \ + Element1 = CreateXmlElement('Name', PackageObject2.GetName(), [], \ [['BaseName', PackageObject2.GetBaseName()]]) Element2 = CreateXmlElement('GUID', PackageObject2.GetGuid(), [], \ [['Version', PackageObject2.GetVersion()]]) - AttributeList = [] NodeList = [Element1, - Element2, - ['Copyright', PackageObject2.GetCopyright()], - ['License', PackageObject2.GetLicense()], - ['Abstract', PackageObject2.GetAbstract()], - ['Description', PackageObject2.GetDescription()], - ['PackagePath', PackageObject2.GetPackagePath()], + Element2 ] + + UNIPackageAbrstractList = [] + UNIPackageDescriptionList = [] + # Get Abstract and Description from Uni File + # if the Uni File exists + if PackageObject2.UniFileClassObject is not None: + UniStrDict = PackageObject2.UniFileClassObject.OrderedStringList + for Lang in UniStrDict: + for StringDefClassObject in UniStrDict[Lang]: + if not StringDefClassObject.StringValue: + continue + if StringDefClassObject.StringName == DataType.TAB_DEC_PACKAGE_ABSTRACT: + UNIPackageAbrstractList.append((GetLanguageCode1766(Lang), + ConvertSpecialUnicodes(StringDefClassObject.StringValue))) + + if StringDefClassObject.StringName == DataType.TAB_DEC_PACKAGE_DESCRIPTION: + UNIPackageDescriptionList.append((GetLanguageCode1766(Lang), + ConvertSpecialUnicodes(StringDefClassObject.StringValue))) + + # Get Abstract and Description from DEC File Header + for (Lang, Value) in PackageObject2.GetCopyright(): + if Value: + NodeList.append(CreateXmlElement(DataType.TAB_HEADER_COPYRIGHT, Value, [], [])) + for (Lang, Value) in PackageObject2.GetLicense(): + if Value: + NodeList.append(CreateXmlElement(DataType.TAB_HEADER_LICENSE, Value, [], [])) + for (Lang, Value) in PackageObject2.GetAbstract() + UNIPackageAbrstractList: + if Value: + NodeList.append(CreateXmlElement(DataType.TAB_HEADER_ABSTRACT, Value, [], [['Lang', Lang]])) + for (Lang, Value) in PackageObject2.GetDescription() + UNIPackageDescriptionList: + if Value: + NodeList.append(CreateXmlElement(DataType.TAB_HEADER_DESCRIPTION, Value, [], [['Lang', Lang]])) + + + NodeList.append(['PackagePath', PackageObject2.GetPackagePath()]) + AttributeList = [] Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList) - return Root def __str__(self): @@ -351,7 +438,6 @@ class MiscellaneousFileXml(object): self.Header.FromXml(Item, Key) NewItem = XmlNode(Item, '%s/Header' % Key) self.Header.FromXml(NewItem, 'Header') - for SubItem in XmlList(Item, '%s/Filename' % Key): Filename = XmlElement(SubItem, '%s/Filename' % Key) Executable = XmlAttribute(XmlNode(SubItem, '%s/Filename' % Key), 'Executable') @@ -362,12 +448,11 @@ class MiscellaneousFileXml(object): else: Executable = '' self.Files.append([Filename, Executable]) - MiscFile = MiscFileObject() - MiscFile.SetCopyright(self.Header.Copyright) - MiscFile.SetLicense(self.Header.License) - MiscFile.SetAbstract(self.Header.Abstract) - MiscFile.SetDescription(self.Header.Description) + MiscFile.SetCopyright(self.Header.CopyrightList) + MiscFile.SetLicense(self.Header.LicenseList) + MiscFile.SetAbstract(self.Header.AbstractList) + MiscFile.SetDescription(self.Header.DescriptionList) MiscFileList = [] for File in self.Files: FileObj = FileObject() @@ -375,7 +460,6 @@ class MiscellaneousFileXml(object): FileObj.SetExecutable(File[1]) MiscFileList.append(FileObj) MiscFile.SetFileList(MiscFileList) - return MiscFile ## # This API is used for DistP's tool section @@ -383,10 +467,8 @@ class MiscellaneousFileXml(object): def FromXml2(self, Item, Key): if Item is None: return None - NewItem = XmlNode(Item, '%s/Header' % Key) self.Header.FromXml(NewItem, 'Header') - for SubItem in XmlList(Item, '%s/Filename' % Key): Filename = XmlElement(SubItem, '%s/Filename' % Key) Executable = \ @@ -399,13 +481,12 @@ class MiscellaneousFileXml(object): else: Executable = '' self.Files.append([Filename, Executable, OsType]) - MiscFile = MiscFileObject() MiscFile.SetName(self.Header.Name) - MiscFile.SetCopyright(self.Header.Copyright) - MiscFile.SetLicense(self.Header.License) - MiscFile.SetAbstract(self.Header.Abstract) - MiscFile.SetDescription(self.Header.Description) + MiscFile.SetCopyright(self.Header.CopyrightList) + MiscFile.SetLicense(self.Header.LicenseList) + MiscFile.SetAbstract(self.Header.AbstractList) + MiscFile.SetDescription(self.Header.DescriptionList) MiscFileList = [] for File in self.Files: FileObj = FileObject() @@ -414,7 +495,6 @@ class MiscellaneousFileXml(object): FileObj.SetOS(File[2]) MiscFileList.append(FileObj) MiscFile.SetFileList(MiscFileList) - return MiscFile ## @@ -424,19 +504,33 @@ class MiscellaneousFileXml(object): if self.Header: pass if MiscFile: - NodeList = [['Copyright', MiscFile.GetCopyright()], - ['License', MiscFile.GetLicense()], - ['Abstract', MiscFile.GetAbstract()], - ['Description', MiscFile.GetDescription()], + if MiscFile.GetAbstract(): + DPAbstract = MiscFile.GetAbstract()[0][1] + else: + DPAbstract = '' + if MiscFile.GetDescription(): + DPDescription = MiscFile.GetDescription()[0][1] + else: + DPDescription = '' + if MiscFile.GetCopyright(): + DPCopyright = MiscFile.GetCopyright()[0][1] + else: + DPCopyright = '' + if MiscFile.GetLicense(): + DPLicense = MiscFile.GetLicense()[0][1] + else: + DPLicense = '' + NodeList = [['Copyright', DPCopyright], + ['License', DPLicense], + ['Abstract', DPAbstract], + ['Description', DPDescription], ] - for File in MiscFile.GetFileList(): NodeList.append\ (CreateXmlElement\ ('Filename', File.GetURI(), [], \ [['Executable', str(File.GetExecutable()).lower()]])) Root = CreateXmlElement('%s' % Key, '', NodeList, []) - return Root ## # This API is used for DistP's tool section @@ -445,15 +539,30 @@ class MiscellaneousFileXml(object): if self.Header: pass if MiscFile: + if MiscFile.GetAbstract(): + DPAbstract = MiscFile.GetAbstract()[0][1] + else: + DPAbstract = '' + if MiscFile.GetDescription(): + DPDescription = MiscFile.GetDescription()[0][1] + else: + DPDescription = '' + if MiscFile.GetCopyright(): + DPCopyright = MiscFile.GetCopyright()[0][1] + else: + DPCopyright = '' + if MiscFile.GetLicense(): + DPLicense = MiscFile.GetLicense()[0][1] + else: + DPLicense = '' NodeList = [['Name', MiscFile.GetName()], - ['Copyright', MiscFile.GetCopyright()], - ['License', MiscFile.GetLicense()], - ['Abstract', MiscFile.GetAbstract()], - ['Description', MiscFile.GetDescription()], + ['Copyright', DPCopyright], + ['License', DPLicense], + ['Abstract', DPAbstract], + ['Description', DPDescription], ] HeaderNode = CreateXmlElement('Header', '', NodeList, []) NodeList = [HeaderNode] - for File in MiscFile.GetFileList(): NodeList.append\ (CreateXmlElement\ @@ -461,7 +570,6 @@ class MiscellaneousFileXml(object): [['Executable', str(File.GetExecutable()).lower()], \ ['OS', File.GetOS()]])) Root = CreateXmlElement('%s' % Key, '', NodeList, []) - return Root def __str__(self): @@ -476,6 +584,11 @@ class UserExtensionsXml(object): def __init__(self): self.UserId = '' self.Identifier = '' + self.BinaryAbstractList = [] + self.BinaryDescriptionList = [] + self.BinaryCopyrightList = [] + self.BinaryLicenseList = [] + self.LangDefsList = [] self.DefineDict = {} self.BuildOptionDict = {} self.IncludesDict = {} @@ -489,51 +602,64 @@ class UserExtensionsXml(object): def FromXml2(self, Item, Key): self.UserId = XmlAttribute(XmlNode(Item, '%s' % Key), 'UserId') self.Identifier = XmlAttribute(XmlNode(Item, '%s' % Key), 'Identifier') - UserExtension = UserExtensionObject() UserExtension.SetUserID(self.UserId) UserExtension.SetIdentifier(self.Identifier) - return UserExtension def FromXml(self, Item, Key): self.UserId = XmlAttribute(XmlNode(Item, '%s' % Key), 'UserId') self.Identifier = XmlAttribute(XmlNode(Item, '%s' % Key), 'Identifier') + if self.UserId == DataType.TAB_BINARY_HEADER_USERID \ + and self.Identifier == DataType.TAB_BINARY_HEADER_IDENTIFIER: + for SubItem in XmlList(Item, '%s/BinaryAbstract' % Key): + BinaryAbstractLang = XmlAttribute(SubItem, 'Lang') + self.BinaryAbstractList.append((BinaryAbstractLang, XmlElement(SubItem, '%s/BinaryAbstract' % Key))) + for SubItem in XmlList(Item, '%s/BinaryDescription' % Key): + BinaryDescriptionLang = XmlAttribute(SubItem, 'Lang') + self.BinaryDescriptionList.append((BinaryDescriptionLang, + XmlElement(SubItem, '%s/BinaryDescription' % Key))) + for SubItem in XmlList(Item, '%s/BinaryCopyright' % Key): + BinaryCopyrightLang = XmlAttribute(SubItem, 'Lang') + self.BinaryCopyrightList.append((BinaryCopyrightLang, + XmlElement(SubItem, '%s/BinaryCopyright' % Key))) + for SubItem in XmlList(Item, '%s/BinaryLicense' % Key): + BinaryLicenseLang = XmlAttribute(SubItem, 'Lang') + self.BinaryLicenseList.append((BinaryLicenseLang, + XmlElement(SubItem, '%s/BinaryLicense' % Key))) DefineItem = XmlNode(Item, '%s/Define' % Key) for SubItem in XmlList(DefineItem, 'Define/Statement'): Statement = XmlElement(SubItem, '%s/Statement' % Key) self.DefineDict[Statement] = "" - BuildOptionItem = XmlNode(Item, '%s/BuildOption' % Key) for SubItem in XmlList(BuildOptionItem, 'BuildOption/Statement'): Statement = XmlElement(SubItem, '%s/Statement' % Key) Arch = XmlAttribute(XmlNode(SubItem, '%s/Statement' % Key), 'SupArchList') self.BuildOptionDict[Arch] = Statement - IncludesItem = XmlNode(Item, '%s/Includes' % Key) for SubItem in XmlList(IncludesItem, 'Includes/Statement'): Statement = XmlElement(SubItem, '%s/Statement' % Key) Arch = XmlAttribute(XmlNode(SubItem, '%s/Statement' % Key), 'SupArchList') self.IncludesDict[Statement] = Arch - SourcesItem = XmlNode(Item, '%s/Sources' % Key) Tmp = UserExtensionSourceXml() SourceDict = Tmp.FromXml(SourcesItem, 'Sources') self.SourcesDict = SourceDict - BinariesItem = XmlNode(Item, '%s/Binaries' % Key) Tmp = UserExtensionBinaryXml() BinariesDict = Tmp.FromXml(BinariesItem, 'Binaries') self.BinariesDict = BinariesDict - self.Statement = XmlElement(Item, 'UserExtensions') SupArch = XmlAttribute(XmlNode(Item, '%s' % Key), 'SupArchList') self.SupArchList = [Arch for Arch in GetSplitValueList(SupArch, DataType.TAB_SPACE_SPLIT) if Arch] - UserExtension = UserExtensionObject() UserExtension.SetUserID(self.UserId) UserExtension.SetIdentifier(self.Identifier) + UserExtension.SetBinaryAbstract(self.BinaryAbstractList) + UserExtension.SetBinaryDescription(self.BinaryDescriptionList) + UserExtension.SetBinaryCopyright(self.BinaryCopyrightList) + UserExtension.SetBinaryLicense(self.BinaryLicenseList) UserExtension.SetStatement(self.Statement) UserExtension.SetSupArchList(self.SupArchList) UserExtension.SetDefinesDict(self.DefineDict) @@ -541,22 +667,37 @@ class UserExtensionsXml(object): UserExtension.SetIncludesDict(self.IncludesDict) UserExtension.SetSourcesDict(self.SourcesDict) UserExtension.SetBinariesDict(self.BinariesDict) - return UserExtension def ToXml(self, UserExtension, Key): if self.UserId: pass - AttributeList = [['UserId', str(UserExtension.GetUserID())], ['Identifier', str(UserExtension.GetIdentifier())], ['SupArchList', \ GetStringOfList(UserExtension.GetSupArchList())], ] - Root = CreateXmlElement('%s' % Key, UserExtension.GetStatement(), [], \ - AttributeList) - + AttributeList) + if UserExtension.GetIdentifier() == DataType.TAB_BINARY_HEADER_IDENTIFIER and \ + UserExtension.GetUserID() == DataType.TAB_BINARY_HEADER_USERID: + for (Lang, Value) in UserExtension.GetBinaryAbstract(): + if Value: + ChildElement = CreateXmlElement('BinaryAbstract', Value, [], [['Lang', Lang]]) + Root.appendChild(ChildElement) + for (Lang, Value) in UserExtension.GetBinaryDescription(): + if Value: + ChildElement = CreateXmlElement('BinaryDescription', Value, [], [['Lang', Lang]]) + Root.appendChild(ChildElement) + for (Lang, Value) in UserExtension.GetBinaryCopyright(): + if Value: + ChildElement = CreateXmlElement('BinaryCopyright', Value, [], []) + Root.appendChild(ChildElement) + for (Lang, Value) in UserExtension.GetBinaryLicense(): + if Value: + ChildElement = CreateXmlElement('BinaryLicense', Value, [], []) + Root.appendChild(ChildElement) + NodeList = [] DefineDict = UserExtension.GetDefinesDict() if DefineDict: @@ -565,7 +706,6 @@ class UserExtensionsXml(object): ('Statement', Item, [], [])) DefineElement = CreateXmlElement('Define', '', NodeList, []) Root.appendChild(DefineElement) - NodeList = [] BuildOptionDict = UserExtension.GetBuildOptionDict() if BuildOptionDict: @@ -576,7 +716,6 @@ class UserExtensionsXml(object): BuildOptionElement = \ CreateXmlElement('BuildOption', '', NodeList, []) Root.appendChild(BuildOptionElement) - NodeList = [] IncludesDict = UserExtension.GetIncludesDict() if IncludesDict: @@ -586,19 +725,16 @@ class UserExtensionsXml(object): [['SupArchList', IncludesDict[Item]]])) IncludesElement = CreateXmlElement('Includes', '', NodeList, []) Root.appendChild(IncludesElement) - NodeList = [] SourcesDict = UserExtension.GetSourcesDict() if SourcesDict: Tmp = UserExtensionSourceXml() Root.appendChild(Tmp.ToXml(SourcesDict, 'Sources')) - NodeList = [] BinariesDict = UserExtension.GetBinariesDict() if BinariesDict: Tmp = UserExtensionBinaryXml() Root.appendChild(Tmp.ToXml(BinariesDict, 'Binaries')) - return Root def __str__(self): @@ -620,7 +756,6 @@ class UserExtensionSourceXml(object): if self.UserExtensionSource: pass Dict = {} - #SourcesItem = XmlNode(Item, '%s/Sources' % Key) for SubItem in XmlList(Item, 'Sources/SourceFile'): FileName = XmlElement(SubItem, 'SourceFile/FileName') @@ -628,7 +763,6 @@ class UserExtensionSourceXml(object): FeatureFlag = XmlElement(SubItem, 'SourceFile/FeatureFlag') SupArchStr = XmlElement(SubItem, 'SourceFile/SupArchList') DictKey = (FileName, Family, FeatureFlag, SupArchStr) - ValueList = [] for ValueNodeItem in XmlList(SubItem, \ 'SourceFile/SourceFileOtherAttr'): @@ -643,9 +777,7 @@ class UserExtensionSourceXml(object): ToolCode = '' Comment = '' ValueList.append((TagName, ToolCode, Comment)) - Dict[DictKey] = ValueList - return Dict def ToXml(self, Dict, Key): @@ -690,16 +822,13 @@ class UserExtensionBinaryXml(object): pass if self.UserExtensionBinary: pass - Dict = {} - for SubItem in XmlList(Item, 'Binaries/Binary'): FileName = XmlElement(SubItem, 'Binary/FileName') FileType = XmlElement(SubItem, 'Binary/FileType') FFE = XmlElement(SubItem, 'Binary/FeatureFlag') SupArch = XmlElement(SubItem, 'Binary/SupArchList') DictKey = (FileName, FileType, ConvertNOTEQToNE(FFE), SupArch) - ValueList = [] for ValueNodeItem in XmlList(SubItem, \ 'Binary/BinaryFileOtherAttr'): @@ -719,9 +848,7 @@ class UserExtensionBinaryXml(object): Comment = '' ValueList.append((Target, Family, TagName, Comment)) - Dict[DictKey] = ValueList - return Dict def ToXml(self, Dict, Key): @@ -777,7 +904,6 @@ class LibraryClassXml(object): HelpTextObj = HelpTextXml() HelpTextObj.FromXml(HelpTextItem, '%s/HelpText' % Key) self.HelpText.append(HelpTextObj) - LibraryClass = LibraryClassObject() LibraryClass.SetLibraryClass(self.Keyword) LibraryClass.SetIncludeHeader(self.HeaderFile) @@ -787,7 +913,6 @@ class LibraryClassXml(object): LibraryClass.SetSupModuleList(self.CommonDefines.SupModList) LibraryClass.SetFeatureFlag(ConvertNOTEQToNE(self.CommonDefines.FeatureFlag)) LibraryClass.SetHelpTextList(GetHelpTextList(self.HelpText)) - return LibraryClass def ToXml(self, LibraryClass, Key): @@ -802,17 +927,13 @@ class LibraryClassXml(object): for Item in LibraryClass.GetHelpTextList(): Tmp = HelpTextXml() NodeList.append(Tmp.ToXml(Item)) - Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList) - return Root def ToXml2(self, LibraryClass, Key): if self.HeaderFile: pass - FeatureFlag = ConvertNEToNOTEQ(LibraryClass.GetFeatureFlag()) - AttributeList = \ [['Usage', LibraryClass.GetUsage()], \ ['SupArchList', GetStringOfList(LibraryClass.GetSupArchList())], \ @@ -823,9 +944,7 @@ class LibraryClassXml(object): for Item in LibraryClass.GetHelpTextList(): Tmp = HelpTextXml() NodeList.append(Tmp.ToXml(Item)) - Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList) - return Root def __str__(self): @@ -847,18 +966,18 @@ class FilenameXml(object): def FromXml(self, Item, Key): self.FileType = XmlAttribute(Item, 'FileType') + Guid = XmlAttribute(Item, 'GUID') self.Filename = XmlElement(Item, 'Filename') self.CommonDefines.FromXml(Item, Key) - FeatureFlag = ConvertNOTEQToNE(self.CommonDefines.FeatureFlag) - Filename = FileNameObject() # # Convert File Type # if self.FileType == 'UEFI_IMAGE': self.FileType = 'PE32' - + + Filename.SetGuidValue(Guid) Filename.SetFileType(self.FileType) Filename.SetFilename(self.Filename) Filename.SetSupArchList(self.CommonDefines.SupArchList) @@ -873,6 +992,7 @@ class FilenameXml(object): GetStringOfList(Filename.GetSupArchList())], ['FileType', Filename.GetFileType()], ['FeatureFlag', ConvertNEToNOTEQ(Filename.GetFeatureFlag())], + ['GUID', Filename.GetGuidValue()] ] Root = CreateXmlElement('%s' % Key, Filename.GetFilename(), [], AttributeList) diff --git a/BaseTools/Source/Python/UPT/Xml/IniToXml.py b/BaseTools/Source/Python/UPT/Xml/IniToXml.py index 4be20d00ca..037471056d 100644 --- a/BaseTools/Source/Python/UPT/Xml/IniToXml.py +++ b/BaseTools/Source/Python/UPT/Xml/IniToXml.py @@ -1,7 +1,7 @@ ## @file # This file is for converting package information data file to xml file. # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -32,6 +32,7 @@ from Library.DataType import TAB_SECTION_END from Logger import StringTable as ST from Library.String import ConvertSpecialChar from Library.ParserValidate import IsValidPath +from Library import GlobalData ## log error: # @@ -58,9 +59,7 @@ def __ValidatePath(Path, Root): # @param Filename: File to be checked # def ValidateMiscFile(Filename): - Root = '' - if 'WORKSPACE' in os.environ: - Root = os.environ['WORKSPACE'] + Root = GlobalData.gWORKSPACE return __ValidatePath(Filename, Root) ## ValidateToolsFile @@ -71,8 +70,8 @@ def ValidateToolsFile(Filename): Valid, Cause = False, '' if not Valid and 'EDK_TOOLS_PATH' in os.environ: Valid, Cause = __ValidatePath(Filename, os.environ['EDK_TOOLS_PATH']) - if not Valid and 'WORKSPACE' in os.environ: - Valid, Cause = __ValidatePath(Filename, os.environ['WORKSPACE']) + if not Valid: + Valid, Cause = __ValidatePath(Filename, GlobalData.gWORKSPACE) return Valid, Cause ## ParseFileList @@ -332,7 +331,7 @@ def IniToXml(IniFile): for Index in range(0, len(FileContent)): LastIndex = Index Line = FileContent[Index].strip() - if Line == '': + if Line == '' or Line.startswith(';'): continue if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END: CurrentKey = '' diff --git a/BaseTools/Source/Python/UPT/Xml/ModuleSurfaceAreaXml.py b/BaseTools/Source/Python/UPT/Xml/ModuleSurfaceAreaXml.py index 9e141cabb4..d117468a17 100644 --- a/BaseTools/Source/Python/UPT/Xml/ModuleSurfaceAreaXml.py +++ b/BaseTools/Source/Python/UPT/Xml/ModuleSurfaceAreaXml.py @@ -3,9 +3,9 @@ # # Copyright (c) 2011 - 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 +# 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, @@ -67,7 +67,7 @@ from Library.Misc import GetSplitValueList #
{1,} # ... {0,} # {1,} -# +# class BinaryFileXml(object): def __init__(self): self.FileNames = [] @@ -82,11 +82,16 @@ class BinaryFileXml(object): pass BinaryFile = BinaryFileObject() FilenameList = [] + SupArchList = ['COMMON'] for SubItem in XmlList(Item, '%s/Filename' % Key): Axml = FilenameXml() Bxml = Axml.FromXml(SubItem, 'Filename') FilenameList.append(Bxml) BinaryFile.SetFileNameList(FilenameList) + for FileName in FilenameList: + if FileName.GetSupArchList(): + SupArchList = FileName.GetSupArchList() + BinaryFile.SetSupArchList(SupArchList) if GlobalData.gIS_BINARY_INF: AsBuiltList = [] for AsBuiltItem in XmlList(Item, '%s/AsBuilt' % Key): @@ -135,42 +140,44 @@ class BinaryFileXml(object): NodeList.append(Tmp.ToXml(Filename, 'Filename')) SupportArch = Filename.SupArchList - if GlobalData.gIS_BINARY_INF: - AsBuildList = BinaryFile.GetAsBuiltList() - PatchPcdValueList = AsBuildList.GetPatchPcdList() - PcdExList = AsBuildList.GetPcdExList() - LibGuidVerList = AsBuildList.GetLibraryInstancesList() - BuildFlagList = AsBuildList.GetBuildFlagsList() - - AsBuiltNodeList = [] - - for Pcd in PatchPcdValueList: - if IsMatchArch(Pcd.SupArchList, SupportArch): - Tmp = PcdEntryXml() - AsBuiltNodeList.append(Tmp.ToXml4(Pcd, 'PatchPcdValue')) - - for Pcd in PcdExList: - if IsMatchArch(Pcd.SupArchList, SupportArch): - Tmp = PcdEntryXml() - AsBuiltNodeList.append(Tmp.ToXml4(Pcd, 'PcdExValue')) - - GuiVerElemList = [] - for LibGuidVer in LibGuidVerList: + AsBuildList = BinaryFile.GetAsBuiltList() + PatchPcdValueList = AsBuildList.GetPatchPcdList() + PcdExList = AsBuildList.GetPcdExList() + LibGuidVerList = AsBuildList.GetLibraryInstancesList() + BuildFlagList = AsBuildList.GetBuildFlagsList() + + AsBuiltNodeList = [] + + for Pcd in PatchPcdValueList: + if IsMatchArch(Pcd.SupArchList, SupportArch): + Tmp = PcdEntryXml() + AsBuiltNodeList.append(Tmp.ToXml4(Pcd, 'PatchPcdValue')) + + for Pcd in PcdExList: + if IsMatchArch(Pcd.SupArchList, SupportArch): + Tmp = PcdEntryXml() + AsBuiltNodeList.append(Tmp.ToXml4(Pcd, 'PcdExValue')) + + GuiVerElemList = [] + for LibGuidVer in LibGuidVerList: + if IsMatchArch(LibGuidVer.GetSupArchList(), SupportArch): GuiVerElem = \ CreateXmlElement('GUID', LibGuidVer.GetLibGuid(), [], [['Version', LibGuidVer.GetLibVersion()]]) GuiVerElemList.append(GuiVerElem) - if len(GuiVerElemList) > 0: - LibGuidVerElem = CreateXmlElement('LibraryInstances', '', GuiVerElemList, []) - AsBuiltNodeList.append(LibGuidVerElem) + if len(GuiVerElemList) > 0: + LibGuidVerElem = CreateXmlElement('LibraryInstances', '', GuiVerElemList, []) + AsBuiltNodeList.append(LibGuidVerElem) - for BuildFlag in BuildFlagList: - Tmp = BuildFlagXml() - Elem = CreateXmlElement('BuildFlags', ''.join(BuildFlag), [], []) - AsBuiltNodeList.append(Elem) + for BuildFlag in BuildFlagList: + if IsMatchArch(BuildFlag.GetSupArchList(), SupportArch): + for Item in BuildFlag.GetAsBuildList(): + Tmp = BuildFlagXml() + Elem = CreateXmlElement('BuildFlags', ''.join(Item), [], []) + AsBuiltNodeList.append(Elem) - if len(AsBuiltNodeList) > 0: - Element = CreateXmlElement('AsBuilt', '', AsBuiltNodeList, []) - NodeList.append(Element) + if len(AsBuiltNodeList) > 0: + Element = CreateXmlElement('AsBuilt', '', AsBuiltNodeList, []) + NodeList.append(Element) Root = CreateXmlElement('%s' % Key, '', NodeList, []) @@ -286,7 +293,7 @@ class ExternXml(object): for Item in self.HelpText: Str = Str + '\n\t' + str(Item) return Str -## +## # DepexXml # class DepexXml(object): @@ -654,7 +661,7 @@ class ModuleSurfaceAreaXml(object): else: Module.SetMiscFileList([]) - # + # # UserExtensions # for Item in XmlList(Item, '/ModuleSurfaceArea/UserExtensions'): @@ -740,7 +747,7 @@ class ModuleSurfaceAreaXml(object): not XmlList(Item, '/ModuleSurfaceArea/PackageDependencies/Package'): Module.SetPackageDependencyList([None]) - # + # # Guid # for SubItem in XmlList(Item, '/ModuleSurfaceArea/Guids/GuidCName'): diff --git a/BaseTools/Source/Python/UPT/Xml/PackageSurfaceAreaXml.py b/BaseTools/Source/Python/UPT/Xml/PackageSurfaceAreaXml.py index 85062ac883..d6ed8c5e3b 100644 --- a/BaseTools/Source/Python/UPT/Xml/PackageSurfaceAreaXml.py +++ b/BaseTools/Source/Python/UPT/Xml/PackageSurfaceAreaXml.py @@ -1,7 +1,7 @@ ## @file # This file is used to parse a Package file of .PKG file # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -254,6 +254,16 @@ class PackageSurfaceAreaXml(object): Tmp = PcdEntryXml() PcdEntry = Tmp.FromXml2(SubItem, 'PcdEntry') Package.SetPcdList(Package.GetPcdList() + [PcdEntry]) + + # + # Get PcdErrorCommentDict from PcdError in PcdEntry Node + # + for PcdErrorObj in PcdEntry.GetPcdErrorsList(): + PcdErrorMessageList = PcdErrorObj.GetErrorMessageList() + if PcdErrorMessageList: + Package.PcdErrorCommentDict[(PcdEntry.GetTokenSpaceGuidCName(), PcdErrorObj.GetErrorNumber())] = \ + PcdErrorMessageList + if XmlList(Item, '/PackageSurfaceArea/PcdDeclarations') and not \ XmlList(Item, '/PackageSurfaceArea/PcdDeclarations/PcdEntry'): diff --git a/BaseTools/Source/Python/UPT/Xml/PcdXml.py b/BaseTools/Source/Python/UPT/Xml/PcdXml.py index d1f1332726..4603918bab 100644 --- a/BaseTools/Source/Python/UPT/Xml/PcdXml.py +++ b/BaseTools/Source/Python/UPT/Xml/PcdXml.py @@ -1,7 +1,7 @@ ## @file # This file is used to parse a PCD file of .PKG file # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -32,8 +32,11 @@ from Library import GlobalData from Object.POM.CommonObject import PcdObject from Object.POM.CommonObject import PcdErrorObject from Xml.CommonXml import HelpTextXml +from Xml.CommonXml import PromptXml from Xml.CommonXml import CommonDefinesXml from Xml.XmlParserMisc import GetHelpTextList +from Xml.XmlParserMisc import GetPromptList +import re ## # PcdErrorXml @@ -51,7 +54,7 @@ class PcdErrorXml(object): self.ValidValueList = XmlElement(Item, '%s/ValidValueList' % Key) self.ValidValueListLang = \ XmlAttribute(XmlNode(Item, '%s/ValidValueList' % Key), 'Lang') - self.ValidValueRange = XmlElement(Item, '%s/ValidValueRange' % Key) + self.ValidValueRange = self.TransferValidEpxr2ValidRange(XmlElement(Item, '%s/ValidValueRange' % Key)) self.Expression = XmlElement(Item, '%s/Expression' % Key) self.ErrorNumber = XmlElement(Item, '%s/ErrorNumber' % Key) for ErrMsg in XmlList(Item, '%s/ErrorMessage' % Key): @@ -81,9 +84,12 @@ class PcdErrorXml(object): [['Lang', PcdError.GetValidValueLang()]]) NodeList.append(Element1) if PcdError.GetValidValueRange(): + TansferedRangeStr = self.TransferValidRange2Expr(PcdError.GetTokenSpaceGuidCName(), + PcdError.GetCName(), + PcdError.GetValidValueRange()) Element1 = \ CreateXmlElement('ValidValueRange', \ - PcdError.GetValidValueRange(), [], []) + TansferedRangeStr, [], []) NodeList.append(Element1) if PcdError.GetExpression(): NodeList.append(['Expression', PcdError.GetExpression()]) @@ -96,6 +102,147 @@ class PcdErrorXml(object): Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList) return Root + + def TransferValidRange2Expr(self, TokenSpaceGuidCName, CName, ValidRange): + if self.Expression: + pass + INT_RANGE_PATTERN1 = '[\t\s]*[0-9]+[\t\s]*-[\t\s]*[0-9]+' + INT_RANGE_PATTERN2 = '[\t\s]*(LT|GT|LE|GE|XOR|EQ)[\t\s]+\d+[\t\s]*' + HEX_RANGE_PATTERN1 = \ + '[\t\s]*0[xX][a-fA-F0-9]+[\t\s]*-[\t\s]*0[xX][a-fA-F0-9]+' + HEX_RANGE_PATTERN2 = '[\t\s]*(LT|GT|LE|GE|XOR|EQ)[\t\s]+0[xX][a-fA-F0-9]+[\t\s]*' + IntMatch1 = re.compile(INT_RANGE_PATTERN1) + IntMatch2 = re.compile(INT_RANGE_PATTERN2) + HexMatch1 = re.compile(HEX_RANGE_PATTERN1) + HexMatch2 = re.compile(HEX_RANGE_PATTERN2) + PcdName = '.'.join([TokenSpaceGuidCName, CName]) + HexMatchedList = [] + IntMatchedList = [] + # + # Convert HEX2 format range + # + if HexMatch2: + for MatchObj in HexMatch2.finditer(ValidRange): + MatchStr = MatchObj.group() + TransferedRangeStr = ' '.join(['', PcdName, MatchStr.strip()]) + ValidRange = ValidRange.replace(MatchStr, TransferedRangeStr) + # + # Convert INT2 format range + # + if IntMatch2: + for MatchObj in IntMatch2.finditer(ValidRange): + MatchStr = MatchObj.group() + TransferedRangeStr = ' '.join(['', PcdName, MatchStr.strip()]) + ValidRange = ValidRange.replace(MatchStr, TransferedRangeStr) + # + # Convert HEX1 format range + # + if HexMatch1: + HexMatchedList += HexMatch1.findall(ValidRange) + + for MatchStr in HexMatchedList: + RangeItemList = MatchStr.strip().split('-') + TransferedRangeStr = '(%s GE %s) AND (%s LE %s)' % \ + (PcdName, RangeItemList[0].strip(), PcdName, RangeItemList[1].strip()) + ValidRange = ValidRange.replace(MatchStr, TransferedRangeStr) + # + # Convert INT1 format range + # + if IntMatch1: + IntMatchedList += IntMatch1.findall(ValidRange) + + for MatchStr in IntMatchedList: + RangeItemList = MatchStr.strip().split('-') + TransferedRangeStr = '(%s GE %s) AND (%s LE %s)' % \ + (PcdName, RangeItemList[0].strip(), PcdName, RangeItemList[1].strip()) + ValidRange = ValidRange.replace(MatchStr, TransferedRangeStr) + + return ValidRange + + def TransferValidEpxr2ValidRange(self, ValidRangeExpr): + if self.Expression: + pass + + PCD_PATTERN = \ + '[\t\s]*[_a-zA-Z][a-zA-Z0-9_]*[\t\s]*\.[\t\s]*[_a-zA-Z][a-zA-Z0-9_]*[\t\s]*' + IntPattern1 = \ + '[\t\s]*\([\t\s]*'+PCD_PATTERN+'[\t\s]+GE[\t\s]+\d+[\t\s]*\)[\t\s]+AND[\t\s]+\([\t\s]*'+\ + PCD_PATTERN+'[\t\s]+LE[\t\s]+\d+[\t\s]*\)' + IntPattern1 = IntPattern1.replace(' ', '') + IntPattern2 = '[\t\s]*'+PCD_PATTERN+'[\t\s]+(LT|GT|LE|GE|XOR|EQ)[\t\s]+\d+[\t\s]*' + + HexPattern1 = \ + '[\t\s]*\([\t\s]*'+PCD_PATTERN+'[\t\s]+GE[\t\s]+0[xX][0-9a-fA-F]+[\t\s]*\)[\t\s]+AND[\t\s]+\([\t\s]*'+\ + PCD_PATTERN+'[\t\s]+LE[\t\s]+0[xX][0-9a-fA-F]+[\t\s]*\)' + HexPattern1 = HexPattern1.replace(' ', '') + HexPattern2 = '[\t\s]*'+PCD_PATTERN+'[\t\s]+(LT|GT|LE|GE|XOR|EQ)[\t\s]+0[xX][0-9a-zA-Z]+[\t\s]*' + + # + # Do the Hex1 conversion + # + HexMatchedList = re.compile(HexPattern1).findall(ValidRangeExpr) + HexRangeDict = {} + for HexMatchedItem in HexMatchedList: + # + # To match items on both sides of '-' + # + RangeItemList = re.compile('[\t\s]*0[xX][0-9a-fA-F]+[\t\s]*').findall(HexMatchedItem) + if RangeItemList and len(RangeItemList) == 2: + HexRangeDict[HexMatchedItem] = RangeItemList + + for Key in HexRangeDict.keys(): + MaxItem = MixItem = '' + if int(HexRangeDict[Key][0], 16) > int(HexRangeDict[Key][1], 16): + MaxItem = HexRangeDict[Key][0] + MixItem = HexRangeDict[Key][1] + else: + MaxItem = HexRangeDict[Key][1] + MixItem = HexRangeDict[Key][0] + + Range = ' %s - %s' % (MixItem.strip(), MaxItem.strip()) + ValidRangeExpr = ValidRangeExpr.replace(Key, Range) + # + # Do the INT1 conversion + # + IntRangeDict = {} + IntMatchList = re.compile(IntPattern1).findall(ValidRangeExpr) + for MatchedItem in IntMatchList: + # + # To match items on both sides of '-' + # + RangeItemList = re.compile('[\t\s]*\d+[\t\s]*').findall(MatchedItem) + if RangeItemList and len(RangeItemList) == 2: + IntRangeDict[MatchedItem] = RangeItemList + + for Key in IntRangeDict.keys(): + MaxItem = MixItem = '' + if int(IntRangeDict[Key][0]) > int(IntRangeDict[Key][1]): + MaxItem = IntRangeDict[Key][0] + MixItem = IntRangeDict[Key][1] + else: + MaxItem = IntRangeDict[Key][1] + MixItem = IntRangeDict[Key][0] + + Range = ' %s - %s' % (MixItem.strip(), MaxItem.strip()) + ValidRangeExpr = ValidRangeExpr.replace(Key, Range) + # + # Do the HEX2 conversion + # + for MatchObj in re.compile(HexPattern2).finditer(ValidRangeExpr): + MatchStr = MatchObj.group() + Range = re.compile(PCD_PATTERN).sub(' ', MatchStr) + ValidRangeExpr = ValidRangeExpr.replace(MatchStr, Range) + # + # Do the INT2 conversion + # + for MatchObj in re.compile(IntPattern2).finditer(ValidRangeExpr): + MatchStr = MatchObj.group() + Range = re.compile(PCD_PATTERN).sub(' ', MatchStr) + ValidRangeExpr = ValidRangeExpr.replace(MatchStr, Range) + + return ValidRangeExpr + + def __str__(self): return "ValidValueList = %s ValidValueListLang = %s ValidValueRange \ @@ -122,6 +269,7 @@ class PcdEntryXml(object): self.Value = '' self.Offset = '' self.CommonDefines = CommonDefinesXml() + self.Prompt = [] self.HelpText = [] self.PcdError = [] @@ -149,6 +297,7 @@ class PcdEntryXml(object): self.Value = XmlElement(Item, '%s/Value' % Key) self.Offset = XmlElement(Item, '%s/Offset' % Key) self.CommonDefines.FromXml(XmlNode(Item, '%s' % Key), Key) + for HelpTextItem in XmlList(Item, '%s/HelpText' % Key): HelpTextObj = HelpTextXml() HelpTextObj.FromXml(HelpTextItem, '%s/HelpText' % Key) @@ -192,6 +341,10 @@ class PcdEntryXml(object): self.DefaultValue = XmlElement(Item, '%s/DefaultValue' % Key) self.MaxDatumSize = XmlElement(Item, '%s/MaxDatumSize' % Key) self.CommonDefines.FromXml(XmlNode(Item, '%s' % Key), Key) + for PromptItem in XmlList(Item, '%s/Prompt' % Key): + PromptObj = PromptXml() + PromptObj.FromXml(PromptItem, '%s/Prompt' % Key) + self.Prompt.append(PromptObj) for HelpTextItem in XmlList(Item, '%s/HelpText' % Key): HelpTextObj = HelpTextXml() HelpTextObj.FromXml(HelpTextItem, '%s/HelpText' % Key) @@ -214,7 +367,8 @@ class PcdEntryXml(object): PcdEntry.SetDefaultValue(self.DefaultValue) PcdEntry.SetMaxDatumSize(self.MaxDatumSize) PcdEntry.SetFeatureFlag(ConvertNOTEQToNE(self.CommonDefines.FeatureFlag)) - + + PcdEntry.SetPromptList(GetPromptList(self.Prompt)) PcdEntry.SetHelpTextList(GetHelpTextList(self.HelpText)) PcdEntry.SetPcdErrorsList(self.PcdError) @@ -311,6 +465,10 @@ class PcdEntryXml(object): ['DefaultValue', DefaultValue], ['MaxDatumSize', PcdEntry.GetMaxDatumSize()], ] + for Item in PcdEntry.GetPromptList(): + Tmp = PromptXml() + NodeList.append(Tmp.ToXml(Item)) + for Item in PcdEntry.GetHelpTextList(): Tmp = HelpTextXml() NodeList.append(Tmp.ToXml(Item)) @@ -400,4 +558,4 @@ class PcdEntryXml(object): Str = Str + "\n\t" + str(Item) for Item in self.PcdError: Str = Str + "\n\tPcdError:" + str(Item) - return Str \ No newline at end of file + return Str diff --git a/BaseTools/Source/Python/UPT/Xml/XmlParser.py b/BaseTools/Source/Python/UPT/Xml/XmlParser.py index 5a2f0dc705..58959081d0 100644 --- a/BaseTools/Source/Python/UPT/Xml/XmlParser.py +++ b/BaseTools/Source/Python/UPT/Xml/XmlParser.py @@ -1,7 +1,7 @@ ## @file # This file is used to parse a xml file of .PKG file # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -38,7 +38,6 @@ from Logger.StringTable import ERR_XML_INVALID_EXTERN_SUPARCHLIST from Logger.StringTable import ERR_XML_INVALID_EXTERN_SUPMODLIST from Logger.StringTable import ERR_XML_INVALID_EXTERN_SUPMODLIST_NOT_LIB from Logger.StringTable import ERR_FILE_NAME_INVALIDE -from Logger.StringTable import ERR_XML_INVALID_BINARY_FILE_TYPE from Logger.ToolError import PARSER_ERROR from Logger.ToolError import FORMAT_INVALID @@ -78,12 +77,25 @@ class DistributionPackageXml(object): DpHeader = self.DistP.Header XmlTreeLevel = ['DistributionPackage', 'DistributionHeader'] CheckDict = Sdict() + if DpHeader.GetAbstract(): + DPAbstract = DpHeader.GetAbstract()[0][1] + else: + DPAbstract = '' + if DpHeader.GetCopyright(): + DPCopyright = DpHeader.GetCopyright()[0][1] + else: + DPCopyright = '' + if DpHeader.GetLicense(): + DPLicense = DpHeader.GetLicense()[0][1] + else: + DPLicense = '' + CheckDict['Name'] = DpHeader.GetName() CheckDict['GUID'] = DpHeader.GetGuid() CheckDict['Version'] = DpHeader.GetVersion() - CheckDict['Copyright'] = DpHeader.GetCopyright() - CheckDict['License'] = DpHeader.GetLicense() - CheckDict['Abstract'] = DpHeader.GetAbstract() + CheckDict['Copyright'] = DPCopyright + CheckDict['License'] = DPLicense + CheckDict['Abstract'] = DPAbstract CheckDict['Vendor'] = DpHeader.GetVendor() CheckDict['Date'] = DpHeader.GetDate() CheckDict['XmlSpecification'] = DpHeader.GetXmlSpecification() @@ -610,11 +622,6 @@ def ValidateMS2(Module, TopXmlTreeLevel): if Item and len(Item.FileNamList) > 0 and Item.FileNamList[0].FileType == 'FREEFORM': Item.FileNamList[0].FileType = 'SUBTYPE_GUID' Module.GetBinaryFileList()[ItemCount] = Item - if Item and len(Item.FileNamList) > 0 and Item.FileNamList[0].FileType == 'DISPOSABLE': - Logger.Error('\nUPT', - PARSER_ERROR, - ERR_XML_INVALID_BINARY_FILE_TYPE % ('DISPOSABLE'), - RaiseError=True) ## ValidateMS3 # @@ -697,8 +704,7 @@ def ValidateMS3(Module, TopXmlTreeLevel): for PcdExItem in AsBuilt.PcdExValueList: CheckDict = {'TokenSpaceGuidValue':PcdExItem.TokenSpaceGuidValue, 'Token':PcdExItem.Token, - 'DatumType':PcdExItem.DatumType, - 'Value':PcdExItem.DefaultValue} + 'DatumType':PcdExItem.DatumType} XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile', 'AsBuilt', 'PcdExValue'] IsRequiredItemListNull(CheckDict, XmlTreeLevel) # diff --git a/BaseTools/Source/Python/UPT/Xml/XmlParserMisc.py b/BaseTools/Source/Python/UPT/Xml/XmlParserMisc.py index 0ffa44d35f..7e3dc94edf 100644 --- a/BaseTools/Source/Python/UPT/Xml/XmlParserMisc.py +++ b/BaseTools/Source/Python/UPT/Xml/XmlParserMisc.py @@ -1,7 +1,7 @@ ## @file # This file is used to parse a xml file of .PKG file # -# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -74,7 +74,6 @@ def IsRequiredItemListNull(ItemDict, XmlTreeLevel): ErrorMsg = ERR_XML_PARSER_REQUIRED_ITEM_MISSING % (Key, Msg) Logger.Error('\nUPT', PARSER_ERROR, ErrorMsg, RaiseError=True) - ## Get help text # # @param HelpText @@ -87,3 +86,16 @@ def GetHelpTextList(HelpText): HelpTextObj.SetString(HelT.HelpText) HelpTextList.append(HelpTextObj) return HelpTextList + +## Get Prompt text +# +# @param Prompt +# +def GetPromptList(Prompt): + PromptList = [] + for SubPrompt in Prompt: + PromptObj = TextObject() + PromptObj.SetLang(SubPrompt.Lang) + PromptObj.SetString(SubPrompt.Prompt) + PromptList.append(PromptObj) + return PromptList -- 2.39.2