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 - # - Content += GenHeaderCommentSection(Package.GetAbstract(), \ - Package.GetDescription(), \ - Package.GetCopyright(), \ - Package.GetLicense()) + # + # Generate file header + # + 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) - 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()) + Statement = (u'%s ' % DT.TAB_INF_DEFINES_BASE_NAME).ljust(LeftOffset) + u'= %s' % BaseName SpecialStatementList.append(Statement) + # 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] - if Destructor: - Statement = '%s = %s' % (DT.TAB_INF_DEFINES_DESTRUCTOR, 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] - + + if 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) + DistPkg, ContentZipFile, DpPkgFileName, DistFile = UnZipDp(WorkspaceDir, Options.PackageFile) # - # PackageList, ModuleList record the information for the meta-data - # files that need to be generated later + # check dependency # - 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] - 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 ReadOnly: - if not Executable: - chmod(ToFile, stat.S_IREAD) - else: - chmod(ToFile, stat.S_IREAD|stat.S_IEXEC) - elif Executable: - chmod(ToFile, stat.S_IREAD|stat.S_IWRITE|stat.S_IEXEC) + if os.path.exists(os.path.normpath(ToFile)): + pass else: - chmod(ToFile, stat.S_IREAD|stat.S_IWRITE) + 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_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_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 - if Abstract: - Abstract = Abstract.rstrip(EndOfLine) - Content += '# ' + Abstract + EndOfLine - Content += '#' + 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 += '#' + EndOfLine + Content += CommChar * 2 + TAB_SPACE_SPLIT + TAB_HEADER_COMMENT + END_OF_LINE + if Abstract: + 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 += 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 = '' - + ValueList = [] 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 - - 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_RANGES, + ST.WRN_MULTI_PCD_VALIDVALUE, 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) + 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) + else: + PcdErr = PcdErrorObject() + 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.IsCurrentOp(["LT", "GT", "LE", "GE", "EQ"]): + if self.IsLogicalOpHappen: + raise _ExprError(ST.ERR_PAREN_NOT_USED % self.Token) + + 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('') - - if self.Token[self.Index:self.Index+1] == '_' or \ - self.Token[self.Index:self.Index+1].isalnum(): - 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 + + 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,12 +493,26 @@ 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 string test +# +# @param Token: string test token +# +def IsValidStringTest(Token, Flag=False): + # + # Not do the check right now, keep the implementation for future enhancement. + # + if not Flag: + return True, "" + return _StringTestParser(Token).IsValidStringTest() + + ## # Check syntax of logical expression # @@ -442,19 +526,6 @@ def IsValidLogicalExpr(Token, Flag=False): return True, "" return _LogicalExpressionParser(Token).IsValidLogicalExpression() -## -# Check syntax of string test -# -# @param Token: string test token -# -def IsValidStringTest(Token, Flag=False): - # - # Not do the check right now, keep the implementation for future enhancement. - # - if not Flag: - return True, "" - return _StringTestParser(Token).IsValidStringTest() - ## # 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") + 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() - 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 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: + 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 % (ItemContent[0]), - File=CurrentLineOfItem.GetFileName(), - Line=CurrentLineOfItem.GetLineNo(), - ExtraData=CurrentLineOfItem.GetLineString()) - return False - if len(ItemContent) > 6: - 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]) - - 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], + # + # 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], + 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(): + 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)) - PcdDeclarations.append(PcdDeclaration) - - self.SetPcdList(self.GetPcdList() + PcdDeclarations) + + # + # 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 + # Get the Dp information # - 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 - + 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) + RemoveDist(Guid, Version, StoredDistFile, DataBase, WorkspaceDir, Options.Yes) - # - # 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) - - # - # 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 ] - Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList) + + 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() + AsBuildList = BinaryFile.GetAsBuiltList() + PatchPcdValueList = AsBuildList.GetPatchPcdList() + PcdExList = AsBuildList.GetPcdExList() + LibGuidVerList = AsBuildList.GetLibraryInstancesList() + BuildFlagList = AsBuildList.GetBuildFlagsList() - AsBuiltNodeList = [] + AsBuiltNodeList = [] - for Pcd in PatchPcdValueList: - if IsMatchArch(Pcd.SupArchList, SupportArch): - Tmp = PcdEntryXml() - AsBuiltNodeList.append(Tmp.ToXml4(Pcd, 'PatchPcdValue')) + 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')) + for Pcd in PcdExList: + if IsMatchArch(Pcd.SupArchList, SupportArch): + Tmp = PcdEntryXml() + AsBuiltNodeList.append(Tmp.ToXml4(Pcd, 'PcdExValue')) - GuiVerElemList = [] - for LibGuidVer in LibGuidVerList: + 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