]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/Ecc/c.py
BaseTools:ECC need to handle lower case 'static'
[mirror_edk2.git] / BaseTools / Source / Python / Ecc / c.py
index 175e2d2e043924bac9089c8d362c6e21932a2d21..a30122a45f81e79f00552c0d099bcc664fde06ed 100644 (file)
@@ -1,28 +1,24 @@
 ## @file\r
 # This file is used to be the c coding style checking of ECC tool\r
 #\r
-# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
-# This program and the accompanying materials\r
-# are licensed and made available under the terms and conditions of the BSD License\r
-# which accompanies this distribution.  The full text of the license may be found at\r
-# http://opensource.org/licenses/bsd-license.php\r
-#\r
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+# Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
 #\r
 \r
+from __future__ import print_function\r
+from __future__ import absolute_import\r
 import sys\r
 import Common.LongFilePathOs as os\r
 import re\r
 import string\r
-import CodeFragmentCollector\r
-import FileProfile\r
+from Ecc import CodeFragmentCollector\r
+from Ecc import FileProfile\r
 from CommonDataClass import DataClass\r
-import Database\r
+from Ecc import Database\r
 from Common import EdkLogger\r
-from EccToolError import *\r
-import EccGlobalData\r
-import MetaDataParser\r
+from Ecc.EccToolError import *\r
+from Ecc import EccGlobalData\r
+from Ecc import MetaDataParser\r
 \r
 IncludeFileListDict = {}\r
 AllIncludeFileListDict = {}\r
@@ -33,7 +29,7 @@ IgnoredKeywordList = ['EFI_ERROR']
 \r
 def GetIgnoredDirListPattern():\r
     skipList = list(EccGlobalData.gConfig.SkipDirList) + ['.svn']\r
-    DirString = string.join(skipList, '|')\r
+    DirString = '|'.join(skipList)\r
     p = re.compile(r'.*[\\/](?:%s)[\\/]?.*' % DirString)\r
     return p\r
 \r
@@ -499,6 +495,8 @@ def CollectSourceCodeDataIntoDB(RootDir):
     tuple = os.walk(RootDir)\r
     IgnoredPattern = GetIgnoredDirListPattern()\r
     ParseErrorFileList = []\r
+    TokenReleaceList = EccGlobalData.gConfig.TokenReleaceList\r
+    TokenReleaceList.extend(['L",\\\""'])\r
 \r
     for dirpath, dirnames, filenames in tuple:\r
         if IgnoredPattern.match(dirpath.upper()):\r
@@ -523,6 +521,7 @@ def CollectSourceCodeDataIntoDB(RootDir):
                 EdkLogger.info("Parsing " + FullName)\r
                 model = f.endswith('c') and DataClass.MODEL_FILE_C or DataClass.MODEL_FILE_H\r
                 collector = CodeFragmentCollector.CodeFragmentCollector(FullName)\r
+                collector.TokenReleaceList = TokenReleaceList\r
                 try:\r
                     collector.ParseFile()\r
                 except UnicodeError:\r
@@ -731,7 +730,7 @@ def SplitPredicateByOp(Str, Op, IsFuncCalling=False):
 \r
             while not LBFound and (Str[Index].isalnum() or Str[Index] == '_'):\r
                 Index += 1\r
-            # maybe type-cast at the begining, skip it.\r
+            # maybe type-cast at the beginning, skip it.\r
             RemainingStr = Str[Index:].lstrip()\r
             if RemainingStr.startswith(')') and not LBFound:\r
                 Index += 1\r
@@ -830,9 +829,9 @@ def GetDataTypeFromModifier(ModifierStr):
     MList = ModifierStr.split()\r
     ReturnType = ''\r
     for M in MList:\r
-        if M in EccGlobalData.gConfig.ModifierList:\r
+        if M in EccGlobalData.gConfig.ModifierSet:\r
             continue\r
-        # remove array sufix\r
+        # remove array suffix\r
         if M.startswith('[') or M.endswith(']'):\r
             continue\r
         ReturnType += M + ' '\r
@@ -961,7 +960,7 @@ def StripComments(Str):
             ListFromStr[Index] = ' '\r
             Index += 1\r
         # check for // comment\r
-        elif ListFromStr[Index] == '/' and ListFromStr[Index + 1] == '/' and ListFromStr[Index + 2] != '\n':\r
+        elif ListFromStr[Index] == '/' and ListFromStr[Index + 1] == '/':\r
             InComment = True\r
             DoubleSlashComment = True\r
 \r
@@ -1017,7 +1016,7 @@ def GetFinalTypeValue(Type, FieldName, TypedefDict, SUDict):
                 Type = GetDataTypeFromModifier(Field[0:Index])\r
                 return Type.strip()\r
             else:\r
-            # For the condition that the field in struct is an array with [] sufixes...\r
+            # For the condition that the field in struct is an array with [] suffixes...\r
                 if not Field[Index + len(FieldName)].isalnum():\r
                     Type = GetDataTypeFromModifier(Field[0:Index])\r
                     return Type.strip()\r
@@ -1295,7 +1294,7 @@ def CheckFuncLayoutReturnType(FullFileName):
         Result0 = Result[0]\r
         if Result0.upper().startswith('STATIC'):\r
             Result0 = Result0[6:].strip()\r
-        Index = Result0.find(ReturnType)\r
+        Index = Result0.find(TypeStart)\r
         if Index != 0 or Result[3] != 0:\r
             PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '[%s] Return Type should appear at the start of line' % FuncName, 'Function', Result[1])\r
 \r
@@ -1509,7 +1508,7 @@ def CheckFuncLayoutBody(FullFileName):
 \r
     FileTable = 'Identifier' + str(FileID)\r
     Db = GetDB()\r
-    SqlStatement = """ select BodyStartColumn, EndColumn, ID\r
+    SqlStatement = """ select BodyStartColumn, EndColumn, ID, Name\r
                        from Function\r
                        where BelongsToFile = %d\r
                    """ % (FileID)\r
@@ -1518,9 +1517,15 @@ def CheckFuncLayoutBody(FullFileName):
         return ErrorMsgList\r
     for Result in ResultSet:\r
         if Result[0] != 0:\r
-            PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY, 'open brace should be at the very beginning of a line.', 'Function', Result[2])\r
+            if not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY, Result[3]):\r
+                PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY,\r
+                              'The open brace should be at the very beginning of a line for the function [%s].' % Result[3],\r
+                              'Function', Result[2])\r
         if Result[1] != 0:\r
-            PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY, 'close brace should be at the very beginning of a line.', 'Function', Result[2])\r
+            if not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY, Result[3]):\r
+                PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY,\r
+                              'The close brace should be at the very beginning of a line for the function [%s].' % Result[3],\r
+                              'Function', Result[2])\r
 \r
 def CheckFuncLayoutLocalVariable(FullFileName):\r
     ErrorMsgList = []\r
@@ -1621,7 +1626,7 @@ def CheckMemberVariableFormat(Name, Value, FileTable, TdId, ModelId):
         Field = Field.strip()\r
         if Field == '':\r
             continue\r
-        # For the condition that the field in struct is an array with [] sufixes...\r
+        # For the condition that the field in struct is an array with [] suffixes...\r
         if Field[-1] == ']':\r
             LBPos = Field.find('[')\r
             Field = Field[0:LBPos]\r
@@ -1854,7 +1859,7 @@ def CheckDeclNoUseCType(FullFileName):
                        where Model = %d\r
                    """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE)\r
     ResultSet = Db.TblFile.Exec(SqlStatement)\r
-    CTypeTuple = ('int', 'unsigned', 'char', 'void', 'static', 'long')\r
+    CTypeTuple = ('int', 'unsigned', 'char', 'void', 'long')\r
     for Result in ResultSet:\r
         for Type in CTypeTuple:\r
             if PatternInModifier(Result[0], Type):\r
@@ -2142,7 +2147,7 @@ def CheckBooleanValueComparison(FullFileName):
                     PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
 \r
 \r
-def CheckHeaderFileData(FullFileName):\r
+def CheckHeaderFileData(FullFileName, AllTypedefFun=[]):\r
     ErrorMsgList = []\r
 \r
     FileID = GetTableID(FullFileName, ErrorMsgList)\r
@@ -2158,7 +2163,11 @@ def CheckHeaderFileData(FullFileName):
     ResultSet = Db.TblFile.Exec(SqlStatement)\r
     for Result in ResultSet:\r
         if not Result[1].startswith('extern'):\r
-            PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_DATA, 'Variable definition appears in header file', FileTable, Result[0])\r
+            for Item in AllTypedefFun:\r
+                if '(%s)' % Result[1] in Item:\r
+                    break\r
+            else:\r
+                PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_DATA, 'Variable definition appears in header file', FileTable, Result[0])\r
 \r
     SqlStatement = """ select ID\r
                        from Function\r
@@ -2285,7 +2294,7 @@ def CheckDoxygenTripleForwardSlash(FullFileName):
         for Result in ResultSet:\r
             CommentSet.append(Result)\r
     except:\r
-        print 'Unrecognized chars in comment of file %s', FullFileName\r
+        print('Unrecognized chars in comment of file %s', FullFileName)\r
 \r
 \r
     for Result in CommentSet:\r
@@ -2348,13 +2357,13 @@ def CheckFileHeaderDoxygenComments(FullFileName):
         if (len(CommentStrListTemp) <= 1):\r
             # For Mac\r
             CommentStrListTemp = CommentStr.split('\r')\r
-        # Skip the content before the file  header    \r
+        # Skip the content before the file  header\r
         for CommentLine in CommentStrListTemp:\r
             if CommentLine.strip().startswith('/** @file'):\r
                 FileStartFlag = True\r
             if FileStartFlag ==  True:\r
                 CommentStrList.append(CommentLine)\r
-                       \r
+\r
         ID = Result[1]\r
         Index = 0\r
         if CommentStrList and CommentStrList[0].strip().startswith('/** @file'):\r
@@ -2377,9 +2386,9 @@ def CheckFileHeaderDoxygenComments(FullFileName):
             if EccGlobalData.gConfig.HeaderCheckCFileCommentStartSpacesNum == '1' or EccGlobalData.gConfig.HeaderCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
                 if CommentLine.startswith('/** @file') == False and CommentLine.startswith('**/') == False and CommentLine.strip() and CommentLine.startswith('  ') == False:\r
                     PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment content should start with two spaces at each line', FileTable, ID)\r
-            \r
+\r
             CommentLine = CommentLine.strip()\r
-            if CommentLine.startswith('Copyright'):\r
+            if CommentLine.startswith('Copyright') or ('Copyright' in CommentLine and CommentLine.lower().startswith('(c)')):\r
                 NoCopyrightFlag = False\r
                 if CommentLine.find('All rights reserved') == -1:\r
                     for Copyright in EccGlobalData.gConfig.Copyright:\r
@@ -2402,9 +2411,9 @@ def CheckFileHeaderDoxygenComments(FullFileName):
                     # Check whether C File header Comment's each reference at list should begin with a bullet character.\r
                     if EccGlobalData.gConfig.HeaderCheckCFileCommentReferenceFormat == '1' or EccGlobalData.gConfig.HeaderCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
                         if RefListFlag == True:\r
-                            if RefLine.strip() and RefLine.strip().startswith('**/') == False and RefLine.startswith('  -') == False:                            \r
-                                PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'Each reference on a separate line should begin with a bullet character ""-"" ', FileTable, ID)                    \r
-    \r
+                            if RefLine.strip() and RefLine.strip().startswith('**/') == False and RefLine.startswith('  -') == False:\r
+                                PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'Each reference on a separate line should begin with a bullet character ""-"" ', FileTable, ID)\r
+\r
     if NoHeaderCommentStartFlag:\r
         PrintErrorMsg(ERROR_DOXYGEN_CHECK_FILE_HEADER, 'File header comment should begin with ""/** @file""', FileTable, ID)\r
         return\r
@@ -2438,7 +2447,7 @@ def CheckFuncHeaderDoxygenComments(FullFileName):
         for Result in ResultSet:\r
             CommentSet.append(Result)\r
     except:\r
-        print 'Unrecognized chars in comment of file %s', FullFileName\r
+        print('Unrecognized chars in comment of file %s', FullFileName)\r
 \r
     # Func Decl check\r
     SqlStatement = """ select Modifier, Name, StartLine, ID, Value\r
@@ -2469,7 +2478,7 @@ def CheckFuncHeaderDoxygenComments(FullFileName):
         for Result in ResultSet:\r
             CommentSet.append(Result)\r
     except:\r
-        print 'Unrecognized chars in comment of file %s', FullFileName\r
+        print('Unrecognized chars in comment of file %s', FullFileName)\r
 \r
     SqlStatement = """ select Modifier, Header, StartLine, ID, Name\r
                        from Function\r
@@ -2633,10 +2642,10 @@ if __name__ == '__main__':
 #    CollectSourceCodeDataIntoDB(sys.argv[1])\r
     try:\r
         test_file = sys.argv[1]\r
-    except IndexError, v:\r
-        print "Usage: %s filename" % sys.argv[0]\r
+    except IndexError as v:\r
+        print("Usage: %s filename" % sys.argv[0])\r
         sys.exit(1)\r
     MsgList = CheckFuncHeaderDoxygenComments(test_file)\r
     for Msg in MsgList:\r
-        print Msg\r
-    print 'Done!'\r
+        print(Msg)\r
+    print('Done!')\r