]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/Ecc/c.py
BaseTools/Capsule: Do not support -o with --dump-info
[mirror_edk2.git] / BaseTools / Source / Python / Ecc / c.py
index 532f4a0918a8a16f2fa642ea1d875a3a5b4533a6..5616c108533e47b51cdd062dfed64ea8df90acba 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # This file is used to be the c coding style checking of ECC tool\r
 #\r
-# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\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
 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 #\r
 \r
+from __future__ import print_function\r
+from __future__ import absolute_import\r
 import sys\r
-import os\r
+import Common.LongFilePathOs as os\r
 import re\r
 import string\r
-import CodeFragmentCollector\r
-import FileProfile\r
+from . import CodeFragmentCollector\r
+from . import FileProfile\r
 from CommonDataClass import DataClass\r
-import Database\r
+from . import Database\r
 from Common import EdkLogger\r
-from EccToolError import *\r
-import EccGlobalData\r
-import MetaDataParser\r
+from .EccToolError import *\r
+from . import EccGlobalData\r
+from . import MetaDataParser\r
 \r
 IncludeFileListDict = {}\r
 AllIncludeFileListDict = {}\r
@@ -271,7 +273,7 @@ def GetIdentifierList():
 def StripNonAlnumChars(Str):\r
     StrippedStr = ''\r
     for Char in Str:\r
-        if Char.isalnum():\r
+        if Char.isalnum() or Char == '_':\r
             StrippedStr += Char\r
     return StrippedStr\r
 \r
@@ -514,6 +516,8 @@ def CollectSourceCodeDataIntoDB(RootDir):
                     dirnames.append(Dirname)\r
 \r
         for f in filenames:\r
+            if f.lower() in EccGlobalData.gConfig.SkipFileList:\r
+                continue\r
             collector = None\r
             FullName = os.path.normpath(os.path.join(dirpath, f))\r
             model = DataClass.MODEL_FILE_OTHERS\r
@@ -548,7 +552,7 @@ def CollectSourceCodeDataIntoDB(RootDir):
     Db.UpdateIdentifierBelongsToFunction()\r
 \r
 def GetTableID(FullFileName, ErrorMsgList=None):\r
-    if ErrorMsgList == None:\r
+    if ErrorMsgList is None:\r
         ErrorMsgList = []\r
 \r
     Db = GetDB()\r
@@ -573,7 +577,7 @@ def GetIncludeFileList(FullFileName):
     if os.path.splitext(FullFileName)[1].upper() not in ('.H'):\r
         return []\r
     IFList = IncludeFileListDict.get(FullFileName)\r
-    if IFList != None:\r
+    if IFList is not None:\r
         return IFList\r
 \r
     FileID = GetTableID(FullFileName)\r
@@ -599,12 +603,12 @@ def GetFullPathOfIncludeFile(Str, IncludePathList):
     return None\r
 \r
 def GetAllIncludeFiles(FullFileName):\r
-    if AllIncludeFileListDict.get(FullFileName) != None:\r
+    if AllIncludeFileListDict.get(FullFileName) is not None:\r
         return AllIncludeFileListDict.get(FullFileName)\r
 \r
     FileDirName = os.path.dirname(FullFileName)\r
     IncludePathList = IncludePathListDict.get(FileDirName)\r
-    if IncludePathList == None:\r
+    if IncludePathList is None:\r
         IncludePathList = MetaDataParser.GetIncludeListOfFile(EccGlobalData.gWorkspace, FullFileName, GetDB())\r
         if FileDirName not in IncludePathList:\r
             IncludePathList.insert(0, FileDirName)\r
@@ -616,7 +620,7 @@ def GetAllIncludeFiles(FullFileName):
         FileName = FileName.strip('\"')\r
         FileName = FileName.lstrip('<').rstrip('>').strip()\r
         FullPath = GetFullPathOfIncludeFile(FileName, IncludePathList)\r
-        if FullPath != None:\r
+        if FullPath is not None:\r
             IncludeFileQueue.append(FullPath)\r
 \r
     i = 0\r
@@ -627,7 +631,7 @@ def GetAllIncludeFiles(FullFileName):
             FileName = FileName.strip('\"')\r
             FileName = FileName.lstrip('<').rstrip('>').strip()\r
             FullPath = GetFullPathOfIncludeFile(FileName, IncludePathList)\r
-            if FullPath != None and FullPath not in IncludeFileQueue:\r
+            if FullPath is not None and FullPath not in IncludeFileQueue:\r
                 IncludeFileQueue.insert(i + 1, FullPath)\r
         i += 1\r
 \r
@@ -828,7 +832,7 @@ 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
         if M.startswith('[') or M.endswith(']'):\r
@@ -851,7 +855,7 @@ def DiffModifier(Str1, Str2):
 def GetTypedefDict(FullFileName):\r
 \r
     Dict = ComplexTypeDict.get(FullFileName)\r
-    if Dict != None:\r
+    if Dict is not None:\r
         return Dict\r
 \r
     FileID = GetTableID(FullFileName)\r
@@ -896,7 +900,7 @@ def GetTypedefDict(FullFileName):
 def GetSUDict(FullFileName):\r
 \r
     Dict = SUDict.get(FullFileName)\r
-    if Dict != None:\r
+    if Dict is not None:\r
         return Dict\r
 \r
     FileID = GetTableID(FullFileName)\r
@@ -981,9 +985,9 @@ def StripComments(Str):
 \r
 def GetFinalTypeValue(Type, FieldName, TypedefDict, SUDict):\r
     Value = TypedefDict.get(Type)\r
-    if Value == None:\r
+    if Value is None:\r
         Value = SUDict.get(Type)\r
-    if Value == None:\r
+    if Value is None:\r
         return None\r
 \r
     LBPos = Value.find('{')\r
@@ -992,11 +996,11 @@ def GetFinalTypeValue(Type, FieldName, TypedefDict, SUDict):
         for FT in FTList:\r
             if FT not in ('struct', 'union'):\r
                 Value = TypedefDict.get(FT)\r
-                if Value == None:\r
+                if Value is None:\r
                     Value = SUDict.get(FT)\r
                 break\r
 \r
-        if Value == None:\r
+        if Value is None:\r
             return None\r
 \r
         LBPos = Value.find('{')\r
@@ -1023,11 +1027,11 @@ def GetFinalTypeValue(Type, FieldName, TypedefDict, SUDict):
     return None\r
 \r
 def GetRealType(Type, TypedefDict, TargetType=None):\r
-    if TargetType != None and Type == TargetType:\r
+    if TargetType is not None and Type == TargetType:\r
             return Type\r
     while TypedefDict.get(Type):\r
         Type = TypedefDict.get(Type)\r
-        if TargetType != None and Type == TargetType:\r
+        if TargetType is not None and Type == TargetType:\r
             return Type\r
     return Type\r
 \r
@@ -1041,10 +1045,10 @@ def GetTypeInfo(RefList, Modifier, FullFileName, TargetType=None):
     while Index < len(RefList):\r
         FieldName = RefList[Index]\r
         FromType = GetFinalTypeValue(Type, FieldName, TypedefDict, SUDict)\r
-        if FromType == None:\r
+        if FromType is None:\r
             return None\r
         # we want to determine the exact type.\r
-        if TargetType != None:\r
+        if TargetType is not None:\r
             Type = FromType.split()[0]\r
         # we only want to check if it is a pointer\r
         else:\r
@@ -1149,7 +1153,7 @@ def GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall=False, TargetTy
 #            Type = GetDataTypeFromModifier(Result[0]).split()[-1]\r
             TypeList = GetDataTypeFromModifier(Result[0]).split()\r
             Type = TypeList[-1]\r
-            if len(TypeList) > 1 and StarList != None:\r
+            if len(TypeList) > 1 and StarList is not None:\r
                 for Star in StarList:\r
                     Type = Type.strip()\r
                     Type = Type.rstrip(Star)\r
@@ -1170,7 +1174,9 @@ def GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall=False, TargetTy
             else:\r
                 TypeList = GetDataTypeFromModifier(Param.Modifier).split()\r
                 Type = TypeList[-1]\r
-                if len(TypeList) > 1 and StarList != None:\r
+                if Type == '*' and len(TypeList) >= 2:\r
+                    Type = TypeList[-2]\r
+                if len(TypeList) > 1 and StarList is not None:\r
                     for Star in StarList:\r
                         Type = Type.strip()\r
                         Type = Type.rstrip(Star)\r
@@ -1195,7 +1201,7 @@ def GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall=False, TargetTy
         else:\r
             TypeList = GetDataTypeFromModifier(Result[0]).split()\r
             Type = TypeList[-1]\r
-            if len(TypeList) > 1 and StarList != None:\r
+            if len(TypeList) > 1 and StarList is not None:\r
                 for Star in StarList:\r
                     Type = Type.strip()\r
                     Type = Type.rstrip(Star)\r
@@ -1226,7 +1232,7 @@ def GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall=False, TargetTy
             else:\r
                 TypeList = GetDataTypeFromModifier(Result[0]).split()\r
                 Type = TypeList[-1]\r
-                if len(TypeList) > 1 and StarList != None:\r
+                if len(TypeList) > 1 and StarList is not None:\r
                     for Star in StarList:\r
                         Type = Type.strip()\r
                         Type = Type.rstrip(Star)\r
@@ -1267,7 +1273,10 @@ def CheckFuncLayoutReturnType(FullFileName):
         FuncName = Result[5]\r
         if EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, FuncName):\r
             continue\r
-        Index = Result[0].find(TypeStart)\r
+        Result0 = Result[0]\r
+        if Result0.upper().startswith('STATIC'):\r
+            Result0 = Result0[6:].strip()\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, FileTable, Result[1])\r
 \r
@@ -1285,13 +1294,13 @@ def CheckFuncLayoutReturnType(FullFileName):
         FuncName = Result[5]\r
         if EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, FuncName):\r
             continue\r
-        Index = Result[0].find(ReturnType)\r
+        Result0 = Result[0]\r
+        if Result0.upper().startswith('STATIC'):\r
+            Result0 = Result0[6:].strip()\r
+        Index = Result0.find(ReturnType)\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
-        if Result[2] == Result[4]:\r
-            PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '[%s] Return Type should appear on its own line' % FuncName, 'Function', Result[1])\r
-\r
 def CheckFuncLayoutModifier(FullFileName):\r
     ErrorMsgList = []\r
 \r
@@ -1309,9 +1318,10 @@ def CheckFuncLayoutModifier(FullFileName):
     for Result in ResultSet:\r
         ReturnType = GetDataTypeFromModifier(Result[0])\r
         TypeStart = ReturnType.split()[0]\r
-#        if len(ReturnType) == 0:\r
-#            continue\r
-        Index = Result[0].find(TypeStart)\r
+        Result0 = Result[0]\r
+        if Result0.upper().startswith('STATIC'):\r
+            Result0 = Result0[6:].strip()\r
+        Index = Result0.find(TypeStart)\r
         if Index != 0:\r
             PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_OPTIONAL_FUNCTIONAL_MODIFIER, '', FileTable, Result[1])\r
 \r
@@ -1323,9 +1333,10 @@ def CheckFuncLayoutModifier(FullFileName):
     for Result in ResultSet:\r
         ReturnType = GetDataTypeFromModifier(Result[0])\r
         TypeStart = ReturnType.split()[0]\r
-#        if len(ReturnType) == 0:\r
-#            continue\r
-        Index = Result[0].find(TypeStart)\r
+        Result0 = Result[0]\r
+        if Result0.upper().startswith('STATIC'):\r
+            Result0 = Result0[6:].strip()\r
+        Index = Result0.find(TypeStart)\r
         if Index != 0:\r
             PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_OPTIONAL_FUNCTIONAL_MODIFIER, '', 'Function', Result[1])\r
 \r
@@ -1559,7 +1570,7 @@ def CheckMemberVariableFormat(Name, Value, FileTable, TdId, ModelId):
     Fields = Value[LBPos + 1 : RBPos]\r
     Fields = StripComments(Fields).strip()\r
     NestPos = Fields.find ('struct')\r
-    if NestPos != -1 and (NestPos + len('struct') < len(Fields)):\r
+    if NestPos != -1 and (NestPos + len('struct') < len(Fields)) and ModelId != DataClass.MODEL_IDENTIFIER_UNION:\r
         if not Fields[NestPos + len('struct') + 1].isalnum():\r
             if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, Name):\r
                 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, 'Nested struct in [%s].' % (Name), FileTable, TdId)\r
@@ -1624,12 +1635,17 @@ def CheckMemberVariableFormat(Name, Value, FileTable, TdId, ModelId):
         Field = Field.strip()\r
         if Field == '':\r
             continue\r
+        if Field.startswith("#"):\r
+            continue\r
         # Enum could directly assign value to variable\r
         Field = Field.split('=')[0].strip()\r
         TokenList = Field.split()\r
         # Remove pointers before variable\r
-        if not Pattern.match(TokenList[-1].lstrip('*')):\r
-            ErrMsgList.append(TokenList[-1].lstrip('*'))\r
+        Token = TokenList[-1]\r
+        if Token in ['OPTIONAL']:\r
+            Token = TokenList[-2]\r
+        if not Pattern.match(Token.lstrip('*')):\r
+            ErrMsgList.append(Token.lstrip('*'))\r
 \r
     return ErrMsgList\r
 \r
@@ -1844,7 +1860,13 @@ def CheckDeclNoUseCType(FullFileName):
     for Result in ResultSet:\r
         for Type in CTypeTuple:\r
             if PatternInModifier(Result[0], Type):\r
-                PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, 'Variable type %s' % Type, FileTable, Result[2])\r
+                if EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE,\r
+                                                        Result[0] + ' ' + Result[1]):\r
+                    continue\r
+                PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE,\r
+                              'Invalid variable type (%s) in definition [%s]' % (Type, Result[0] + ' ' + Result[1]),\r
+                              FileTable,\r
+                              Result[2])\r
                 break\r
 \r
     SqlStatement = """ select Modifier, Name, ID, Value\r
@@ -1919,12 +1941,12 @@ def CheckPointerNullComparison(FullFileName):
     p = GetFuncDeclPattern()\r
     for Str in PSL:\r
         FuncRecord = GetFuncContainsPE(Str[1], FL)\r
-        if FuncRecord == None:\r
+        if FuncRecord is None:\r
             continue\r
 \r
         for Exp in GetPredicateListFromPredicateExpStr(Str[0]):\r
             PredInfo = SplitPredicateStr(Exp)\r
-            if PredInfo[1] == None:\r
+            if PredInfo[1] is None:\r
                 PredVarStr = PredInfo[0][0].strip()\r
                 IsFuncCall = False\r
                 SearchInCache = False\r
@@ -1946,7 +1968,7 @@ def CheckPointerNullComparison(FullFileName):
                     continue\r
                 if SearchInCache:\r
                     Type = FuncReturnTypeDict.get(PredVarStr)\r
-                    if Type != None:\r
+                    if Type is not None:\r
                         if Type.find('*') != -1 and Type != 'BOOLEAN*':\r
                             PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
                         continue\r
@@ -1957,7 +1979,7 @@ def CheckPointerNullComparison(FullFileName):
                 Type = GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall, None, StarList)\r
                 if SearchInCache:\r
                     FuncReturnTypeDict[PredVarStr] = Type\r
-                if Type == None:\r
+                if Type is None:\r
                     continue\r
                 Type = GetTypeFromArray(Type, PredVarStr)\r
                 if Type.find('*') != -1 and Type != 'BOOLEAN*':\r
@@ -1998,12 +2020,12 @@ def CheckNonBooleanValueComparison(FullFileName):
     p = GetFuncDeclPattern()\r
     for Str in PSL:\r
         FuncRecord = GetFuncContainsPE(Str[1], FL)\r
-        if FuncRecord == None:\r
+        if FuncRecord is None:\r
             continue\r
 \r
         for Exp in GetPredicateListFromPredicateExpStr(Str[0]):\r
             PredInfo = SplitPredicateStr(Exp)\r
-            if PredInfo[1] == None:\r
+            if PredInfo[1] is None:\r
                 PredVarStr = PredInfo[0][0].strip()\r
                 IsFuncCall = False\r
                 SearchInCache = False\r
@@ -2026,7 +2048,7 @@ def CheckNonBooleanValueComparison(FullFileName):
 \r
                 if SearchInCache:\r
                     Type = FuncReturnTypeDict.get(PredVarStr)\r
-                    if Type != None:\r
+                    if Type is not None:\r
                         if Type.find('BOOLEAN') == -1:\r
                             PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
                         continue\r
@@ -2036,7 +2058,7 @@ def CheckNonBooleanValueComparison(FullFileName):
                 Type = GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall, 'BOOLEAN', StarList)\r
                 if SearchInCache:\r
                     FuncReturnTypeDict[PredVarStr] = Type\r
-                if Type == None:\r
+                if Type is None:\r
                     continue\r
                 if Type.find('BOOLEAN') == -1:\r
                     PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
@@ -2077,7 +2099,7 @@ def CheckBooleanValueComparison(FullFileName):
     p = GetFuncDeclPattern()\r
     for Str in PSL:\r
         FuncRecord = GetFuncContainsPE(Str[1], FL)\r
-        if FuncRecord == None:\r
+        if FuncRecord is None:\r
             continue\r
 \r
         for Exp in GetPredicateListFromPredicateExpStr(Str[0]):\r
@@ -2105,7 +2127,7 @@ def CheckBooleanValueComparison(FullFileName):
 \r
                 if SearchInCache:\r
                     Type = FuncReturnTypeDict.get(PredVarStr)\r
-                    if Type != None:\r
+                    if Type is not None:\r
                         if Type.find('BOOLEAN') != -1:\r
                             PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
                         continue\r
@@ -2116,7 +2138,7 @@ def CheckBooleanValueComparison(FullFileName):
                 Type = GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall, 'BOOLEAN', StarList)\r
                 if SearchInCache:\r
                     FuncReturnTypeDict[PredVarStr] = Type\r
-                if Type == None:\r
+                if Type is None:\r
                     continue\r
                 if Type.find('BOOLEAN') != -1:\r
                     PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
@@ -2202,7 +2224,8 @@ def CheckDoxygenCommand(FullFileName):
                        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
+    DoxygenCommandList = ['bug', 'todo', 'example', 'file', 'attention', 'param', 'post', 'pre', 'retval',\r
+                          'return', 'sa', 'since', 'test', 'note', 'par', 'endcode', 'code']\r
     for Result in ResultSet:\r
         CommentStr = Result[0]\r
         CommentPartList = CommentStr.split()\r
@@ -2214,6 +2237,10 @@ def CheckDoxygenCommand(FullFileName):
             if Part.startswith('@'):\r
                 if EccGlobalData.gException.IsException(ERROR_DOXYGEN_CHECK_COMMAND, Part):\r
                     continue\r
+                if not Part.replace('@', '').strip():\r
+                    continue\r
+                if Part.lstrip('@') in ['{', '}']:\r
+                    continue\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
@@ -2260,7 +2287,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
@@ -2305,28 +2332,93 @@ def CheckFileHeaderDoxygenComments(FullFileName):
                    """ % (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
+        PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'No File License header appear at the very beginning of file.', 'File', FileID)\r
         return ErrorMsgList\r
 \r
-    IsFoundError1 = True\r
-    IsFoundError2 = True\r
-    IsFoundError3 = True\r
+    NoHeaderCommentStartFlag = True\r
+    NoHeaderCommentEndFlag = True\r
+    NoHeaderCommentPeriodFlag = True\r
+    NoCopyrightFlag = True\r
+    NoLicenseFlag = True\r
+    NoRevReferFlag = True\r
+    NextLineIndex = 0\r
     for Result in ResultSet:\r
+        FileStartFlag = False\r
+        CommentStrList = []\r
         CommentStr = Result[0].strip()\r
+        CommentStrListTemp = CommentStr.split('\n')\r
+        if (len(CommentStrListTemp) <= 1):\r
+            # For Mac\r
+            CommentStrListTemp = CommentStr.split('\r')\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
         ID = Result[1]\r
-        if CommentStr.startswith('/** @file'):\r
-            IsFoundError1 = False\r
-        if CommentStr.endswith('**/'):\r
-            IsFoundError2 = False\r
-        if CommentStr.find('.') != -1:\r
-            IsFoundError3 = False\r
-\r
-    if IsFoundError1:\r
+        Index = 0\r
+        if CommentStrList and CommentStrList[0].strip().startswith('/** @file'):\r
+            NoHeaderCommentStartFlag = False\r
+        else:\r
+            continue\r
+        if CommentStrList and CommentStrList[-1].strip().endswith('**/'):\r
+            NoHeaderCommentEndFlag = False\r
+        else:\r
+            continue\r
+\r
+        for CommentLine in CommentStrList:\r
+            Index = Index + 1\r
+            NextLineIndex = Index\r
+            if CommentLine.startswith('/** @file'):\r
+                continue\r
+            if CommentLine.startswith('**/'):\r
+                break\r
+            # Check whether C File header Comment content start with two spaces.\r
+            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
+            CommentLine = CommentLine.strip()\r
+            if CommentLine.startswith('Copyright'):\r
+                NoCopyrightFlag = False\r
+                if CommentLine.find('All rights reserved') == -1:\r
+                    for Copyright in EccGlobalData.gConfig.Copyright:\r
+                        if CommentLine.find(Copyright) > -1:\r
+                            PrintErrorMsg(ERROR_HEADER_CHECK_FILE, '""All rights reserved"" announcement should be following the ""Copyright"" at the same line', FileTable, ID)\r
+                            break\r
+                if CommentLine.endswith('<BR>') == -1:\r
+                    PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'The ""<BR>"" at the end of the Copyright line is required', FileTable, ID)\r
+                if NextLineIndex < len(CommentStrList) and CommentStrList[NextLineIndex].strip().startswith('Copyright') == False and CommentStrList[NextLineIndex].strip():\r
+                    NoLicenseFlag = False\r
+            if CommentLine.startswith('@par Revision Reference:'):\r
+                NoRevReferFlag = False\r
+                RefListFlag = False\r
+                for RefLine in CommentStrList[NextLineIndex:]:\r
+                    if RefLine.strip() and (NextLineIndex + 1) < len(CommentStrList) and CommentStrList[NextLineIndex+1].strip() and CommentStrList[NextLineIndex+1].strip().startswith('**/') == False:\r
+                        RefListFlag = True\r
+                    if RefLine.strip() == False or RefLine.strip().startswith('**/'):\r
+                        RefListFlag = False\r
+                        break\r
+                    # 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 NoHeaderCommentStartFlag:\r
         PrintErrorMsg(ERROR_DOXYGEN_CHECK_FILE_HEADER, 'File header comment should begin with ""/** @file""', FileTable, ID)\r
-    if IsFoundError2:\r
+        return\r
+    if NoHeaderCommentEndFlag:\r
         PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment should end with ""**/""', FileTable, ID)\r
-    if IsFoundError3:\r
-        PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMENT_DESCRIPTION, 'Comment description should end with period "".""', FileTable, ID)\r
+        return\r
+    if NoCopyrightFlag:\r
+        PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment missing the ""Copyright""', FileTable, ID)\r
+    #Check whether C File header Comment have the License immediately after the ""Copyright"" line.\r
+    if EccGlobalData.gConfig.HeaderCheckCFileCommentLicenseFormat == '1' or EccGlobalData.gConfig.HeaderCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
+        if NoLicenseFlag:\r
+            PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment should have the License immediately after the ""Copyright"" line', FileTable, ID)\r
 \r
 def CheckFuncHeaderDoxygenComments(FullFileName):\r
     ErrorMsgList = []\r
@@ -2348,7 +2440,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
@@ -2379,7 +2471,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
@@ -2543,10 +2635,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