]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/Ecc/MetaDataParser.py
Sync BaseTool trunk (version r2460) into EDKII BaseTools. The change mainly includes:
[mirror_edk2.git] / BaseTools / Source / Python / Ecc / MetaDataParser.py
index 4dda2e53600126c91c84abda4fed36d018b581b4..bbafa00dddd127e0660c40d824a830d97afe87f3 100644 (file)
@@ -13,8 +13,9 @@
 \r
 import os\r
 from CommonDataClass.DataClass import *\r
-\r
-\r
+from EccToolError import *\r
+import EccGlobalData\r
+import re\r
 ## Get the inlcude path list for a source file\r
 #\r
 # 1. Find the source file belongs to which inf file\r
@@ -76,3 +77,188 @@ def GetTableList(FileModelList, Table, Db):
 \r
     return TableList\r
 \r
+## ParseHeaderCommentSection\r
+#\r
+# Parse Header comment section lines, extract Abstract, Description, Copyright\r
+# , License lines\r
+#\r
+# @param CommentList:   List of (Comment, LineNumber)\r
+# @param FileName:      FileName of the comment\r
+#\r
+def ParseHeaderCommentSection(CommentList, FileName = None):\r
+    \r
+    Abstract = ''\r
+    Description = ''\r
+    Copyright = ''\r
+    License = ''\r
+    EndOfLine = "\n"\r
+    STR_HEADER_COMMENT_START = "@file"\r
+    \r
+    #\r
+    # used to indicate the state of processing header comment section of dec, \r
+    # inf files\r
+    #\r
+    HEADER_COMMENT_NOT_STARTED = -1\r
+    HEADER_COMMENT_STARTED     = 0\r
+    HEADER_COMMENT_FILE        = 1\r
+    HEADER_COMMENT_ABSTRACT    = 2\r
+    HEADER_COMMENT_DESCRIPTION = 3\r
+    HEADER_COMMENT_COPYRIGHT   = 4\r
+    HEADER_COMMENT_LICENSE     = 5\r
+    HEADER_COMMENT_END         = 6\r
+    #\r
+    # first find the last copyright line\r
+    #\r
+    Last = 0\r
+    HeaderCommentStage = HEADER_COMMENT_NOT_STARTED\r
+    for Index in xrange(len(CommentList)-1, 0, -1):\r
+        Line = CommentList[Index][0]\r
+        if _IsCopyrightLine(Line):\r
+            Last = Index\r
+            break\r
+    \r
+    for Item in CommentList:\r
+        Line = Item[0]\r
+        LineNo = Item[1]\r
+        \r
+        if not Line.startswith('#') and Line:\r
+            SqlStatement = """ select ID from File where FullPath like '%s'""" % FileName\r
+            ResultSet = EccGlobalData.gDb.TblFile.Exec(SqlStatement)\r
+            for Result in ResultSet:\r
+                Msg = 'Comment must start with #'\r
+                EccGlobalData.gDb.TblReport.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER, Msg, "File", Result[0])\r
+        Comment = CleanString2(Line)[1]\r
+        Comment = Comment.strip()\r
+        #\r
+        # if there are blank lines between License or Description, keep them as they would be \r
+        # indication of different block; or in the position that Abstract should be, also keep it\r
+        # as it indicates that no abstract\r
+        #\r
+        if not Comment and HeaderCommentStage not in [HEADER_COMMENT_LICENSE, \\r
+                                                      HEADER_COMMENT_DESCRIPTION, HEADER_COMMENT_ABSTRACT]:\r
+            continue\r
+        \r
+        if HeaderCommentStage == HEADER_COMMENT_NOT_STARTED:\r
+            if Comment.startswith(STR_HEADER_COMMENT_START):\r
+                HeaderCommentStage = HEADER_COMMENT_ABSTRACT\r
+            else:\r
+                License += Comment + EndOfLine\r
+        else:\r
+            if HeaderCommentStage == HEADER_COMMENT_ABSTRACT:\r
+                #\r
+                # in case there is no abstract and description\r
+                #\r
+                if not Comment:\r
+                    Abstract = ''\r
+                    HeaderCommentStage = HEADER_COMMENT_DESCRIPTION\r
+                elif _IsCopyrightLine(Comment):                    \r
+                    Copyright += Comment + EndOfLine\r
+                    HeaderCommentStage = HEADER_COMMENT_COPYRIGHT\r
+                else:                    \r
+                    Abstract += Comment + EndOfLine\r
+                    HeaderCommentStage = HEADER_COMMENT_DESCRIPTION\r
+            elif HeaderCommentStage == HEADER_COMMENT_DESCRIPTION:\r
+                #\r
+                # in case there is no description\r
+                #                \r
+                if _IsCopyrightLine(Comment):                    \r
+                    Copyright += Comment + EndOfLine\r
+                    HeaderCommentStage = HEADER_COMMENT_COPYRIGHT\r
+                else:\r
+                    Description += Comment + EndOfLine                \r
+            elif HeaderCommentStage == HEADER_COMMENT_COPYRIGHT:\r
+                if _IsCopyrightLine(Comment):                    \r
+                    Copyright += Comment + EndOfLine\r
+                else:\r
+                    #\r
+                    # Contents after copyright line are license, those non-copyright lines in between\r
+                    # copyright line will be discarded \r
+                    #\r
+                    if LineNo > Last:\r
+                        if License:\r
+                            License += EndOfLine\r
+                        License += Comment + EndOfLine\r
+                        HeaderCommentStage = HEADER_COMMENT_LICENSE                \r
+            else:\r
+                if not Comment and not License:\r
+                    continue\r
+                License += Comment + EndOfLine\r
+    \r
+    if not Copyright:\r
+        SqlStatement = """ select ID from File where FullPath like '%s'""" % FileName\r
+        ResultSet = EccGlobalData.gDb.TblFile.Exec(SqlStatement)\r
+        for Result in ResultSet:\r
+            Msg = 'Header comment section must have copyright information'\r
+            EccGlobalData.gDb.TblReport.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER, Msg, "File", Result[0])\r
+\r
+    if not License:\r
+        SqlStatement = """ select ID from File where FullPath like '%s'""" % FileName\r
+        ResultSet = EccGlobalData.gDb.TblFile.Exec(SqlStatement)\r
+        for Result in ResultSet:\r
+            Msg = 'Header comment section must have license information'\r
+            EccGlobalData.gDb.TblReport.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER, Msg, "File", Result[0])\r
+                     \r
+    return Abstract.strip(), Description.strip(), Copyright.strip(), License.strip()\r
+\r
+## _IsCopyrightLine\r
+# check whether current line is copyright line, the criteria is whether there is case insensitive keyword "Copyright" \r
+# followed by zero or more white space characters followed by a "(" character \r
+#\r
+# @param LineContent:  the line need to be checked\r
+# @return: True if current line is copyright line, False else\r
+#\r
+def _IsCopyrightLine (LineContent):\r
+    LineContent = LineContent.upper()\r
+    Result = False\r
+    \r
+    ReIsCopyrightRe = re.compile(r"""(^|\s)COPYRIGHT *\(""", re.DOTALL)\r
+    if ReIsCopyrightRe.search(LineContent):\r
+        Result = True\r
+        \r
+    return Result\r
+\r
+\r
+## CleanString2\r
+#\r
+# Split comments in a string\r
+# Remove spaces\r
+#\r
+# @param Line:              The string to be cleaned\r
+# @param CommentCharacter:  Comment char, used to ignore comment content, \r
+#                           default is DataType.TAB_COMMENT_SPLIT\r
+#\r
+def CleanString2(Line, CommentCharacter='#', AllowCppStyleComment=False):\r
+    #\r
+    # remove whitespace\r
+    #\r
+    Line = Line.strip()\r
+    #\r
+    # Replace EDK1's comment character\r
+    #\r
+    if AllowCppStyleComment:\r
+        Line = Line.replace('//', CommentCharacter)\r
+    #\r
+    # separate comments and statements\r
+    #\r
+    LineParts = Line.split(CommentCharacter, 1)\r
+    #\r
+    # remove whitespace again\r
+    #\r
+    Line = LineParts[0].strip()\r
+    if len(LineParts) > 1:\r
+        Comment = LineParts[1].strip()\r
+        #\r
+        # Remove prefixed and trailing comment characters\r
+        #\r
+        Start = 0\r
+        End = len(Comment)\r
+        while Start < End and Comment.startswith(CommentCharacter, Start, End):\r
+            Start += 1\r
+        while End >= 0 and Comment.endswith(CommentCharacter, Start, End):\r
+            End -= 1\r
+        Comment = Comment[Start:End]\r
+        Comment = Comment.strip()\r
+    else:\r
+        Comment = ''\r
+\r
+    return Line, Comment\r