]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/Ecc/c.py
BaseTools/ECC: Add a new exception support
[mirror_edk2.git] / BaseTools / Source / Python / Ecc / c.py
index 4c831e0ff72e8ffc49bca9d400de5133b10fc8bf..39a9d8ac363a8abeb1cbe060010ad0c98b6a633c 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
@@ -12,7 +12,7 @@
 #\r
 \r
 import sys\r
-import os\r
+import Common.LongFilePathOs as os\r
 import re\r
 import string\r
 import CodeFragmentCollector\r
@@ -62,7 +62,7 @@ def PrintErrorMsg(ErrorType, Msg, TableName, ItemId):
     for Part in MsgPartList:\r
         Msg += Part\r
         Msg += ' '\r
-    GetDB().TblReport.Insert(ErrorType, OtherMsg = Msg, BelongsToTable = TableName, BelongsToItem = ItemId)\r
+    GetDB().TblReport.Insert(ErrorType, OtherMsg=Msg, BelongsToTable=TableName, BelongsToItem=ItemId)\r
 \r
 def GetIdType(Str):\r
     Type = DataClass.MODEL_UNKNOWN\r
@@ -93,16 +93,16 @@ def SuOccurInTypedef (Su, TdList):
 def GetIdentifierList():\r
     IdList = []\r
     for comment in FileProfile.CommentList:\r
-        IdComment = DataClass.IdentifierClass(-1, '', '', '', comment.Content, DataClass.MODEL_IDENTIFIER_COMMENT, -1, -1, comment.StartPos[0],comment.StartPos[1],comment.EndPos[0],comment.EndPos[1])\r
+        IdComment = DataClass.IdentifierClass(-1, '', '', '', comment.Content, DataClass.MODEL_IDENTIFIER_COMMENT, -1, -1, comment.StartPos[0], comment.StartPos[1], comment.EndPos[0], comment.EndPos[1])\r
         IdList.append(IdComment)\r
 \r
     for pp in FileProfile.PPDirectiveList:\r
         Type = GetIdType(pp.Content)\r
-        IdPP = DataClass.IdentifierClass(-1, '', '', '', pp.Content, Type, -1, -1, pp.StartPos[0],pp.StartPos[1],pp.EndPos[0],pp.EndPos[1])\r
+        IdPP = DataClass.IdentifierClass(-1, '', '', '', pp.Content, Type, -1, -1, pp.StartPos[0], pp.StartPos[1], pp.EndPos[0], pp.EndPos[1])\r
         IdList.append(IdPP)\r
 \r
     for pe in FileProfile.PredicateExpressionList:\r
-        IdPE = DataClass.IdentifierClass(-1, '', '', '', pe.Content, DataClass.MODEL_IDENTIFIER_PREDICATE_EXPRESSION, -1, -1, pe.StartPos[0],pe.StartPos[1],pe.EndPos[0],pe.EndPos[1])\r
+        IdPE = DataClass.IdentifierClass(-1, '', '', '', pe.Content, DataClass.MODEL_IDENTIFIER_PREDICATE_EXPRESSION, -1, -1, pe.StartPos[0], pe.StartPos[1], pe.EndPos[0], pe.EndPos[1])\r
         IdList.append(IdPE)\r
 \r
     FuncDeclPattern = GetFuncDeclPattern()\r
@@ -191,7 +191,7 @@ def GetIdentifierList():
                     var.Modifier += ' ' + Name[LSBPos:]\r
                     Name = Name[0:LSBPos]\r
 \r
-                IdVar = DataClass.IdentifierClass(-1, var.Modifier, '', Name, (len(DeclList) > 1 and [DeclList[1]]or [''])[0], DataClass.MODEL_IDENTIFIER_VARIABLE, -1, -1, var.StartPos[0],var.StartPos[1], VarNameStartLine, VarNameStartColumn)\r
+                IdVar = DataClass.IdentifierClass(-1, var.Modifier, '', Name, (len(DeclList) > 1 and [DeclList[1]]or [''])[0], DataClass.MODEL_IDENTIFIER_VARIABLE, -1, -1, var.StartPos[0], var.StartPos[1], VarNameStartLine, VarNameStartColumn)\r
                 IdList.append(IdVar)\r
         else:\r
             DeclList = var.Declarator.split('=')\r
@@ -200,15 +200,15 @@ def GetIdentifierList():
                 LSBPos = var.Declarator.find('[')\r
                 var.Modifier += ' ' + Name[LSBPos:]\r
                 Name = Name[0:LSBPos]\r
-            IdVar = DataClass.IdentifierClass(-1, var.Modifier, '', Name, (len(DeclList) > 1 and [DeclList[1]]or [''])[0], DataClass.MODEL_IDENTIFIER_VARIABLE, -1, -1, var.StartPos[0],var.StartPos[1], VarNameStartLine, VarNameStartColumn)\r
+            IdVar = DataClass.IdentifierClass(-1, var.Modifier, '', Name, (len(DeclList) > 1 and [DeclList[1]]or [''])[0], DataClass.MODEL_IDENTIFIER_VARIABLE, -1, -1, var.StartPos[0], var.StartPos[1], VarNameStartLine, VarNameStartColumn)\r
             IdList.append(IdVar)\r
 \r
     for enum in FileProfile.EnumerationDefinitionList:\r
         LBPos = enum.Content.find('{')\r
         RBPos = enum.Content.find('}')\r
         Name = enum.Content[4:LBPos].strip()\r
-        Value = enum.Content[LBPos+1:RBPos]\r
-        IdEnum = DataClass.IdentifierClass(-1, '', '', Name, Value, DataClass.MODEL_IDENTIFIER_ENUMERATE, -1, -1, enum.StartPos[0],enum.StartPos[1],enum.EndPos[0],enum.EndPos[1])\r
+        Value = enum.Content[LBPos + 1:RBPos]\r
+        IdEnum = DataClass.IdentifierClass(-1, '', '', Name, Value, DataClass.MODEL_IDENTIFIER_ENUMERATE, -1, -1, enum.StartPos[0], enum.StartPos[1], enum.EndPos[0], enum.EndPos[1])\r
         IdList.append(IdEnum)\r
 \r
     for su in FileProfile.StructUnionDefinitionList:\r
@@ -226,8 +226,8 @@ def GetIdentifierList():
             Value = ''\r
         else:\r
             Name = su.Content[SkipLen:LBPos].strip()\r
-            Value = su.Content[LBPos:RBPos+1]\r
-        IdPE = DataClass.IdentifierClass(-1, '', '', Name, Value, Type, -1, -1, su.StartPos[0],su.StartPos[1],su.EndPos[0],su.EndPos[1])\r
+            Value = su.Content[LBPos:RBPos + 1]\r
+        IdPE = DataClass.IdentifierClass(-1, '', '', Name, Value, Type, -1, -1, su.StartPos[0], su.StartPos[1], su.EndPos[0], su.EndPos[1])\r
         IdList.append(IdPE)\r
 \r
     TdFuncPointerPattern = GetTypedefFuncPointerPattern()\r
@@ -238,7 +238,7 @@ def GetIdentifierList():
         if TdFuncPointerPattern.match(td.ToType):\r
             Modifier = td.FromType\r
             LBPos = td.ToType.find('(')\r
-            TmpStr = td.ToType[LBPos+1:].strip()\r
+            TmpStr = td.ToType[LBPos + 1:].strip()\r
             StarPos = TmpStr.find('*')\r
             if StarPos != -1:\r
                 Modifier += ' ' + TmpStr[0:StarPos]\r
@@ -260,22 +260,22 @@ def GetIdentifierList():
             Value += Name[LBPos : RBPos + 1]\r
             Name = Name[0 : LBPos]\r
 \r
-        IdTd = DataClass.IdentifierClass(-1, Modifier, '', Name, Value, DataClass.MODEL_IDENTIFIER_TYPEDEF, -1, -1, td.StartPos[0],td.StartPos[1],td.EndPos[0],td.EndPos[1])\r
+        IdTd = DataClass.IdentifierClass(-1, Modifier, '', Name, Value, DataClass.MODEL_IDENTIFIER_TYPEDEF, -1, -1, td.StartPos[0], td.StartPos[1], td.EndPos[0], td.EndPos[1])\r
         IdList.append(IdTd)\r
 \r
     for funcCall in FileProfile.FunctionCallingList:\r
-        IdFC = DataClass.IdentifierClass(-1, '', '', funcCall.FuncName, funcCall.ParamList, DataClass.MODEL_IDENTIFIER_FUNCTION_CALLING, -1, -1, funcCall.StartPos[0],funcCall.StartPos[1],funcCall.EndPos[0],funcCall.EndPos[1])\r
+        IdFC = DataClass.IdentifierClass(-1, '', '', funcCall.FuncName, funcCall.ParamList, DataClass.MODEL_IDENTIFIER_FUNCTION_CALLING, -1, -1, funcCall.StartPos[0], funcCall.StartPos[1], funcCall.EndPos[0], funcCall.EndPos[1])\r
         IdList.append(IdFC)\r
     return IdList\r
 \r
 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
-def GetParamList(FuncDeclarator, FuncNameLine = 0, FuncNameOffset = 0):\r
+def GetParamList(FuncDeclarator, FuncNameLine=0, FuncNameOffset=0):\r
     FuncDeclarator = StripComments(FuncDeclarator)\r
     ParamIdList = []\r
     #DeclSplitList = FuncDeclarator.split('(')\r
@@ -477,7 +477,7 @@ def GetFunctionList():
                         FuncNameStartColumn += 1\r
                     PreChar = FirstChar\r
 \r
-        FuncObj = DataClass.FunctionClass(-1, FuncDef.Declarator, FuncDef.Modifier, FuncName.strip(), '', FuncDef.StartPos[0],FuncDef.StartPos[1],FuncDef.EndPos[0],FuncDef.EndPos[1], FuncDef.LeftBracePos[0], FuncDef.LeftBracePos[1], -1, ParamIdList, [], FuncNameStartLine, FuncNameStartColumn)\r
+        FuncObj = DataClass.FunctionClass(-1, FuncDef.Declarator, FuncDef.Modifier, FuncName.strip(), '', FuncDef.StartPos[0], FuncDef.StartPos[1], FuncDef.EndPos[0], FuncDef.EndPos[1], FuncDef.LeftBracePos[0], FuncDef.LeftBracePos[1], -1, ParamIdList, [], FuncNameStartLine, FuncNameStartColumn)\r
         FuncObjList.append(FuncObj)\r
 \r
     return FuncObjList\r
@@ -514,6 +514,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
@@ -547,7 +549,7 @@ def CollectSourceCodeDataIntoDB(RootDir):
 \r
     Db.UpdateIdentifierBelongsToFunction()\r
 \r
-def GetTableID(FullFileName, ErrorMsgList = None):\r
+def GetTableID(FullFileName, ErrorMsgList=None):\r
     if ErrorMsgList == None:\r
         ErrorMsgList = []\r
 \r
@@ -562,11 +564,11 @@ def GetTableID(FullFileName, ErrorMsgList = None):
     for Result in ResultSet:\r
         if FileID != -1:\r
             ErrorMsgList.append('Duplicate file ID found in DB for file %s' % FullFileName)\r
-            return -2\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 - 1\r
     return FileID\r
 \r
 def GetIncludeFileList(FullFileName):\r
@@ -645,7 +647,7 @@ def GetPredicateListFromPredicateExpStr(PES):
     while i < len(PES) - 1:\r
         if (PES[i].isalnum() or PES[i] == '_' or PES[i] == '*') and LogicOpPos > PredicateBegin:\r
             PredicateBegin = i\r
-        if (PES[i] == '&' and PES[i+1] == '&') or (PES[i] == '|' and PES[i+1] == '|'):\r
+        if (PES[i] == '&' and PES[i + 1] == '&') or (PES[i] == '|' and PES[i + 1] == '|'):\r
             LogicOpPos = i\r
             Exp = PES[PredicateBegin:i].strip()\r
             # Exp may contain '.' or '->'\r
@@ -670,7 +672,7 @@ def GetPredicateListFromPredicateExpStr(PES):
             PredicateList.append(Exp.rstrip(';').rstrip(')').strip())\r
     return PredicateList\r
 \r
-def GetCNameList(Lvalue, StarList = []):\r
+def GetCNameList(Lvalue, StarList=[]):\r
     Lvalue += ' '\r
     i = 0\r
     SearchBegin = 0\r
@@ -686,7 +688,7 @@ def GetCNameList(Lvalue, StarList = []):
                 VarEnd = i\r
                 i += 1\r
             elif VarEnd != -1:\r
-                VarList.append(Lvalue[VarStart:VarEnd+1])\r
+                VarList.append(Lvalue[VarStart:VarEnd + 1])\r
                 i += 1\r
                 break\r
             else:\r
@@ -714,7 +716,7 @@ def GetCNameList(Lvalue, StarList = []):
 \r
     return VarList\r
 \r
-def SplitPredicateByOp(Str, Op, IsFuncCalling = False):\r
+def SplitPredicateByOp(Str, Op, IsFuncCalling=False):\r
 \r
     Name = Str.strip()\r
     Value = None\r
@@ -760,7 +762,7 @@ def SplitPredicateByOp(Str, Op, IsFuncCalling = False):
             return [Name]\r
 \r
         Name = Str[0:Index + IndexInRemainingStr].strip()\r
-        Value = Str[Index+IndexInRemainingStr+len(Op):].strip().strip(')')\r
+        Value = Str[Index + IndexInRemainingStr + len(Op):].strip().strip(')')\r
         return [Name, Value]\r
 \r
     TmpStr = Str.rstrip(';').rstrip(')')\r
@@ -769,7 +771,7 @@ def SplitPredicateByOp(Str, Op, IsFuncCalling = False):
         if Index == -1:\r
             return [Name]\r
 \r
-        if Str[Index - 1].isalnum() or Str[Index - 1].isspace() or Str[Index - 1] == ')':\r
+        if Str[Index - 1].isalnum() or Str[Index - 1].isspace() or Str[Index - 1] == ')' or Str[Index - 1] == ']':\r
             Name = Str[0:Index].strip()\r
             Value = Str[Index + len(Op):].strip()\r
             return [Name, Value]\r
@@ -826,15 +828,13 @@ def PatternInModifier(Modifier, SubStr):
 \r
 def GetDataTypeFromModifier(ModifierStr):\r
     MList = ModifierStr.split()\r
+    ReturnType = ''\r
     for M in MList:\r
         if M in EccGlobalData.gConfig.ModifierList:\r
-            MList.remove(M)\r
+            continue\r
         # remove array sufix\r
-        if M.startswith('['):\r
-            MList.remove(M)\r
-\r
-    ReturnType = ''\r
-    for M in MList:\r
+        if M.startswith('[') or M.endswith(']'):\r
+            continue\r
         ReturnType += M + ' '\r
 \r
     ReturnType = ReturnType.strip()\r
@@ -950,7 +950,7 @@ def StripComments(Str):
                 DoubleSlashComment = False\r
             Index += 1\r
         # check for */ comment end\r
-        elif InComment and not DoubleSlashComment and ListFromStr[Index] == '*' and ListFromStr[Index+1] == '/':\r
+        elif InComment and not DoubleSlashComment and ListFromStr[Index] == '*' and ListFromStr[Index + 1] == '/':\r
             ListFromStr[Index] = ' '\r
             Index += 1\r
             ListFromStr[Index] = ' '\r
@@ -961,12 +961,12 @@ 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] == '/' and ListFromStr[Index + 2] != '\n':\r
             InComment = True\r
             DoubleSlashComment = True\r
 \r
         # check for /* comment start\r
-        elif ListFromStr[Index] == '/' and ListFromStr[Index+1] == '*':\r
+        elif ListFromStr[Index] == '/' and ListFromStr[Index + 1] == '*':\r
             ListFromStr[Index] = ' '\r
             Index += 1\r
             ListFromStr[Index] = ' '\r
@@ -1024,7 +1024,7 @@ def GetFinalTypeValue(Type, FieldName, TypedefDict, SUDict):
 \r
     return None\r
 \r
-def GetRealType(Type, TypedefDict, TargetType = None):\r
+def GetRealType(Type, TypedefDict, TargetType=None):\r
     if TargetType != None and Type == TargetType:\r
             return Type\r
     while TypedefDict.get(Type):\r
@@ -1033,7 +1033,7 @@ def GetRealType(Type, TypedefDict, TargetType = None):
             return Type\r
     return Type\r
 \r
-def GetTypeInfo(RefList, Modifier, FullFileName, TargetType = None):\r
+def GetTypeInfo(RefList, Modifier, FullFileName, TargetType=None):\r
     TypedefDict = GetTypedefDict(FullFileName)\r
     SUDict = GetSUDict(FullFileName)\r
     Type = GetDataTypeFromModifier(Modifier).replace('*', '').strip()\r
@@ -1051,7 +1051,7 @@ def GetTypeInfo(RefList, Modifier, FullFileName, TargetType = None):
         # we only want to check if it is a pointer\r
         else:\r
             Type = FromType\r
-            if Type.find('*') != -1 and Index == len(RefList)-1:\r
+            if Type.find('*') != -1 and Index == len(RefList) - 1:\r
                 return Type\r
             Type = FromType.split()[0]\r
 \r
@@ -1061,7 +1061,7 @@ def GetTypeInfo(RefList, Modifier, FullFileName, TargetType = None):
 \r
     return Type\r
 \r
-def GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall = False, TargetType = None, StarList = None):\r
+def GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall=False, TargetType=None, StarList=None):\r
 \r
     PredVar = PredVarList[0]\r
     FileID = GetTableID(FullFileName)\r
@@ -1172,6 +1172,8 @@ def GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall = False, Target
             else:\r
                 TypeList = GetDataTypeFromModifier(Param.Modifier).split()\r
                 Type = TypeList[-1]\r
+                if Type == '*' and len(TypeList) >= 2:\r
+                    Type = TypeList[-2]\r
                 if len(TypeList) > 1 and StarList != None:\r
                     for Star in StarList:\r
                         Type = Type.strip()\r
@@ -1269,7 +1271,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
@@ -1287,13 +1292,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
@@ -1311,9 +1316,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
@@ -1325,9 +1331,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
@@ -1536,7 +1543,7 @@ def CheckFuncLayoutLocalVariable(FullFileName):
         FL.append(Result)\r
 \r
     for F in FL:\r
-        SqlStatement = """ select Name, Value, ID\r
+        SqlStatement = """ select Name, Value, ID, Modifier\r
                        from %s\r
                        where Model = %d and BelongsToFunction = %d\r
                    """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE, F[0])\r
@@ -1545,7 +1552,7 @@ def CheckFuncLayoutLocalVariable(FullFileName):
             continue\r
 \r
         for Result in ResultSet:\r
-            if len(Result[1]) > 0:\r
+            if len(Result[1]) > 0 and 'CONST' not in Result[3]:\r
                 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_NO_INIT_OF_VARIABLE, 'Variable Name: %s' % Result[0], FileTable, Result[2])\r
 \r
 def CheckMemberVariableFormat(Name, Value, FileTable, TdId, ModelId):\r
@@ -1561,7 +1568,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
@@ -1626,12 +1633,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
@@ -1687,9 +1699,9 @@ def CheckDeclTypedefFormat(FullFileName, ModelId):
         # Check member variable format.\r
         ErrMsgList = CheckMemberVariableFormat(Name, Value, FileTable, Td[5], ModelId)\r
         for ErrMsg in ErrMsgList:\r
-            if EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Name+'.'+ErrMsg):\r
+            if EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Name + '.' + ErrMsg):\r
                 continue\r
-            PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Member variable [%s] NOT follow naming convention.' % (Name+'.'+ErrMsg), FileTable, Td[5])\r
+            PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Member variable [%s] NOT follow naming convention.' % (Name + '.' + ErrMsg), FileTable, Td[5])\r
 \r
     # First check in current file to see whether struct/union/enum is typedef-ed.\r
     UntypedefedList = []\r
@@ -1710,9 +1722,9 @@ def CheckDeclTypedefFormat(FullFileName, ModelId):
             continue\r
         ErrMsgList = CheckMemberVariableFormat(Name, Value, FileTable, Result[3], ModelId)\r
         for ErrMsg in ErrMsgList:\r
-            if EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Result[0]+'.'+ErrMsg):\r
+            if EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Result[0] + '.' + ErrMsg):\r
                 continue\r
-            PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Member variable [%s] NOT follow naming convention.' % (Result[0]+'.'+ErrMsg), FileTable, Result[3])\r
+            PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Member variable [%s] NOT follow naming convention.' % (Result[0] + '.' + ErrMsg), FileTable, Result[3])\r
         # Check whether it is typedefed.\r
         Found = False\r
         for Td in TdList:\r
@@ -1846,7 +1858,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
@@ -1949,7 +1967,7 @@ def CheckPointerNullComparison(FullFileName):
                 if SearchInCache:\r
                     Type = FuncReturnTypeDict.get(PredVarStr)\r
                     if Type != None:\r
-                        if Type.find('*') != -1:\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
 \r
@@ -1962,7 +1980,7 @@ def CheckPointerNullComparison(FullFileName):
                 if Type == None:\r
                     continue\r
                 Type = GetTypeFromArray(Type, PredVarStr)\r
-                if Type.find('*') != -1:\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
 \r
 def CheckNonBooleanValueComparison(FullFileName):\r
@@ -2004,8 +2022,6 @@ def CheckNonBooleanValueComparison(FullFileName):
             continue\r
 \r
         for Exp in GetPredicateListFromPredicateExpStr(Str[0]):\r
-#            if p.match(Exp):\r
-#                continue\r
             PredInfo = SplitPredicateStr(Exp)\r
             if PredInfo[1] == None:\r
                 PredVarStr = PredInfo[0][0].strip()\r
@@ -2037,7 +2053,6 @@ def CheckNonBooleanValueComparison(FullFileName):
 \r
                     if PredVarStr in FuncReturnTypeDict:\r
                         continue\r
-\r
                 Type = GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall, 'BOOLEAN', StarList)\r
                 if SearchInCache:\r
                     FuncReturnTypeDict[PredVarStr] = Type\r
@@ -2207,7 +2222,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
@@ -2219,6 +2235,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
@@ -2310,28 +2330,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
@@ -2446,7 +2531,7 @@ def GetDoxygenStrFromComment(Str):
 \r
     return DoxygenStrList\r
 \r
-def CheckGeneralDoxygenCommentLayout(Str, StartLine, ErrorMsgList, CommentId = -1, TableName = ''):\r
+def CheckGeneralDoxygenCommentLayout(Str, StartLine, ErrorMsgList, CommentId= -1, TableName=''):\r
     #/** --*/ @retval after @param\r
     if not Str.startswith('/**'):\r
         ErrorMsgList.append('Line %d : Comment does NOT have prefix /** ' % StartLine)\r
@@ -2460,7 +2545,7 @@ def CheckGeneralDoxygenCommentLayout(Str, StartLine, ErrorMsgList, CommentId = -
         ErrorMsgList.append('Line %d : @retval appear before @param ' % StartLine)\r
         PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, @retval appear before @param  ', TableName, CommentId)\r
 \r
-def CheckFunctionHeaderConsistentWithDoxygenComment(FuncModifier, FuncHeader, FuncStartLine, CommentStr, CommentStartLine, ErrorMsgList, CommentId = -1, TableName = ''):\r
+def CheckFunctionHeaderConsistentWithDoxygenComment(FuncModifier, FuncHeader, FuncStartLine, CommentStr, CommentStartLine, ErrorMsgList, CommentId= -1, TableName=''):\r
 \r
     ParamList = GetParamList(FuncHeader)\r
     CheckGeneralDoxygenCommentLayout(CommentStr, CommentStartLine, ErrorMsgList, CommentId, TableName)\r
@@ -2480,18 +2565,18 @@ def CheckFunctionHeaderConsistentWithDoxygenComment(FuncModifier, FuncHeader, Fu
             ParamName = ParamList[Index].Name.strip()\r
             Tag = DoxygenStrList[Index].strip(' ')\r
             if (not Tag[-1] == ('\n')) and (not Tag[-1] == ('\r')):\r
-                ErrorMsgList.append('Line %d : in Comment, \"%s\" does NOT end with new line ' % (CommentStartLine, Tag.replace('\n', '').replace('\r', '')))\r
-                PrintErrorMsg(ERROR_HEADER_CHECK_FUNCTION, 'in Comment, \"%s\" does NOT end with new line ' % (Tag.replace('\n', '').replace('\r', '')), TableName, CommentId)\r
+                ErrorMsgList.append('Line %d : in Comment, <%s> does NOT end with new line ' % (CommentStartLine, Tag.replace('\n', '').replace('\r', '')))\r
+                PrintErrorMsg(ERROR_HEADER_CHECK_FUNCTION, 'in Comment, <%s> does NOT end with new line ' % (Tag.replace('\n', '').replace('\r', '')), TableName, CommentId)\r
             TagPartList = Tag.split()\r
             if len(TagPartList) < 2:\r
-                ErrorMsgList.append('Line %d : in Comment, \"%s\" does NOT contain doxygen contents ' % (CommentStartLine, Tag.replace('\n', '').replace('\r', '')))\r
-                PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, \"%s\" does NOT contain doxygen contents ' % (Tag.replace('\n', '').replace('\r', '')), TableName, CommentId)\r
+                ErrorMsgList.append('Line %d : in Comment, <%s> does NOT contain doxygen contents ' % (CommentStartLine, Tag.replace('\n', '').replace('\r', '')))\r
+                PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, <%s> does NOT contain doxygen contents ' % (Tag.replace('\n', '').replace('\r', '')), TableName, CommentId)\r
                 Index += 1\r
                 continue\r
             LBPos = Tag.find('[')\r
             RBPos = Tag.find(']')\r
             ParamToLBContent = Tag[len('@param'):LBPos].strip()\r
-            if LBPos > 0 and len(ParamToLBContent)==0 and RBPos > LBPos:\r
+            if LBPos > 0 and len(ParamToLBContent) == 0 and RBPos > LBPos:\r
                 InOutStr = ''\r
                 ModifierPartList = ParamModifier.split()\r
                 for Part in ModifierPartList:\r
@@ -2504,12 +2589,19 @@ def CheckFunctionHeaderConsistentWithDoxygenComment(FuncModifier, FuncHeader, Fu
                             InOutStr = 'out'\r
 \r
                 if InOutStr != '':\r
-                    if Tag.find('['+InOutStr+']') == -1:\r
-                        ErrorMsgList.append('Line %d : in Comment, \"%s\" does NOT have %s ' % (CommentStartLine, (TagPartList[0] + ' ' +TagPartList[1]).replace('\n', '').replace('\r', ''), '['+InOutStr+']'))\r
-                        PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, \"%s\" does NOT have %s ' % ((TagPartList[0] + ' ' +TagPartList[1]).replace('\n', '').replace('\r', ''), '['+InOutStr+']'), TableName, CommentId)\r
+                    if Tag.find('[' + InOutStr + ']') == -1:\r
+                        if InOutStr != 'in, out':\r
+                            ErrorMsgList.append('Line %d : in Comment, <%s> does NOT have %s ' % (CommentStartLine, (TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), '[' + InOutStr + ']'))\r
+                            PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, <%s> does NOT have %s ' % ((TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), '[' + InOutStr + ']'), TableName, CommentId)\r
+                        else:\r
+                            if Tag.find('[in,out]') == -1:\r
+                                ErrorMsgList.append('Line %d : in Comment, <%s> does NOT have %s ' % (CommentStartLine, (TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), '[' + InOutStr + ']'))\r
+                                PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, <%s> does NOT have %s ' % ((TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), '[' + InOutStr + ']'), TableName, CommentId)\r
+\r
+\r
             if Tag.find(ParamName) == -1 and ParamName != 'VOID' and ParamName != 'void':\r
-                ErrorMsgList.append('Line %d : in Comment, \"%s\" does NOT consistent with parameter name %s ' % (CommentStartLine, (TagPartList[0] + ' ' +TagPartList[1]).replace('\n', '').replace('\r', ''), ParamName))\r
-                PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, \"%s\" does NOT consistent with parameter name %s ' % ((TagPartList[0] + ' ' +TagPartList[1]).replace('\n', '').replace('\r', ''), ParamName), TableName, CommentId)\r
+                ErrorMsgList.append('Line %d : in Comment, <%s> does NOT consistent with parameter name %s ' % (CommentStartLine, (TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), ParamName))\r
+                PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, <%s> does NOT consistent with parameter name %s ' % ((TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), ParamName), TableName, CommentId)\r
             Index += 1\r
 \r
         if Index < ParamNumber:\r