## @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
#\r
\r
import sys\r
-import os\r
+import Common.LongFilePathOs as os\r
import re\r
import string\r
import CodeFragmentCollector\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
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
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
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
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
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
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
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
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
\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
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
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
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
# 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
\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
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
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
\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
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
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
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
""" % (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