ECC: Doxygen command and file comment description check initial check-in.
authorjlin16 <jlin16@7335b38e-4728-0410-8992-fb3ffe349368>
Thu, 20 Mar 2008 08:58:46 +0000 (08:58 +0000)
committerjlin16 <jlin16@7335b38e-4728-0410-8992-fb3ffe349368>
Thu, 20 Mar 2008 08:58:46 +0000 (08:58 +0000)
git-svn-id: https://buildtools.tianocore.org/svn/buildtools/trunk/BaseTools@1083 7335b38e-4728-0410-8992-fb3ffe349368

Source/Python/Ecc/Check.py
Source/Python/Ecc/c.py

index b556c04..6b2236d 100644 (file)
@@ -49,7 +49,17 @@ class Check(object):
     #\r
     def DoxygenCheckFileHeader(self):\r
         if EccGlobalData.gConfig.DoxygenCheckFileHeader == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1':\r
-            pass\r
+            EdkLogger.quiet("Checking Doxygen file header ...")\r
+            Tuple = os.walk(EccGlobalData.gTarget)\r
+            IgnoredPattern = re.compile(r'.*[\\/](?:BUILD|CVS|\.SVN|INTELRESTRICTEDTOOLS|INTELRESTRICTEDPKG)[\\/].*')\r
+        \r
+            for Dirpath, Dirnames, Filenames in Tuple:\r
+                if IgnoredPattern.match(Dirpath.upper()) or Dirpath.find('.svn') != -1:\r
+                    continue\r
+                for F in Filenames:\r
+                    if os.path.splitext(F)[1] in ('.h', '.c'):\r
+                        FullName = os.path.join(Dirpath, F)\r
+                        MsgList = c.CheckFileHeaderDoxygenComments(FullName)\r
     \r
     #\r
     # Check whether the function headers are followed Doxygen special documentation blocks in section 2.3.5\r
@@ -69,7 +79,7 @@ class Check(object):
                         FullName = os.path.join(Dirpath, F)\r
                         MsgList = c.CheckFuncHeaderDoxygenComments(FullName)\r
 #                        for Msg in MsgList:\r
-#                            print Msg\r
+#                            print Msg                \r
                             \r
     #\r
     # Check whether the first line of text in a comment block is a brief description of the element being documented. \r
@@ -84,14 +94,34 @@ class Check(object):
     #\r
     def DoxygenCheckCommentFormat(self):\r
         if EccGlobalData.gConfig.DoxygenCheckCommentFormat == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1':\r
-            pass\r
+            EdkLogger.quiet("Checking Doxygen comment ///< ...")\r
+            Tuple = os.walk(EccGlobalData.gTarget)\r
+            IgnoredPattern = re.compile(r'.*[\\/](?:BUILD|CVS|\.SVN|INTELRESTRICTEDTOOLS|INTELRESTRICTEDPKG)[\\/].*')\r
+        \r
+            for Dirpath, Dirnames, Filenames in Tuple:\r
+                if IgnoredPattern.match(Dirpath.upper()) or Dirpath.find('.svn') != -1:\r
+                    continue\r
+                for F in Filenames:\r
+                    if os.path.splitext(F)[1] in ('.h', '.c'):\r
+                        FullName = os.path.join(Dirpath, F)\r
+                        MsgList = c.CheckDoxygenTripleForwardSlash(FullName)\r
         \r
     #\r
     # Check whether only Doxygen commands allowed to mark the code are @bug and @todo.\r
     #\r
     def DoxygenCheckCommand(self):\r
         if EccGlobalData.gConfig.DoxygenCheckCommand == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1':\r
-            pass\r
+            EdkLogger.quiet("Checking Doxygen command ...")\r
+            Tuple = os.walk(EccGlobalData.gTarget)\r
+            IgnoredPattern = re.compile(r'.*[\\/](?:BUILD|CVS|\.SVN|INTELRESTRICTEDTOOLS|INTELRESTRICTEDPKG)[\\/].*')\r
+        \r
+            for Dirpath, Dirnames, Filenames in Tuple:\r
+                if IgnoredPattern.match(Dirpath.upper()) or Dirpath.find('.svn') != -1:\r
+                    continue\r
+                for F in Filenames:\r
+                    if os.path.splitext(F)[1] in ('.h', '.c'):\r
+                        FullName = os.path.join(Dirpath, F)\r
+                        MsgList = c.CheckDoxygenCommand(FullName)\r
     \r
     #\r
     # Meta-Data File Processing Checking\r
index 2099593..ad05f1d 100644 (file)
@@ -231,8 +231,7 @@ def CollectSourceCodeDataIntoDB(RootDir):
 \r
     Db.UpdateIdentifierBelongsToFunction()\r
 \r
-def CheckFuncHeaderDoxygenComments(FullFileName):\r
-    ErrorMsgList = []\r
+def GetTableID(FullFileName, ErrorMsgList):\r
     Db = GetDB()\r
     \r
     SqlStatement = """ select ID\r
@@ -241,18 +240,134 @@ def CheckFuncHeaderDoxygenComments(FullFileName):
                    """ % FullFileName\r
     \r
     ResultSet = Db.TblFile.Exec(SqlStatement)\r
-    FileTable = 'Identifier'\r
+\r
     FileID = -1\r
     for Result in ResultSet:\r
-        FileTable += str(Result[0])\r
         if FileID != -1:\r
             ErrorMsgList.append('Duplicate file ID found in DB for file %s' % FullFileName)\r
-            return ErrorMsgList\r
+            return -2\r
         FileID = Result[0]\r
     if FileID == -1:\r
         ErrorMsgList.append('NO file ID found in DB for file %s' % FullFileName)\r
+        return -1\r
+    return FileID\r
+\r
+def CheckDoxygenCommand(FullFileName):\r
+    ErrorMsgList = []\r
+    \r
+    FileID = GetTableID(FullFileName, ErrorMsgList)\r
+    if FileID < 0:\r
+        return ErrorMsgList\r
+    \r
+    Db = GetDB()\r
+    FileTable = 'Identifier' + str(FileID)\r
+    SqlStatement = """ select Value, ID\r
+                       from %s\r
+                       where Model = %d or Model = %d\r
+                   """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT, DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER)\r
+    ResultSet = Db.TblFile.Exec(SqlStatement)\r
+    DoxygenCommandList = ['bug', 'todo', 'example', 'file', 'attention', 'param', 'post', 'pre', 'retval', 'return', 'sa', 'since', 'test', 'note', 'par']\r
+    for Result in ResultSet:\r
+        CommentStr = Result[0]\r
+        CommentPartList = CommentStr.split()\r
+        for Part in CommentPartList:\r
+            if Part.upper() == 'BUGBUG':\r
+                PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Bug should be marked with doxygen tag @bug', FileTable, Result[1])\r
+            if Part.upper() == 'TODO':\r
+                PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'ToDo should be marked with doxygen tag @todo', FileTable, Result[1])\r
+            if Part.startswith('@'):\r
+                if Part.lstrip('@').isalpha():\r
+                    if Part.lstrip('@') not in DoxygenCommandList:\r
+                        PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Unknown doxygen command %s' % Part, FileTable, Result[1])\r
+                else:\r
+                    Index = Part.find('[')\r
+                    if Index == -1:\r
+                        PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Unknown doxygen command %s' % Part, FileTable, Result[1])\r
+                    RealCmd = Part[1:Index]\r
+                    if RealCmd not in DoxygenCommandList:\r
+                        PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Unknown doxygen command %s' % Part, FileTable, Result[1])\r
+        \r
+    \r
+def CheckDoxygenTripleForwardSlash(FullFileName):\r
+    ErrorMsgList = []\r
+    \r
+    FileID = GetTableID(FullFileName, ErrorMsgList)\r
+    if FileID < 0:\r
+        return ErrorMsgList\r
+    \r
+    Db = GetDB()\r
+    FileTable = 'Identifier' + str(FileID)\r
+    SqlStatement = """ select Value, ID, StartLine\r
+                       from %s\r
+                       where Model = %d or Model = %d\r
+                   """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT, DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER)\r
+    ResultSet = Db.TblFile.Exec(SqlStatement)\r
+    CommentSet = []\r
+    try:\r
+        for Result in ResultSet:\r
+            CommentSet.append(Result)\r
+    except:\r
+        print 'Unrecognized chars in comment of file %s', FullFileName\r
+    \r
+    SqlStatement = """ select ID, StartLine, EndLine\r
+                       from %s\r
+                       where Model = %d or Model = %d or Model = %d\r
+                   """ % (FileTable, DataClass.MODEL_IDENTIFIER_STRUCTURE, DataClass.MODEL_IDENTIFIER_ENUMERATE, DataClass.MODEL_IDENTIFIER_UNION)\r
+    SUEResultSet = Db.TblFile.Exec(SqlStatement)\r
+    \r
+    for Result in CommentSet:\r
+        CommentStr = Result[0]\r
+        StartLine = Result[2]\r
+        if not CommentStr.startswith('///<'):\r
+            continue\r
+        if len(ResultSet) == 0:\r
+            PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMENT_FORMAT, '', FileTable, Result[1])\r
+            continue\r
+        Found = False\r
+        for SUE in SUEResultSet:\r
+            if StartLine > SUE[1] and StartLine < SUE[2]:\r
+                Found = True\r
+                break\r
+        if not Found:\r
+            PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMENT_FORMAT, '', FileTable, Result[1])\r
+\r
+\r
+def CheckFileHeaderDoxygenComments(FullFileName):\r
+    ErrorMsgList = []\r
+    \r
+    FileID = GetTableID(FullFileName, ErrorMsgList)\r
+    if FileID < 0:\r
+        return ErrorMsgList\r
+    \r
+    Db = GetDB()\r
+    FileTable = 'Identifier' + str(FileID)\r
+    SqlStatement = """ select Value, ID\r
+                       from %s\r
+                       where Model = %d and StartLine = 1 and StartColumn = 0\r
+                   """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT)\r
+    ResultSet = Db.TblFile.Exec(SqlStatement)\r
+    if len(ResultSet) == 0:\r
+        PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'No Comment appear at the very beginning of file.', 'File', FileID)\r
         return ErrorMsgList\r
     \r
+    for Result in ResultSet:\r
+        CommentStr = Result[0]\r
+        if not CommentStr.startswith('/** @file'):\r
+            PrintErrorMsg(ERROR_DOXYGEN_CHECK_FILE_HEADER, 'File header comment should begin with ""/** @file""', FileTable, Result[1])\r
+        if not CommentStr.endswith('**/'):\r
+            PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment should end with **/', FileTable, Result[1])\r
+        if CommentStr.find('.') == -1:\r
+            PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMENT_DESCRIPTION, 'Comment description should end with period \'.\'', FileTable, Result[1])\r
+\r
+def CheckFuncHeaderDoxygenComments(FullFileName):\r
+    ErrorMsgList = []\r
+    \r
+    FileID = GetTableID(FullFileName, ErrorMsgList)\r
+    if FileID < 0:\r
+        return ErrorMsgList\r
+    \r
+    Db = GetDB()\r
+    FileTable = 'Identifier' + str(FileID)\r
     SqlStatement = """ select Value, StartLine, EndLine, ID\r
                        from %s\r
                        where Model = %d\r
@@ -264,7 +379,7 @@ def CheckFuncHeaderDoxygenComments(FullFileName):
         for Result in ResultSet:\r
             CommentSet.append(Result)\r
     except:\r
-        print 'Unrecognized chars in comment'\r
+        print 'Unrecognized chars in comment of file %s', FullFileName\r
     \r
     # Func Decl check\r
     SqlStatement = """ select Modifier, Name, StartLine, ID\r
@@ -292,7 +407,7 @@ def CheckFuncHeaderDoxygenComments(FullFileName):
         for Result in ResultSet:\r
             CommentSet.append(Result)\r
     except:\r
-        print 'Unrecognized chars in comment'\r
+        print 'Unrecognized chars in comment of file %s', FullFileName\r
     \r
     SqlStatement = """ select Modifier, Header, StartLine, ID\r
                        from Function\r
@@ -323,7 +438,9 @@ def GetDoxygenStrFromComment(Str):
         while i < len(ParamTagList):\r
             DoxygenStrList.append('@param' + ParamTagList[i])\r
             i += 1\r
-        \r
+    \r
+    Str = ParamTagList[0]\r
+            \r
     RetvalTagList = ParamTagList[-1].split('@retval')\r
     if len(RetvalTagList) > 1:\r
         if len(ParamTagList) > 1:\r
@@ -356,7 +473,10 @@ def CheckFunctionHeaderConsistentWithDoxygenComment(FuncModifier, FuncHeader, Fu
     \r
     ParamList = GetParamList(FuncHeader) \r
     CheckGeneralDoxygenCommentLayout(CommentStr, CommentStartLine, ErrorMsgList, CommentId, TableName)\r
-    DoxygenStrList = GetDoxygenStrFromComment(CommentStr)\r
+    DescriptionStr = CommentStr\r
+    DoxygenStrList = GetDoxygenStrFromComment(DescriptionStr)\r
+    if DescriptionStr.find('.') == -1:\r
+        PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMENT_DESCRIPTION, 'Comment description should end with period \'.\'', TableName, CommentId)\r
     DoxygenTagNumber = len(DoxygenStrList)\r
     ParamNumber = len(ParamList)\r
     Index = 0\r