From 1b2467c58f3fd4b407c676438bf471afd65588aa Mon Sep 17 00:00:00 2001 From: Hess Chen Date: Thu, 25 Jun 2015 07:50:55 +0000 Subject: [PATCH] BaseTools/Ecc: Add a checkpoint for invalid UNI file. Add a checkpoint to check that the UNI file which is associated by INF or DEC file need define the prompt and help information. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Hess Chen Reviewed-by: YangX Li git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17706 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Python/Common/LongFilePathSupport.py | 6 +- BaseTools/Source/Python/Ecc/Configuration.py | 7 ++ BaseTools/Source/Python/Ecc/Ecc.py | 3 +- BaseTools/Source/Python/Ecc/EccToolError.py | 4 +- .../Ecc/MetaFileWorkspace/MetaFileParser.py | 96 ++++++++++++++++++- BaseTools/Source/Python/Ecc/config.ini | 11 ++- BaseTools/Source/Python/Table/TableReport.py | 9 +- 7 files changed, 127 insertions(+), 9 deletions(-) diff --git a/BaseTools/Source/Python/Common/LongFilePathSupport.py b/BaseTools/Source/Python/Common/LongFilePathSupport.py index 72dde20503..b3e3c8ea64 100644 --- a/BaseTools/Source/Python/Common/LongFilePathSupport.py +++ b/BaseTools/Source/Python/Common/LongFilePathSupport.py @@ -1,7 +1,7 @@ ## @file # Override built in function file.open to provide support for long file path # -# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# Copyright (c) 2014 - 2015, 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 @@ -14,6 +14,7 @@ import os import platform import shutil +import codecs ## # OpenLongPath @@ -37,6 +38,9 @@ def LongFilePath(FileName): def OpenLongFilePath(FileName, Mode='r', Buffer= -1): return open(LongFilePath(FileName), Mode, Buffer) +def CodecOpenLongFilePath(Filename, Mode='rb', Encoding=None, Errors='strict', Buffering=1): + return codecs.open(LongFilePath(Filename), Mode, Encoding, Errors, Buffering) + ## # CopyLongFilePath # wrap copyfile to support copy a long file path diff --git a/BaseTools/Source/Python/Ecc/Configuration.py b/BaseTools/Source/Python/Ecc/Configuration.py index 55a1655ae5..5a06c4ee2e 100644 --- a/BaseTools/Source/Python/Ecc/Configuration.py +++ b/BaseTools/Source/Python/Ecc/Configuration.py @@ -246,6 +246,13 @@ class Configuration(object): self.MetaDataFileCheckModuleFilePpiFormat = 1 # Check Pcd Format in INF files self.MetaDataFileCheckModuleFilePcdFormat = 1 + + # Check UNI file + self.UniCheckAll = 0 + # Check INF or DEC file whether defined the localized information in the associated UNI file. + self.UniCheckHelpInfo = 1 + # Check PCD whether defined the prompt, help in the DEC file and localized information in the associated UNI file. + self.UniCheckPCDInfo = 1 # # The check points in this section are reserved diff --git a/BaseTools/Source/Python/Ecc/Ecc.py b/BaseTools/Source/Python/Ecc/Ecc.py index cb47bc2e53..ec8f6c22cf 100644 --- a/BaseTools/Source/Python/Ecc/Ecc.py +++ b/BaseTools/Source/Python/Ecc/Ecc.py @@ -251,7 +251,8 @@ class Ecc(object): Filename = os.path.normpath(os.path.join(Root, File)) EdkLogger.quiet("Parsing %s" % Filename) Op.write("%s\r" % Filename) - EccGlobalData.gDb.TblFile.InsertFile(Filename, MODEL_FILE_UNI) + FileID = EccGlobalData.gDb.TblFile.InsertFile(Filename, MODEL_FILE_UNI) + EccGlobalData.gDb.TblReport.UpdateBelongsToItemByFile(FileID, File) continue Op.close() diff --git a/BaseTools/Source/Python/Ecc/EccToolError.py b/BaseTools/Source/Python/Ecc/EccToolError.py index 3895193d8c..900dcc17dd 100644 --- a/BaseTools/Source/Python/Ecc/EccToolError.py +++ b/BaseTools/Source/Python/Ecc/EccToolError.py @@ -1,7 +1,7 @@ ## @file # Standardized Error Hanlding infrastructures. # -# Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.
+# Copyright (c) 2008 - 2015, 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 @@ -21,6 +21,7 @@ ERROR_GENERAL_CHECK_CARRIAGE_RETURN = 1006 ERROR_GENERAL_CHECK_FILE_EXISTENCE = 1007 ERROR_GENERAL_CHECK_NON_ACSII = 1008 ERROR_GENERAL_CHECK_UNI = 1009 +ERROR_GENERAL_CHECK_UNI_HELP_INFO = 1010 ERROR_SPACE_CHECK_ALL = 2000 @@ -114,6 +115,7 @@ gEccErrorMessage = { ERROR_GENERAL_CHECK_FILE_EXISTENCE : "File not found", ERROR_GENERAL_CHECK_NON_ACSII : "File has invalid Non-ACSII char", ERROR_GENERAL_CHECK_UNI : "File is not a valid UTF-16 UNI file", + ERROR_GENERAL_CHECK_UNI_HELP_INFO : "UNI file that is associated by INF or DEC file need define the prompt and help information.", ERROR_SPACE_CHECK_ALL : "", diff --git a/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py b/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py index 9f31d4d4de..dbe7f2a296 100644 --- a/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py +++ b/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py @@ -1,7 +1,7 @@ ## @file # This file is used to parse meta files # -# Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.
+# Copyright (c) 2008 - 2015, 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 @@ -33,6 +33,7 @@ from CommonDataClass.Exceptions import * from MetaFileTable import MetaFileStorage from GenFds.FdfParser import FdfParser from Common.LongFilePathSupport import OpenLongFilePath as open +from Common.LongFilePathSupport import CodecOpenLongFilePath ## A decorator used to parse macro definition def ParseMacro(Parser): @@ -174,6 +175,9 @@ class MetaFileParser(object): self._PostProcessed = False # Different version of meta-file has different way to parse. self._Version = 0 + # UNI object and extra UNI object + self._UniObj = None + self._UniExtraObj = None ## Store the parsed data in table def _Store(self, *Args): @@ -258,8 +262,16 @@ class MetaFileParser(object): ## Skip unsupported data def _Skip(self): - EdkLogger.warn("Parser", "Unrecognized content", File=self.MetaFile, - Line=self._LineIndex+1, ExtraData=self._CurrentLine); + if self._SectionName == TAB_USER_EXTENSIONS.upper() and self._CurrentLine.upper().endswith('.UNI'): + if EccGlobalData.gConfig.UniCheckHelpInfo == '1' or EccGlobalData.gConfig.UniCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + ExtraUni = self._CurrentLine.strip() + ExtraUniFile = os.path.join(os.path.dirname(self.MetaFile), ExtraUni) + IsModuleUni = self.MetaFile.upper().endswith('.INF') + self._UniExtraObj = UniParser(ExtraUniFile, IsExtraUni=True, IsModuleUni=IsModuleUni) + self._UniExtraObj.Start() + else: + EdkLogger.warn("Parser", "Unrecognized content", File=self.MetaFile, + Line=self._LineIndex + 1, ExtraData=self._CurrentLine); self._ValueList[0:1] = [self._CurrentLine] ## Section header parser @@ -328,7 +340,20 @@ class MetaFileParser(object): except: EdkLogger.error('Parser', FORMAT_INVALID, "Invalid version number", ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex+1) - + elif Name == 'MODULE_UNI_FILE': + UniFile = os.path.join(os.path.dirname(self.MetaFile), Value) + if os.path.exists(UniFile): + self._UniObj = UniParser(UniFile, IsExtraUni=False, IsModuleUni=True) + self._UniObj.Start() + else: + EdkLogger.error('Parser', FILE_NOT_FOUND, "Module UNI file %s is missing." % Value, + ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex+1, + RaiseError=False) + elif Name == 'PACKAGE_UNI_FILE': + UniFile = os.path.join(os.path.dirname(self.MetaFile), Value) + if os.path.exists(UniFile): + self._UniObj = UniParser(UniFile, IsExtraUni=False, IsModuleUni=False) + if type(self) == InfParser and self._Version < 0x00010005: # EDK module allows using defines as macros self._FileLocalMacros[Name] = Value @@ -1873,6 +1898,69 @@ class Fdf(FdfObject): BelongsToFile = self.InsertFile(FileName) self.TblFdf.Insert(Model, Value1, Value2, Value3, Scope1, Scope2, BelongsToItem, BelongsToFile, StartLine, StartColumn, EndLine, EndColumn, Enabled) +class UniParser(object): + # IsExtraUni defined the UNI file is Module UNI or extra Module UNI + # IsModuleUni defined the UNI file is Module UNI or Package UNI + def __init__(self, FilePath, IsExtraUni=False, IsModuleUni=True): + self.FilePath = FilePath + self.FileName = os.path.basename(FilePath) + self.IsExtraUni = IsExtraUni + self.IsModuleUni = IsModuleUni + self.FileIn = None + self.Missing = [] + self.__read() + + def __read(self): + try: + self.FileIn = CodecOpenLongFilePath(self.FilePath, Mode = 'rb', Encoding = 'utf_16').read() + except UnicodeError: + self.FileIn = CodecOpenLongFilePath(self.FilePath, Mode = 'rb', Encoding = 'utf_16_le').read() + except IOError: + self.FileIn = "" + + def Start(self): + if self.IsModuleUni: + if self.IsExtraUni: + ModuleName = self.CheckKeyValid('STR_PROPERTIES_MODULE_NAME') + self.PrintLog('STR_PROPERTIES_MODULE_NAME', ModuleName) + else: + ModuleAbstract = self.CheckKeyValid('STR_MODULE_ABSTRACT') + self.PrintLog('STR_MODULE_ABSTRACT', ModuleAbstract) + ModuleDescription = self.CheckKeyValid('STR_MODULE_DESCRIPTION') + self.PrintLog('STR_MODULE_DESCRIPTION', ModuleDescription) + else: + if self.IsExtraUni: + PackageName = self.CheckKeyValid('STR_PROPERTIES_PACKAGE_NAME') + self.PrintLog('STR_PROPERTIES_PACKAGE_NAME', PackageName) + else: + PackageAbstract = self.CheckKeyValid('STR_PACKAGE_ABSTRACT') + self.PrintLog('STR_PACKAGE_ABSTRACT', PackageAbstract) + PackageDescription = self.CheckKeyValid('STR_PACKAGE_DESCRIPTION') + self.PrintLog('STR_PACKAGE_DESCRIPTION', PackageDescription) + + def CheckKeyValid(self, Key, Contents=None): + if not Contents: + Contents = self.FileIn + KeyPattern = re.compile('#string\s+%s\s+.*?#language.*?".*?"' % Key, re.S) + if KeyPattern.search(Contents): + return True + return False + + def CheckPcdInfo(self, PcdCName): + PromptKey = 'STR_%s_PROMPT' % PcdCName.replace('.', '_') + PcdPrompt = self.CheckKeyValid(PromptKey) + self.PrintLog(PromptKey, PcdPrompt) + HelpKey = 'STR_%s_HELP' % PcdCName.replace('.', '_') + PcdHelp = self.CheckKeyValid(HelpKey) + self.PrintLog(HelpKey, PcdHelp) + + def PrintLog(self, Key, Value): + if not Value and Key not in self.Missing: + Msg = '%s is missing in the %s file.' % (Key, self.FileName) + EdkLogger.warn('Parser', Msg) + EccGlobalData.gDb.TblReport.Insert(EccToolError.ERROR_GENERAL_CHECK_UNI_HELP_INFO, OtherMsg=Msg, BelongsToTable='File', BelongsToItem=-2) + self.Missing.append(Key) + ## # # This acts like the main() function for the script, unless it is 'import'ed into another diff --git a/BaseTools/Source/Python/Ecc/config.ini b/BaseTools/Source/Python/Ecc/config.ini index 8e11082b83..89c17a5ef2 100644 --- a/BaseTools/Source/Python/Ecc/config.ini +++ b/BaseTools/Source/Python/Ecc/config.ini @@ -2,7 +2,7 @@ # This file is used to set configuration of ECC tool # For the items listed below, 1 means valid, 0 means invalid # -# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2015, 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 @@ -248,6 +248,15 @@ MetaDataFileCheckPcdType = 1 # Check whether there are FILE_GUID duplication among different INF files MetaDataFileCheckModuleFileGuidDuplication = 1 +# +# Uni File Processing Checking +# +UniCheckAll = 0 +# Check INF or DEC file whether defined the localized information in the associated UNI file. +UniCheckHelpInfo = 1 +# Check PCD whether defined the prompt, help in the DEC file and localized information in the associated UNI file. +UniCheckPCDInfo = 1 + # # The check points in this section are reserved # diff --git a/BaseTools/Source/Python/Table/TableReport.py b/BaseTools/Source/Python/Table/TableReport.py index 4065a43c5b..c7829c0097 100644 --- a/BaseTools/Source/Python/Table/TableReport.py +++ b/BaseTools/Source/Python/Table/TableReport.py @@ -1,7 +1,7 @@ ## @file # This file is used to create/update/query/erase table for ECC reports # -# Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.
+# Copyright (c) 2008 - 2015, 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 @@ -85,6 +85,13 @@ class TableReport(Table): where Enabled > -1 order by ErrorID, BelongsToItem""" % (self.Table) return self.Exec(SqlCommand) + ## Update table + # + def UpdateBelongsToItemByFile(self, ItemID=-1, File=""): + SqlCommand = """update Report set BelongsToItem=%s where BelongsToTable='File' and BelongsToItem=-2 + and OtherMsg like '%%%s%%'""" % (ItemID, File) + return self.Exec(SqlCommand) + ## Convert to CSV # # Get all enabled records from table report and save them to a .csv file