X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=BaseTools%2FSource%2FPython%2FEcc%2FCheck.py;h=33060db5f27a73bc0a72885053f6b7cbec7a771d;hb=HEAD;hp=fc86ad96f2cf2fbdfc388abd74d77db43e29fb5b;hpb=855698fb69fdb85fa24c4374d07947106f4de828;p=mirror_edk2.git diff --git a/BaseTools/Source/Python/Ecc/Check.py b/BaseTools/Source/Python/Ecc/Check.py index fc86ad96f2..33060db5f2 100644 --- a/BaseTools/Source/Python/Ecc/Check.py +++ b/BaseTools/Source/Python/Ecc/Check.py @@ -1,14 +1,9 @@ ## @file # This file is used to define checkpoints used by ECC tool # -# Copyright (c) 2008 - 2018, 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. +# Copyright (c) 2021, Arm Limited. All rights reserved.
+# Copyright (c) 2008 - 2020, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent # from __future__ import absolute_import import Common.LongFilePathOs as os @@ -223,7 +218,7 @@ class Check(object): IndexOfLine = 0 for Line in op: IndexOfLine += 1 - if not Line.endswith('\r\n'): + if not bytes.decode(Line).endswith('\r\n'): OtherMsg = "File %s has invalid line ending at line %s" % (Record[1], IndexOfLine) EccGlobalData.gDb.TblReport.Insert(ERROR_GENERAL_CHECK_INVALID_LINE_ENDING, OtherMsg=OtherMsg, BelongsToTable='File', BelongsToItem=Record[0]) @@ -235,7 +230,7 @@ class Check(object): RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) for Record in RecordSet: if Record[2].upper() not in EccGlobalData.gConfig.BinaryExtList: - op = open(Record[1], 'rb').readlines() + op = open(Record[1], 'r').readlines() IndexOfLine = 0 for Line in op: IndexOfLine += 1 @@ -270,6 +265,66 @@ class Check(object): self.FunctionLayoutCheckPrototype() self.FunctionLayoutCheckBody() self.FunctionLayoutCheckLocalVariable() + self.FunctionLayoutCheckDeprecated() + + # To check if the deprecated functions are used + def FunctionLayoutCheckDeprecated(self): + if EccGlobalData.gConfig.CFunctionLayoutCheckNoDeprecated == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking function no deprecated one being used ...") + + DeprecatedFunctionSet = ('UnicodeValueToString', + 'AsciiValueToString', + 'StrCpy', + 'StrnCpy', + 'StrCat', + 'StrnCat', + 'UnicodeStrToAsciiStr', + 'AsciiStrCpy', + 'AsciiStrnCpy', + 'AsciiStrCat', + 'AsciiStrnCat', + 'AsciiStrToUnicodeStr', + 'PcdSet8', + 'PcdSet16', + 'PcdSet32', + 'PcdSet64', + 'PcdSetPtr', + 'PcdSetBool', + 'PcdSetEx8', + 'PcdSetEx16', + 'PcdSetEx32', + 'PcdSetEx64', + 'PcdSetExPtr', + 'PcdSetExBool', + 'LibPcdSet8', + 'LibPcdSet16', + 'LibPcdSet32', + 'LibPcdSet64', + 'LibPcdSetPtr', + 'LibPcdSetBool', + 'LibPcdSetEx8', + 'LibPcdSetEx16', + 'LibPcdSetEx32', + 'LibPcdSetEx64', + 'LibPcdSetExPtr', + 'LibPcdSetExBool', + 'GetVariable', + 'GetEfiGlobalVariable', + ) + + for IdentifierTable in EccGlobalData.gIdentifierTableList: + SqlCommand = """select ID, Name, BelongsToFile from %s + where Model = %s """ % (IdentifierTable, MODEL_IDENTIFIER_FUNCTION_CALLING) + RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) + for Record in RecordSet: + for Key in DeprecatedFunctionSet: + if Key == Record[1]: + if not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_NO_DEPRECATE, Key): + OtherMsg = 'The function [%s] is deprecated which should NOT be used' % Key + EccGlobalData.gDb.TblReport.Insert(ERROR_C_FUNCTION_LAYOUT_CHECK_NO_DEPRECATE, + OtherMsg=OtherMsg, + BelongsToTable=IdentifierTable, + BelongsToItem=Record[0]) def WalkTree(self): IgnoredPattern = c.GetIgnoredDirListPattern() @@ -387,7 +442,7 @@ class Check(object): self.DeclCheckUnionType() - # Check whether no use of int, unsigned, char, void, static, long in any .c, .h or .asl files. + # Check whether no use of int, unsigned, char, void, long in any .c, .h or .asl files. def DeclCheckNoUseCType(self): if EccGlobalData.gConfig.DeclarationDataTypeCheckNoUseCType == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': EdkLogger.quiet("Checking Declaration No use C type ...") @@ -586,13 +641,23 @@ class Check(object): if EccGlobalData.gConfig.IncludeFileCheckData == '1' or EccGlobalData.gConfig.IncludeFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': EdkLogger.quiet("Checking header file data ...") + # Get all typedef functions + gAllTypedefFun = [] + for IdentifierTable in EccGlobalData.gIdentifierTableList: + SqlCommand = """select Name from %s + where Model = %s """ % (IdentifierTable, MODEL_IDENTIFIER_TYPEDEF) + RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) + for Record in RecordSet: + if Record[0].startswith('('): + gAllTypedefFun.append(Record[0]) + # for Dirpath, Dirnames, Filenames in self.WalkTree(): # for F in Filenames: # if os.path.splitext(F)[1] in ('.h'): # FullName = os.path.join(Dirpath, F) # MsgList = c.CheckHeaderFileData(FullName) for FullName in EccGlobalData.gHFileList: - MsgList = c.CheckHeaderFileData(FullName) + MsgList = c.CheckHeaderFileData(FullName, gAllTypedefFun) # Doxygen document checking def DoxygenCheck(self): @@ -1039,11 +1104,11 @@ class Check(object): InfPathList.append(Item[0]) SqlCommand = """ select ID, Path, FullPath from File where upper(FullPath) not in - (select upper(A.Path) || '\\' || upper(B.Value1) from File as A, INF as B + (select upper(A.Path) || '%s' || upper(B.Value1) from File as A, INF as B where A.ID in (select BelongsToFile from INF where Model = %s group by BelongsToFile) and B.BelongsToFile = A.ID and B.Model = %s) and (Model = %s or Model = %s) - """ % (MODEL_EFI_SOURCE_FILE, MODEL_EFI_SOURCE_FILE, MODEL_FILE_C, MODEL_FILE_H) + """ % (os.sep, MODEL_EFI_SOURCE_FILE, MODEL_EFI_SOURCE_FILE, MODEL_FILE_C, MODEL_FILE_H) RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand) for Record in RecordSet: Path = Record[1] @@ -1068,9 +1133,9 @@ class Check(object): BelongsToFile = Pcd[4] SqlCommand = """ select ID from File where FullPath in - (select B.Path || '\\' || A.Value1 from INF as A, File as B where A.Model = %s and A.BelongsToFile = %s + (select B.Path || '%s' || A.Value1 from INF as A, File as B where A.Model = %s and A.BelongsToFile = %s and B.ID = %s and (B.Model = %s or B.Model = %s)) - """ % (MODEL_EFI_SOURCE_FILE, BelongsToFile, BelongsToFile, MODEL_FILE_C, MODEL_FILE_H) + """ % (os.sep, MODEL_EFI_SOURCE_FILE, BelongsToFile, BelongsToFile, MODEL_FILE_C, MODEL_FILE_H) TableSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) for Tbl in TableSet: TblName = 'Identifier' + str(Tbl[0]) @@ -1333,7 +1398,7 @@ class Check(object): # Check whether only capital letters are used for #define declarations def NamingConventionCheckDefineStatement(self, FileTable): if EccGlobalData.gConfig.NamingConventionCheckDefineStatement == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': - EdkLogger.quiet("Checking naming covention of #define statement ...") + EdkLogger.quiet("Checking naming convention of #define statement ...") SqlCommand = """select ID, Value from %s where Model = %s""" % (FileTable, MODEL_IDENTIFIER_MACRO_DEFINE) RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) @@ -1348,7 +1413,7 @@ class Check(object): # Check whether only capital letters are used for typedef declarations def NamingConventionCheckTypedefStatement(self, FileTable): if EccGlobalData.gConfig.NamingConventionCheckTypedefStatement == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': - EdkLogger.quiet("Checking naming covention of #typedef statement ...") + EdkLogger.quiet("Checking naming convention of #typedef statement ...") SqlCommand = """select ID, Name from %s where Model = %s""" % (FileTable, MODEL_IDENTIFIER_TYPEDEF) RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) @@ -1368,15 +1433,17 @@ class Check(object): # Check whether the #ifndef at the start of an include file uses both prefix and postfix underscore characters, '_'. def NamingConventionCheckIfndefStatement(self, FileTable): if EccGlobalData.gConfig.NamingConventionCheckIfndefStatement == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': - EdkLogger.quiet("Checking naming covention of #ifndef statement ...") + EdkLogger.quiet("Checking naming convention of #ifndef statement ...") SqlCommand = """select ID, Value from %s where Model = %s""" % (FileTable, MODEL_IDENTIFIER_MACRO_IFNDEF) RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) - for Record in RecordSet: - Name = Record[1].replace('#ifndef', '').strip() - if Name[0] != '_' or Name[-1] != '_': + if RecordSet: + # Only check the first ifndef statement of the file + FirstDefine = sorted(RecordSet, key=lambda Record: Record[0])[0] + Name = FirstDefine[1].replace('#ifndef', '').strip() + if Name[0] == '_' or Name[-1] != '_' or Name[-2] == '_': if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_IFNDEF_STATEMENT, Name): - EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_IFNDEF_STATEMENT, OtherMsg="The #ifndef name [%s] does not follow the rules" % (Name), BelongsToTable=FileTable, BelongsToItem=Record[0]) + EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_IFNDEF_STATEMENT, OtherMsg="The #ifndef name [%s] does not follow the rules" % (Name), BelongsToTable=FileTable, BelongsToItem=FirstDefine[0]) # Rule for path name, variable name and function name # 1. First character should be upper case @@ -1385,7 +1452,7 @@ class Check(object): # Check whether the path name followed the rule def NamingConventionCheckPathName(self): if EccGlobalData.gConfig.NamingConventionCheckPathName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': - EdkLogger.quiet("Checking naming covention of file path name ...") + EdkLogger.quiet("Checking naming convention of file path name ...") Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$') SqlCommand = """select ID, Name from File""" RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) @@ -1402,16 +1469,17 @@ class Check(object): # Check whether the variable name followed the rule def NamingConventionCheckVariableName(self, FileTable): if EccGlobalData.gConfig.NamingConventionCheckVariableName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': - EdkLogger.quiet("Checking naming covention of variable name ...") + EdkLogger.quiet("Checking naming convention of variable name ...") Pattern = re.compile(r'^[A-Zgm]+\S*[a-z]\S*$') - SqlCommand = """select ID, Name from %s where Model = %s""" % (FileTable, MODEL_IDENTIFIER_VARIABLE) + SqlCommand = """select ID, Name, Modifier from %s where Model = %s""" % (FileTable, MODEL_IDENTIFIER_VARIABLE) RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) for Record in RecordSet: Var = Record[1] + Modifier = Record[2] if Var.startswith('CONST'): Var = Var[5:].lstrip() - if not Pattern.match(Var): + if not Pattern.match(Var) and not (Modifier.endswith('*') and Var.startswith('p')): if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Record[1]): EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, OtherMsg="The variable name [%s] does not follow the rules" % (Record[1]), BelongsToTable=FileTable, BelongsToItem=Record[0]) @@ -1422,7 +1490,7 @@ class Check(object): # Check whether the function name followed the rule def NamingConventionCheckFunctionName(self): if EccGlobalData.gConfig.NamingConventionCheckFunctionName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': - EdkLogger.quiet("Checking naming covention of function name ...") + EdkLogger.quiet("Checking naming convention of function name ...") Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$') SqlCommand = """select ID, Name from Function""" RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) @@ -1434,7 +1502,7 @@ class Check(object): # Check whether NO use short variable name with single character def NamingConventionCheckSingleCharacterVariable(self, FileTable): if EccGlobalData.gConfig.NamingConventionCheckSingleCharacterVariable == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': - EdkLogger.quiet("Checking naming covention of single character variable name ...") + EdkLogger.quiet("Checking naming convention of single character variable name ...") SqlCommand = """select ID, Name from %s where Model = %s""" % (FileTable, MODEL_IDENTIFIER_VARIABLE) RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)