X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=BaseTools%2FSource%2FPython%2FEcc%2Fc.py;h=99b22725e6bacb788653eae2cabd397613f60458;hb=5b0671c1e514e534c6d5be9604da33bfc2cd0a24;hp=989ba7091dd355a8b7d4043f987db4c534f7b89a;hpb=96e6b8e67b359af8d0c97a5ebf8a00d9be29ce08;p=mirror_edk2.git diff --git a/BaseTools/Source/Python/Ecc/c.py b/BaseTools/Source/Python/Ecc/c.py index 989ba7091d..99b22725e6 100644 --- a/BaseTools/Source/Python/Ecc/c.py +++ b/BaseTools/Source/Python/Ecc/c.py @@ -1,5 +1,18 @@ +## @file +# This file is used to be the c coding style checking of ECC tool +# +# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# + import sys -import os +import Common.LongFilePathOs as os import re import string import CodeFragmentCollector @@ -49,7 +62,7 @@ def PrintErrorMsg(ErrorType, Msg, TableName, ItemId): for Part in MsgPartList: Msg += Part Msg += ' ' - GetDB().TblReport.Insert(ErrorType, OtherMsg = Msg, BelongsToTable = TableName, BelongsToItem = ItemId) + GetDB().TblReport.Insert(ErrorType, OtherMsg=Msg, BelongsToTable=TableName, BelongsToItem=ItemId) def GetIdType(Str): Type = DataClass.MODEL_UNKNOWN @@ -80,18 +93,18 @@ def SuOccurInTypedef (Su, TdList): def GetIdentifierList(): IdList = [] for comment in FileProfile.CommentList: - IdComment = DataClass.IdentifierClass(-1, '', '', '', comment.Content, DataClass.MODEL_IDENTIFIER_COMMENT, -1, -1, comment.StartPos[0],comment.StartPos[1],comment.EndPos[0],comment.EndPos[1]) + IdComment = DataClass.IdentifierClass(-1, '', '', '', comment.Content, DataClass.MODEL_IDENTIFIER_COMMENT, -1, -1, comment.StartPos[0], comment.StartPos[1], comment.EndPos[0], comment.EndPos[1]) IdList.append(IdComment) - + for pp in FileProfile.PPDirectiveList: Type = GetIdType(pp.Content) - IdPP = DataClass.IdentifierClass(-1, '', '', '', pp.Content, Type, -1, -1, pp.StartPos[0],pp.StartPos[1],pp.EndPos[0],pp.EndPos[1]) + IdPP = DataClass.IdentifierClass(-1, '', '', '', pp.Content, Type, -1, -1, pp.StartPos[0], pp.StartPos[1], pp.EndPos[0], pp.EndPos[1]) IdList.append(IdPP) - + for pe in FileProfile.PredicateExpressionList: - 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]) + 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]) IdList.append(IdPE) - + FuncDeclPattern = GetFuncDeclPattern() ArrayPattern = GetArrayPattern() for var in FileProfile.VariableDeclarationList: @@ -125,10 +138,10 @@ def GetIdentifierList(): DeclText = DeclText[1:] VarNameStartColumn += 1 FirstChar = DeclText[0] - + var.Declarator = DeclText if FuncDeclPattern.match(var.Declarator): - DeclSplitList = var.Declarator.split('(') + DeclSplitList = var.Declarator.split('(') FuncName = DeclSplitList[0].strip() FuncNamePartList = FuncName.split() if len(FuncNamePartList) > 1: @@ -168,8 +181,8 @@ def GetIdentifierList(): IdVar = DataClass.IdentifierClass(-1, var.Modifier, '', var.Declarator, FuncName, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION, -1, -1, var.StartPos[0], var.StartPos[1], VarNameStartLine, VarNameStartColumn) IdList.append(IdVar) continue - - if var.Declarator.find('{') == -1: + + if var.Declarator.find('{') == -1: for decl in var.Declarator.split(','): DeclList = decl.split('=') Name = DeclList[0].strip() @@ -177,8 +190,8 @@ def GetIdentifierList(): LSBPos = var.Declarator.find('[') var.Modifier += ' ' + Name[LSBPos:] Name = Name[0:LSBPos] - - 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) + + 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) IdList.append(IdVar) else: DeclList = var.Declarator.split('=') @@ -187,17 +200,17 @@ def GetIdentifierList(): LSBPos = var.Declarator.find('[') var.Modifier += ' ' + Name[LSBPos:] Name = Name[0:LSBPos] - 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) + 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) IdList.append(IdVar) - + for enum in FileProfile.EnumerationDefinitionList: LBPos = enum.Content.find('{') RBPos = enum.Content.find('}') Name = enum.Content[4:LBPos].strip() - Value = enum.Content[LBPos+1:RBPos] - IdEnum = DataClass.IdentifierClass(-1, '', '', Name, Value, DataClass.MODEL_IDENTIFIER_ENUMERATE, -1, -1, enum.StartPos[0],enum.StartPos[1],enum.EndPos[0],enum.EndPos[1]) + Value = enum.Content[LBPos + 1:RBPos] + IdEnum = DataClass.IdentifierClass(-1, '', '', Name, Value, DataClass.MODEL_IDENTIFIER_ENUMERATE, -1, -1, enum.StartPos[0], enum.StartPos[1], enum.EndPos[0], enum.EndPos[1]) IdList.append(IdEnum) - + for su in FileProfile.StructUnionDefinitionList: if SuOccurInTypedef(su, FileProfile.TypedefDefinitionList): continue @@ -213,11 +226,11 @@ def GetIdentifierList(): Value = '' else: Name = su.Content[SkipLen:LBPos].strip() - Value = su.Content[LBPos:RBPos+1] - IdPE = DataClass.IdentifierClass(-1, '', '', Name, Value, Type, -1, -1, su.StartPos[0],su.StartPos[1],su.EndPos[0],su.EndPos[1]) + Value = su.Content[LBPos:RBPos + 1] + IdPE = DataClass.IdentifierClass(-1, '', '', Name, Value, Type, -1, -1, su.StartPos[0], su.StartPos[1], su.EndPos[0], su.EndPos[1]) IdList.append(IdPE) - - TdFuncPointerPattern = GetTypedefFuncPointerPattern() + + TdFuncPointerPattern = GetTypedefFuncPointerPattern() for td in FileProfile.TypedefDefinitionList: Modifier = '' Name = td.ToType @@ -225,7 +238,7 @@ def GetIdentifierList(): if TdFuncPointerPattern.match(td.ToType): Modifier = td.FromType LBPos = td.ToType.find('(') - TmpStr = td.ToType[LBPos+1:].strip() + TmpStr = td.ToType[LBPos + 1:].strip() StarPos = TmpStr.find('*') if StarPos != -1: Modifier += ' ' + TmpStr[0:StarPos] @@ -240,29 +253,29 @@ def GetIdentifierList(): while Name.startswith('*'): Value += ' ' + '*' Name = Name.lstrip('*').strip() - + if Name.find('[') != -1: LBPos = Name.find('[') RBPos = Name.rfind(']') Value += Name[LBPos : RBPos + 1] Name = Name[0 : LBPos] - - 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]) + + 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]) IdList.append(IdTd) - + for funcCall in FileProfile.FunctionCallingList: - 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]) + 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]) IdList.append(IdFC) return IdList def StripNonAlnumChars(Str): StrippedStr = '' for Char in Str: - if Char.isalnum(): + if Char.isalnum() or Char == '_': StrippedStr += Char return StrippedStr -def GetParamList(FuncDeclarator, FuncNameLine = 0, FuncNameOffset = 0): +def GetParamList(FuncDeclarator, FuncNameLine=0, FuncNameOffset=0): FuncDeclarator = StripComments(FuncDeclarator) ParamIdList = [] #DeclSplitList = FuncDeclarator.split('(') @@ -278,7 +291,7 @@ def GetParamList(FuncDeclarator, FuncNameLine = 0, FuncNameOffset = 0): OffsetSkipped = 0 TailChar = FuncName[-1] while not TailChar.isalpha() and TailChar != '_': - + if TailChar == '\n': FuncName = FuncName.rstrip('\r\n').rstrip('\n') LineSkipped += 1 @@ -296,9 +309,9 @@ def GetParamList(FuncDeclarator, FuncNameLine = 0, FuncNameOffset = 0): else: FuncName = FuncName[:-1] TailChar = FuncName[-1] - + OffsetSkipped += 1 #skip '(' - + for p in ParamStr.split(','): ListP = p.split() if len(ListP) == 0: @@ -325,13 +338,13 @@ def GetParamList(FuncDeclarator, FuncNameLine = 0, FuncNameOffset = 0): LBIndex = ParamName.find('[') if LBIndex != -1: ParamName = ParamName[0:LBIndex] - + Start = RightSpacePos Index = 0 PreChar = '' while Index < Start: FirstChar = p[Index] - + if FirstChar == '\r': Index += 1 LineSkipped += 1 @@ -351,15 +364,15 @@ def GetParamList(FuncDeclarator, FuncNameLine = 0, FuncNameOffset = 0): Index += 1 OffsetSkipped += 1 PreChar = FirstChar - + ParamBeginLine = FuncNameLine + LineSkipped ParamBeginOffset = FuncNameOffset + OffsetSkipped - + Index = Start + len(ParamName) PreChar = '' while Index < len(p): FirstChar = p[Index] - + if FirstChar == '\r': Index += 1 LineSkipped += 1 @@ -379,18 +392,18 @@ def GetParamList(FuncDeclarator, FuncNameLine = 0, FuncNameOffset = 0): Index += 1 OffsetSkipped += 1 PreChar = FirstChar - + ParamEndLine = FuncNameLine + LineSkipped ParamEndOffset = FuncNameOffset + OffsetSkipped if ParamName != '...': ParamName = StripNonAlnumChars(ParamName) IdParam = DataClass.IdentifierClass(-1, ParamModifier, '', ParamName, '', DataClass.MODEL_IDENTIFIER_PARAMETER, -1, -1, ParamBeginLine, ParamBeginOffset, ParamEndLine, ParamEndOffset) ParamIdList.append(IdParam) - + OffsetSkipped += 1 #skip ',' - + return ParamIdList - + def GetFunctionList(): FuncObjList = [] for FuncDef in FileProfile.FunctionDefinitionList: @@ -422,12 +435,12 @@ def GetFunctionList(): DeclText = DeclText[1:] FuncNameStartColumn += 1 FirstChar = DeclText[0] - + FuncDef.Declarator = DeclText DeclSplitList = FuncDef.Declarator.split('(') if len(DeclSplitList) < 2: continue - + FuncName = DeclSplitList[0] FuncNamePartList = FuncName.split() if len(FuncNamePartList) > 1: @@ -463,10 +476,10 @@ def GetFunctionList(): Index += 1 FuncNameStartColumn += 1 PreChar = FirstChar - - 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) + + 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) FuncObjList.append(FuncObj) - + return FuncObjList def GetFileModificationTimeFromDB(FullFileName): @@ -501,7 +514,11 @@ def CollectSourceCodeDataIntoDB(RootDir): dirnames.append(Dirname) for f in filenames: + if f.lower() in EccGlobalData.gConfig.SkipFileList: + continue + collector = None FullName = os.path.normpath(os.path.join(dirpath, f)) + model = DataClass.MODEL_FILE_OTHERS if os.path.splitext(f)[1] in ('.h', '.c'): EdkLogger.info("Parsing " + FullName) model = f.endswith('c') and DataClass.MODEL_FILE_C or DataClass.MODEL_FILE_H @@ -513,55 +530,58 @@ def CollectSourceCodeDataIntoDB(RootDir): collector.CleanFileProfileBuffer() collector.ParseFileWithClearedPPDirective() # collector.PrintFragments() - BaseName = os.path.basename(f) - DirName = os.path.dirname(FullName) - Ext = os.path.splitext(f)[1].lstrip('.') - ModifiedTime = os.path.getmtime(FullName) - FileObj = DataClass.FileClass(-1, BaseName, Ext, DirName, FullName, model, ModifiedTime, GetFunctionList(), GetIdentifierList(), []) - FileObjList.append(FileObj) - collector.CleanFileProfileBuffer() - + BaseName = os.path.basename(f) + DirName = os.path.dirname(FullName) + Ext = os.path.splitext(f)[1].lstrip('.') + ModifiedTime = os.path.getmtime(FullName) + FileObj = DataClass.FileClass(-1, BaseName, Ext, DirName, FullName, model, ModifiedTime, GetFunctionList(), GetIdentifierList(), []) + FileObjList.append(FileObj) + if collector: + collector.CleanFileProfileBuffer() + if len(ParseErrorFileList) > 0: EdkLogger.info("Found unrecoverable error during parsing:\n\t%s\n" % "\n\t".join(ParseErrorFileList)) - - Db = GetDB() - for file in FileObjList: - Db.InsertOneFile(file) + + Db = GetDB() + for file in FileObjList: + if file.ExtName.upper() not in ['INF', 'DEC', 'DSC', 'FDF']: + Db.InsertOneFile(file) Db.UpdateIdentifierBelongsToFunction() -def GetTableID(FullFileName, ErrorMsgList = None): - if ErrorMsgList == None: +def GetTableID(FullFileName, ErrorMsgList=None): + if ErrorMsgList is None: ErrorMsgList = [] - + Db = GetDB() SqlStatement = """ select ID from File where FullPath like '%s' """ % FullFileName - ResultSet = Db.TblFile.Exec(SqlStatement) FileID = -1 for Result in ResultSet: if FileID != -1: ErrorMsgList.append('Duplicate file ID found in DB for file %s' % FullFileName) - return -2 + return - 2 FileID = Result[0] if FileID == -1: ErrorMsgList.append('NO file ID found in DB for file %s' % FullFileName) - return -1 + return - 1 return FileID def GetIncludeFileList(FullFileName): + if os.path.splitext(FullFileName)[1].upper() not in ('.H'): + return [] IFList = IncludeFileListDict.get(FullFileName) - if IFList != None: + if IFList is not None: return IFList - + FileID = GetTableID(FullFileName) if FileID < 0: return [] - + Db = GetDB() FileTable = 'Identifier' + str(FileID) SqlStatement = """ select Value @@ -581,12 +601,12 @@ def GetFullPathOfIncludeFile(Str, IncludePathList): return None def GetAllIncludeFiles(FullFileName): - if AllIncludeFileListDict.get(FullFileName) != None: + if AllIncludeFileListDict.get(FullFileName) is not None: return AllIncludeFileListDict.get(FullFileName) - + FileDirName = os.path.dirname(FullFileName) IncludePathList = IncludePathListDict.get(FileDirName) - if IncludePathList == None: + if IncludePathList is None: IncludePathList = MetaDataParser.GetIncludeListOfFile(EccGlobalData.gWorkspace, FullFileName, GetDB()) if FileDirName not in IncludePathList: IncludePathList.insert(0, FileDirName) @@ -598,9 +618,9 @@ def GetAllIncludeFiles(FullFileName): FileName = FileName.strip('\"') FileName = FileName.lstrip('<').rstrip('>').strip() FullPath = GetFullPathOfIncludeFile(FileName, IncludePathList) - if FullPath != None: + if FullPath is not None: IncludeFileQueue.append(FullPath) - + i = 0 while i < len(IncludeFileQueue): for IncludeFile in GetIncludeFileList(IncludeFileQueue[i]): @@ -609,10 +629,10 @@ def GetAllIncludeFiles(FullFileName): FileName = FileName.strip('\"') FileName = FileName.lstrip('<').rstrip('>').strip() FullPath = GetFullPathOfIncludeFile(FileName, IncludePathList) - if FullPath != None and FullPath not in IncludeFileQueue: + if FullPath is not None and FullPath not in IncludeFileQueue: IncludeFileQueue.insert(i + 1, FullPath) i += 1 - + AllIncludeFileListDict[FullFileName] = IncludeFileQueue return IncludeFileQueue @@ -627,7 +647,7 @@ def GetPredicateListFromPredicateExpStr(PES): while i < len(PES) - 1: if (PES[i].isalnum() or PES[i] == '_' or PES[i] == '*') and LogicOpPos > PredicateBegin: PredicateBegin = i - if (PES[i] == '&' and PES[i+1] == '&') or (PES[i] == '|' and PES[i+1] == '|'): + if (PES[i] == '&' and PES[i + 1] == '&') or (PES[i] == '|' and PES[i + 1] == '|'): LogicOpPos = i Exp = PES[PredicateBegin:i].strip() # Exp may contain '.' or '->' @@ -637,7 +657,7 @@ def GetPredicateListFromPredicateExpStr(PES): else: PredicateList.append(Exp.rstrip(';').rstrip(')').strip()) i += 1 - + if PredicateBegin > LogicOpPos: while PredicateBegin < len(PES): if PES[PredicateBegin].isalnum() or PES[PredicateBegin] == '_' or PES[PredicateBegin] == '*': @@ -651,15 +671,15 @@ def GetPredicateListFromPredicateExpStr(PES): else: PredicateList.append(Exp.rstrip(';').rstrip(')').strip()) return PredicateList - -def GetCNameList(Lvalue, StarList = []): + +def GetCNameList(Lvalue, StarList=[]): Lvalue += ' ' i = 0 SearchBegin = 0 VarStart = -1 VarEnd = -1 VarList = [] - + while SearchBegin < len(Lvalue): while i < len(Lvalue): if Lvalue[i].isalnum() or Lvalue[i] == '_': @@ -668,7 +688,7 @@ def GetCNameList(Lvalue, StarList = []): VarEnd = i i += 1 elif VarEnd != -1: - VarList.append(Lvalue[VarStart:VarEnd+1]) + VarList.append(Lvalue[VarStart:VarEnd + 1]) i += 1 break else: @@ -677,8 +697,8 @@ def GetCNameList(Lvalue, StarList = []): i += 1 if VarEnd == -1: break - - + + DotIndex = Lvalue[VarEnd:].find('.') ArrowIndex = Lvalue[VarEnd:].find('->') if DotIndex == -1 and ArrowIndex == -1: @@ -688,19 +708,19 @@ def GetCNameList(Lvalue, StarList = []): elif ArrowIndex == -1 and DotIndex != -1: SearchBegin = VarEnd + DotIndex else: - SearchBegin = VarEnd + ((DotIndex < ArrowIndex) and DotIndex or ArrowIndex) - + SearchBegin = VarEnd + ((DotIndex < ArrowIndex) and DotIndex or ArrowIndex) + i = SearchBegin VarStart = -1 VarEnd = -1 - - return VarList -def SplitPredicateByOp(Str, Op, IsFuncCalling = False): + return VarList + +def SplitPredicateByOp(Str, Op, IsFuncCalling=False): Name = Str.strip() Value = None - + if IsFuncCalling: Index = 0 LBFound = False @@ -708,7 +728,7 @@ def SplitPredicateByOp(Str, Op, IsFuncCalling = False): while Index < len(Str): while not LBFound and Str[Index] != '_' and not Str[Index].isalnum(): Index += 1 - + while not LBFound and (Str[Index].isalnum() or Str[Index] == '_'): Index += 1 # maybe type-cast at the begining, skip it. @@ -716,81 +736,81 @@ def SplitPredicateByOp(Str, Op, IsFuncCalling = False): if RemainingStr.startswith(')') and not LBFound: Index += 1 continue - + if RemainingStr.startswith('(') and not LBFound: LBFound = True - + if Str[Index] == '(': UnmatchedLBCount += 1 Index += 1 continue - + if Str[Index] == ')': UnmatchedLBCount -= 1 Index += 1 if UnmatchedLBCount == 0: break continue - + Index += 1 - + if UnmatchedLBCount > 0: return [Name] - + IndexInRemainingStr = Str[Index:].find(Op) if IndexInRemainingStr == -1: return [Name] - + Name = Str[0:Index + IndexInRemainingStr].strip() - Value = Str[Index+IndexInRemainingStr+len(Op):].strip().strip(')') + Value = Str[Index + IndexInRemainingStr + len(Op):].strip().strip(')') return [Name, Value] - + TmpStr = Str.rstrip(';').rstrip(')') while True: Index = TmpStr.rfind(Op) if Index == -1: return [Name] - - if Str[Index - 1].isalnum() or Str[Index - 1].isspace() or Str[Index - 1] == ')': + + if Str[Index - 1].isalnum() or Str[Index - 1].isspace() or Str[Index - 1] == ')' or Str[Index - 1] == ']': Name = Str[0:Index].strip() Value = Str[Index + len(Op):].strip() - return [Name, Value] - + return [Name, Value] + TmpStr = Str[0:Index - 1] def SplitPredicateStr(Str): - + Str = Str.lstrip('(') IsFuncCalling = False p = GetFuncDeclPattern() TmpStr = Str.replace('.', '').replace('->', '') if p.match(TmpStr): IsFuncCalling = True - + PredPartList = SplitPredicateByOp(Str, '==', IsFuncCalling) if len(PredPartList) > 1: return [PredPartList, '=='] - + PredPartList = SplitPredicateByOp(Str, '!=', IsFuncCalling) if len(PredPartList) > 1: return [PredPartList, '!='] - + PredPartList = SplitPredicateByOp(Str, '>=', IsFuncCalling) if len(PredPartList) > 1: return [PredPartList, '>='] - + PredPartList = SplitPredicateByOp(Str, '<=', IsFuncCalling) if len(PredPartList) > 1: return [PredPartList, '<='] - + PredPartList = SplitPredicateByOp(Str, '>', IsFuncCalling) if len(PredPartList) > 1: return [PredPartList, '>'] - + PredPartList = SplitPredicateByOp(Str, '<', IsFuncCalling) if len(PredPartList) > 1: return [PredPartList, '<'] - + return [[Str, None], None] def GetFuncContainsPE(ExpLine, ResultSet): @@ -808,17 +828,15 @@ def PatternInModifier(Modifier, SubStr): def GetDataTypeFromModifier(ModifierStr): MList = ModifierStr.split() - for M in MList: - if M in EccGlobalData.gConfig.ModifierList: - MList.remove(M) - # remove array sufix - if M.startswith('['): - MList.remove(M) - ReturnType = '' for M in MList: + if M in EccGlobalData.gConfig.ModifierSet: + continue + # remove array sufix + if M.startswith('[') or M.endswith(']'): + continue ReturnType += M + ' ' - + ReturnType = ReturnType.strip() if len(ReturnType) == 0: ReturnType = 'VOID' @@ -831,13 +849,13 @@ def DiffModifier(Str1, Str2): return False else: return True - + def GetTypedefDict(FullFileName): - + Dict = ComplexTypeDict.get(FullFileName) - if Dict != None: + if Dict is not None: return Dict - + FileID = GetTableID(FullFileName) FileTable = 'Identifier' + str(FileID) Db = GetDB() @@ -846,25 +864,25 @@ def GetTypedefDict(FullFileName): where Model = %d """ % (FileTable, DataClass.MODEL_IDENTIFIER_TYPEDEF) ResultSet = Db.TblFile.Exec(SqlStatement) - + Dict = {} for Result in ResultSet: if len(Result[0]) == 0: Dict[Result[1]] = Result[2] - + IncludeFileList = GetAllIncludeFiles(FullFileName) for F in IncludeFileList: FileID = GetTableID(F) if FileID < 0: continue - + FileTable = 'Identifier' + str(FileID) SqlStatement = """ select Modifier, Name, Value, ID from %s where Model = %d """ % (FileTable, DataClass.MODEL_IDENTIFIER_TYPEDEF) ResultSet = Db.TblFile.Exec(SqlStatement) - + for Result in ResultSet: if not Result[2].startswith('FP ('): Dict[Result[1]] = Result[2] @@ -873,16 +891,16 @@ def GetTypedefDict(FullFileName): Dict[Result[1]] = 'VOID' else: Dict[Result[1]] = GetDataTypeFromModifier(Result[0]) - + ComplexTypeDict[FullFileName] = Dict return Dict def GetSUDict(FullFileName): - + Dict = SUDict.get(FullFileName) - if Dict != None: + if Dict is not None: return Dict - + FileID = GetTableID(FullFileName) FileTable = 'Identifier' + str(FileID) Db = GetDB() @@ -891,36 +909,36 @@ def GetSUDict(FullFileName): where Model = %d or Model = %d """ % (FileTable, DataClass.MODEL_IDENTIFIER_STRUCTURE, DataClass.MODEL_IDENTIFIER_UNION) ResultSet = Db.TblFile.Exec(SqlStatement) - + Dict = {} for Result in ResultSet: if len(Result[1]) > 0: Dict[Result[0]] = Result[1] - + IncludeFileList = GetAllIncludeFiles(FullFileName) for F in IncludeFileList: FileID = GetTableID(F) if FileID < 0: continue - + FileTable = 'Identifier' + str(FileID) SqlStatement = """ select Name, Value, ID from %s where Model = %d or Model = %d """ % (FileTable, DataClass.MODEL_IDENTIFIER_STRUCTURE, DataClass.MODEL_IDENTIFIER_UNION) ResultSet = Db.TblFile.Exec(SqlStatement) - + for Result in ResultSet: if len(Result[1]) > 0: Dict[Result[0]] = Result[1] - + SUDict[FullFileName] = Dict return Dict def StripComments(Str): Str += ' ' ListFromStr = list(Str) - + InComment = False DoubleSlashComment = False Index = 0 @@ -932,7 +950,7 @@ def StripComments(Str): DoubleSlashComment = False Index += 1 # check for */ comment end - elif InComment and not DoubleSlashComment and ListFromStr[Index] == '*' and ListFromStr[Index+1] == '/': + elif InComment and not DoubleSlashComment and ListFromStr[Index] == '*' and ListFromStr[Index + 1] == '/': ListFromStr[Index] = ' ' Index += 1 ListFromStr[Index] = ' ' @@ -943,12 +961,12 @@ def StripComments(Str): ListFromStr[Index] = ' ' Index += 1 # check for // comment - elif ListFromStr[Index] == '/' and ListFromStr[Index+1] == '/' and ListFromStr[Index+2] != '\n': + elif ListFromStr[Index] == '/' and ListFromStr[Index + 1] == '/' and ListFromStr[Index + 2] != '\n': InComment = True DoubleSlashComment = True - + # check for /* comment start - elif ListFromStr[Index] == '/' and ListFromStr[Index+1] == '*': + elif ListFromStr[Index] == '/' and ListFromStr[Index + 1] == '*': ListFromStr[Index] = ' ' Index += 1 ListFromStr[Index] = ' ' @@ -960,31 +978,31 @@ def StripComments(Str): # restore from List to String Str = "".join(ListFromStr) Str = Str.rstrip(' ') - + return Str def GetFinalTypeValue(Type, FieldName, TypedefDict, SUDict): Value = TypedefDict.get(Type) - if Value == None: + if Value is None: Value = SUDict.get(Type) - if Value == None: + if Value is None: return None - + LBPos = Value.find('{') while LBPos == -1: FTList = Value.split() for FT in FTList: if FT not in ('struct', 'union'): Value = TypedefDict.get(FT) - if Value == None: + if Value is None: Value = SUDict.get(FT) break - - if Value == None: + + if Value is None: return None - + LBPos = Value.find('{') - + # RBPos = Value.find('}') Fields = Value[LBPos + 1:] Fields = StripComments(Fields) @@ -999,59 +1017,59 @@ def GetFinalTypeValue(Type, FieldName, TypedefDict, SUDict): Type = GetDataTypeFromModifier(Field[0:Index]) return Type.strip() else: - # For the condition that the field in struct is an array with [] sufixes... + # For the condition that the field in struct is an array with [] sufixes... if not Field[Index + len(FieldName)].isalnum(): Type = GetDataTypeFromModifier(Field[0:Index]) return Type.strip() - + return None - -def GetRealType(Type, TypedefDict, TargetType = None): - if TargetType != None and Type == TargetType: + +def GetRealType(Type, TypedefDict, TargetType=None): + if TargetType is not None and Type == TargetType: return Type while TypedefDict.get(Type): Type = TypedefDict.get(Type) - if TargetType != None and Type == TargetType: + if TargetType is not None and Type == TargetType: return Type return Type -def GetTypeInfo(RefList, Modifier, FullFileName, TargetType = None): +def GetTypeInfo(RefList, Modifier, FullFileName, TargetType=None): TypedefDict = GetTypedefDict(FullFileName) SUDict = GetSUDict(FullFileName) Type = GetDataTypeFromModifier(Modifier).replace('*', '').strip() - + Type = Type.split()[-1] Index = 0 while Index < len(RefList): FieldName = RefList[Index] FromType = GetFinalTypeValue(Type, FieldName, TypedefDict, SUDict) - if FromType == None: + if FromType is None: return None # we want to determine the exact type. - if TargetType != None: + if TargetType is not None: Type = FromType.split()[0] # we only want to check if it is a pointer else: Type = FromType - if Type.find('*') != -1 and Index == len(RefList)-1: + if Type.find('*') != -1 and Index == len(RefList) - 1: return Type Type = FromType.split()[0] - + Index += 1 Type = GetRealType(Type, TypedefDict, TargetType) return Type -def GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall = False, TargetType = None, StarList = None): - +def GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall=False, TargetType=None, StarList=None): + PredVar = PredVarList[0] FileID = GetTableID(FullFileName) - + Db = GetDB() FileTable = 'Identifier' + str(FileID) # search variable in include files - + # it is a function call, search function declarations and definitions if IsFuncCall: SqlStatement = """ select Modifier, ID @@ -1059,65 +1077,65 @@ def GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall = False, Target where Model = %d and Value = \'%s\' """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION, PredVar) ResultSet = Db.TblFile.Exec(SqlStatement) - - for Result in ResultSet: + + for Result in ResultSet: Type = GetDataTypeFromModifier(Result[0]).split()[-1] TypedefDict = GetTypedefDict(FullFileName) Type = GetRealType(Type, TypedefDict, TargetType) return Type - + IncludeFileList = GetAllIncludeFiles(FullFileName) for F in IncludeFileList: FileID = GetTableID(F) if FileID < 0: continue - + FileTable = 'Identifier' + str(FileID) SqlStatement = """ select Modifier, ID from %s where Model = %d and Value = \'%s\' """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION, PredVar) ResultSet = Db.TblFile.Exec(SqlStatement) - + for Result in ResultSet: Type = GetDataTypeFromModifier(Result[0]).split()[-1] TypedefDict = GetTypedefDict(FullFileName) Type = GetRealType(Type, TypedefDict, TargetType) return Type - + FileID = GetTableID(FullFileName) SqlStatement = """ select Modifier, ID from Function where BelongsToFile = %d and Name = \'%s\' """ % (FileID, PredVar) ResultSet = Db.TblFile.Exec(SqlStatement) - - for Result in ResultSet: + + for Result in ResultSet: Type = GetDataTypeFromModifier(Result[0]).split()[-1] TypedefDict = GetTypedefDict(FullFileName) Type = GetRealType(Type, TypedefDict, TargetType) return Type - + for F in IncludeFileList: FileID = GetTableID(F) if FileID < 0: continue - + FileTable = 'Identifier' + str(FileID) SqlStatement = """ select Modifier, ID from Function where BelongsToFile = %d and Name = \'%s\' """ % (FileID, PredVar) ResultSet = Db.TblFile.Exec(SqlStatement) - + for Result in ResultSet: Type = GetDataTypeFromModifier(Result[0]).split()[-1] TypedefDict = GetTypedefDict(FullFileName) Type = GetRealType(Type, TypedefDict, TargetType) return Type - + return None - + # really variable, search local variable first SqlStatement = """ select Modifier, ID from %s @@ -1133,7 +1151,7 @@ def GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall = False, Target # Type = GetDataTypeFromModifier(Result[0]).split()[-1] TypeList = GetDataTypeFromModifier(Result[0]).split() Type = TypeList[-1] - if len(TypeList) > 1 and StarList != None: + if len(TypeList) > 1 and StarList is not None: for Star in StarList: Type = Type.strip() Type = Type.rstrip(Star) @@ -1143,7 +1161,7 @@ def GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall = False, Target TypedefDict = GetTypedefDict(FullFileName) Type = GetRealType(Type, TypedefDict, TargetType) return Type - + # search function parameters second ParamList = GetParamList(FuncRecord[2]) for Param in ParamList: @@ -1154,7 +1172,9 @@ def GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall = False, Target else: TypeList = GetDataTypeFromModifier(Param.Modifier).split() Type = TypeList[-1] - if len(TypeList) > 1 and StarList != None: + if Type == '*' and len(TypeList) >= 2: + Type = TypeList[-2] + if len(TypeList) > 1 and StarList is not None: for Star in StarList: Type = Type.strip() Type = Type.rstrip(Star) @@ -1164,7 +1184,7 @@ def GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall = False, Target TypedefDict = GetTypedefDict(FullFileName) Type = GetRealType(Type, TypedefDict, TargetType) return Type - + # search global variable next SqlStatement = """ select Modifier, ID from %s @@ -1179,7 +1199,7 @@ def GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall = False, Target else: TypeList = GetDataTypeFromModifier(Result[0]).split() Type = TypeList[-1] - if len(TypeList) > 1 and StarList != None: + if len(TypeList) > 1 and StarList is not None: for Star in StarList: Type = Type.strip() Type = Type.rstrip(Star) @@ -1189,13 +1209,13 @@ def GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall = False, Target TypedefDict = GetTypedefDict(FullFileName) Type = GetRealType(Type, TypedefDict, TargetType) return Type - + IncludeFileList = GetAllIncludeFiles(FullFileName) for F in IncludeFileList: FileID = GetTableID(F) if FileID < 0: continue - + FileTable = 'Identifier' + str(FileID) SqlStatement = """ select Modifier, ID from %s @@ -1210,7 +1230,7 @@ def GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall = False, Target else: TypeList = GetDataTypeFromModifier(Result[0]).split() Type = TypeList[-1] - if len(TypeList) > 1 and StarList != None: + if len(TypeList) > 1 and StarList is not None: for Star in StarList: Type = Type.strip() Type = Type.rstrip(Star) @@ -1223,7 +1243,7 @@ def GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall = False, Target def GetTypeFromArray(Type, Var): Count = Var.count('[') - + while Count > 0: Type = Type.strip() Type = Type.rstrip('*') @@ -1233,14 +1253,14 @@ def GetTypeFromArray(Type, Var): def CheckFuncLayoutReturnType(FullFileName): ErrorMsgList = [] - + FileID = GetTableID(FullFileName, ErrorMsgList) if FileID < 0: return ErrorMsgList - + Db = GetDB() FileTable = 'Identifier' + str(FileID) - SqlStatement = """ select Modifier, ID, StartLine, StartColumn, EndLine, Value + SqlStatement = """ select Modifier, ID, StartLine, StartColumn, EndLine, Value from %s where Model = %d """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION) @@ -1251,13 +1271,16 @@ def CheckFuncLayoutReturnType(FullFileName): FuncName = Result[5] if EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, FuncName): continue - Index = Result[0].find(TypeStart) + Result0 = Result[0] + if Result0.upper().startswith('STATIC'): + Result0 = Result0[6:].strip() + Index = Result0.find(TypeStart) if Index != 0 or Result[3] != 0: PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '[%s] Return Type should appear at the start of line' % FuncName, FileTable, Result[1]) - + if Result[2] == Result[4]: PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '[%s] Return Type should appear on its own line' % FuncName, FileTable, Result[1]) - + SqlStatement = """ select Modifier, ID, StartLine, StartColumn, FunNameStartLine, Name from Function where BelongsToFile = %d @@ -1269,20 +1292,20 @@ def CheckFuncLayoutReturnType(FullFileName): FuncName = Result[5] if EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, FuncName): continue - Index = Result[0].find(ReturnType) + Result0 = Result[0] + if Result0.upper().startswith('STATIC'): + Result0 = Result0[6:].strip() + Index = Result0.find(ReturnType) if Index != 0 or Result[3] != 0: PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '[%s] Return Type should appear at the start of line' % FuncName, 'Function', Result[1]) - - if Result[2] == Result[4]: - PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '[%s] Return Type should appear on its own line' % FuncName, 'Function', Result[1]) - + def CheckFuncLayoutModifier(FullFileName): ErrorMsgList = [] - + FileID = GetTableID(FullFileName, ErrorMsgList) if FileID < 0: return ErrorMsgList - + Db = GetDB() FileTable = 'Identifier' + str(FileID) SqlStatement = """ select Modifier, ID @@ -1293,12 +1316,13 @@ def CheckFuncLayoutModifier(FullFileName): for Result in ResultSet: ReturnType = GetDataTypeFromModifier(Result[0]) TypeStart = ReturnType.split()[0] -# if len(ReturnType) == 0: -# continue - Index = Result[0].find(TypeStart) + Result0 = Result[0] + if Result0.upper().startswith('STATIC'): + Result0 = Result0[6:].strip() + Index = Result0.find(TypeStart) if Index != 0: PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_OPTIONAL_FUNCTIONAL_MODIFIER, '', FileTable, Result[1]) - + SqlStatement = """ select Modifier, ID from Function where BelongsToFile = %d @@ -1307,9 +1331,10 @@ def CheckFuncLayoutModifier(FullFileName): for Result in ResultSet: ReturnType = GetDataTypeFromModifier(Result[0]) TypeStart = ReturnType.split()[0] -# if len(ReturnType) == 0: -# continue - Index = Result[0].find(TypeStart) + Result0 = Result[0] + if Result0.upper().startswith('STATIC'): + Result0 = Result0[6:].strip() + Index = Result0.find(TypeStart) if Index != 0: PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_OPTIONAL_FUNCTIONAL_MODIFIER, '', 'Function', Result[1]) @@ -1321,7 +1346,7 @@ def CheckFuncLayoutName(FullFileName): FileID = GetTableID(FullFileName, ErrorMsgList) if FileID < 0: return ErrorMsgList - + Db = GetDB() FileTable = 'Identifier' + str(FileID) SqlStatement = """ select Name, ID, EndColumn, Value @@ -1343,14 +1368,14 @@ def CheckFuncLayoutName(FullFileName): if Param.StartLine <= StartLine: PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Parameter %s should be in its own line.' % Param.Name, FileTable, Result[1]) if Param.StartLine - StartLine > 1: - PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Empty line appears before Parameter %s.' % Param.Name, FileTable, Result[1]) + PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Empty line appears before Parameter %s.' % Param.Name, FileTable, Result[1]) if not Pattern.match(Param.Name) and not Param.Name in ParamIgnoreList and not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Param.Name): PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Parameter [%s] NOT follow naming convention.' % Param.Name, FileTable, Result[1]) StartLine = Param.StartLine - + if not Result[0].endswith('\n )') and not Result[0].endswith('\r )'): PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, '\')\' should be on a new line and indented two spaces', FileTable, Result[1]) - + SqlStatement = """ select Modifier, ID, FunNameStartColumn, Name from Function where BelongsToFile = %d @@ -1379,11 +1404,11 @@ def CheckFuncLayoutName(FullFileName): def CheckFuncLayoutPrototype(FullFileName): ErrorMsgList = [] - + FileID = GetTableID(FullFileName, ErrorMsgList) if FileID < 0: return ErrorMsgList - + FileTable = 'Identifier' + str(FileID) Db = GetDB() SqlStatement = """ select Modifier, Header, Name, ID @@ -1393,11 +1418,11 @@ def CheckFuncLayoutPrototype(FullFileName): ResultSet = Db.TblFile.Exec(SqlStatement) if len(ResultSet) == 0: return ErrorMsgList - + FuncDefList = [] for Result in ResultSet: FuncDefList.append(Result) - + SqlStatement = """ select Modifier, Name, ID from %s where Model = %d @@ -1406,7 +1431,7 @@ def CheckFuncLayoutPrototype(FullFileName): FuncDeclList = [] for Result in ResultSet: FuncDeclList.append(Result) - + UndeclFuncList = [] for FuncDef in FuncDefList: FuncName = FuncDef[2].strip() @@ -1421,26 +1446,26 @@ def CheckFuncLayoutPrototype(FullFileName): PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, 'Function [%s] modifier different with prototype.' % FuncName, 'Function', FuncDef[3]) ParamListOfDef = GetParamList(FuncDefHeader) ParamListOfDecl = GetParamList(FuncDecl[1]) - if len(ParamListOfDef) != len(ParamListOfDecl): - PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, 'Parameter number different.', 'Function', FuncDef[3]) + if len(ParamListOfDef) != len(ParamListOfDecl) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_2, FuncName): + PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_2, 'Parameter number different in function [%s].' % FuncName, 'Function', FuncDef[3]) break Index = 0 while Index < len(ParamListOfDef): - if DiffModifier(ParamListOfDef[Index].Modifier, ParamListOfDecl[Index].Modifier): - PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, 'Parameter %s has different modifier with prototype.' % ParamListOfDef[Index].Name, 'Function', FuncDef[3]) + if DiffModifier(ParamListOfDef[Index].Modifier, ParamListOfDecl[Index].Modifier) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_3, FuncName): + PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_3, 'Parameter %s has different modifier with prototype in function [%s].' % (ParamListOfDef[Index].Name, FuncName), 'Function', FuncDef[3]) Index += 1 break else: UndeclFuncList.append(FuncDef) - + IncludeFileList = GetAllIncludeFiles(FullFileName) FuncDeclList = [] for F in IncludeFileList: FileID = GetTableID(F, ErrorMsgList) if FileID < 0: continue - + FileTable = 'Identifier' + str(FileID) SqlStatement = """ select Modifier, Name, ID from %s @@ -1450,7 +1475,7 @@ def CheckFuncLayoutPrototype(FullFileName): for Result in ResultSet: FuncDeclList.append(Result) - + for FuncDef in UndeclFuncList: FuncName = FuncDef[2].strip() FuncModifier = FuncDef[0] @@ -1464,24 +1489,24 @@ def CheckFuncLayoutPrototype(FullFileName): PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, 'Function [%s] modifier different with prototype.' % FuncName, 'Function', FuncDef[3]) ParamListOfDef = GetParamList(FuncDefHeader) ParamListOfDecl = GetParamList(FuncDecl[1]) - if len(ParamListOfDef) != len(ParamListOfDecl): - PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, 'Parameter number different.', 'Function', FuncDef[3]) + if len(ParamListOfDef) != len(ParamListOfDecl) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_2, FuncName): + PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_2, 'Parameter number different in function [%s].' % FuncName, 'Function', FuncDef[3]) break Index = 0 while Index < len(ParamListOfDef): - if DiffModifier(ParamListOfDef[Index].Modifier, ParamListOfDecl[Index].Modifier): - PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, 'Parameter %s has different modifier with prototype.' % ParamListOfDef[Index].Name, 'Function', FuncDef[3]) + if DiffModifier(ParamListOfDef[Index].Modifier, ParamListOfDecl[Index].Modifier) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_3, FuncName): + PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_3, 'Parameter %s has different modifier with prototype in function [%s].' % (ParamListOfDef[Index].Name, FuncName), 'Function', FuncDef[3]) Index += 1 break - + def CheckFuncLayoutBody(FullFileName): ErrorMsgList = [] - + FileID = GetTableID(FullFileName, ErrorMsgList) if FileID < 0: return ErrorMsgList - + FileTable = 'Identifier' + str(FileID) Db = GetDB() SqlStatement = """ select BodyStartColumn, EndColumn, ID @@ -1499,11 +1524,11 @@ def CheckFuncLayoutBody(FullFileName): def CheckFuncLayoutLocalVariable(FullFileName): ErrorMsgList = [] - + FileID = GetTableID(FullFileName, ErrorMsgList) if FileID < 0: return ErrorMsgList - + Db = GetDB() FileTable = 'Identifier' + str(FileID) SqlStatement = """ select ID @@ -1516,34 +1541,34 @@ def CheckFuncLayoutLocalVariable(FullFileName): FL = [] for Result in ResultSet: FL.append(Result) - + for F in FL: - SqlStatement = """ select Name, Value, ID + SqlStatement = """ select Name, Value, ID, Modifier from %s where Model = %d and BelongsToFunction = %d """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE, F[0]) ResultSet = Db.TblFile.Exec(SqlStatement) if len(ResultSet) == 0: continue - + for Result in ResultSet: - if len(Result[1]) > 0: + if len(Result[1]) > 0 and 'CONST' not in Result[3]: PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_NO_INIT_OF_VARIABLE, 'Variable Name: %s' % Result[0], FileTable, Result[2]) - + def CheckMemberVariableFormat(Name, Value, FileTable, TdId, ModelId): ErrMsgList = [] # Member variable format pattern. Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$') - + LBPos = Value.find('{') RBPos = Value.rfind('}') if LBPos == -1 or RBPos == -1: return ErrMsgList - + Fields = Value[LBPos + 1 : RBPos] Fields = StripComments(Fields).strip() NestPos = Fields.find ('struct') - if NestPos != -1 and (NestPos + len('struct') < len(Fields)): + if NestPos != -1 and (NestPos + len('struct') < len(Fields)) and ModelId != DataClass.MODEL_IDENTIFIER_UNION: if not Fields[NestPos + len('struct') + 1].isalnum(): if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, Name): PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, 'Nested struct in [%s].' % (Name), FileTable, TdId) @@ -1560,7 +1585,7 @@ def CheckMemberVariableFormat(Name, Value, FileTable, TdId, ModelId): if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, Name): PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, 'Nested enum in [%s].' % (Name), FileTable, TdId) return ErrMsgList - + if ModelId == DataClass.MODEL_IDENTIFIER_ENUMERATE: FieldsList = Fields.split(',') # deal with enum is pre-assigned a value by function call ( , , , ...) @@ -1569,34 +1594,34 @@ def CheckMemberVariableFormat(Name, Value, FileTable, TdId, ModelId): RemoveCurrentElement = False while Index < len(FieldsList): Field = FieldsList[Index] - + if Field.find('(') != -1: QuoteCount += 1 RemoveCurrentElement = True Index += 1 continue - + if Field.find(')') != -1 and QuoteCount > 0: QuoteCount -= 1 - if RemoveCurrentElement: + if RemoveCurrentElement: FieldsList.remove(Field) if QuoteCount == 0: RemoveCurrentElement = False continue - + if QuoteCount == 0: RemoveCurrentElement = False - + Index += 1 else: FieldsList = Fields.split(';') - + for Field in FieldsList: Field = Field.strip() if Field == '': continue - # For the condition that the field in struct is an array with [] sufixes... + # For the condition that the field in struct is an array with [] sufixes... if Field[-1] == ']': LBPos = Field.find('[') Field = Field[0:LBPos] @@ -1604,26 +1629,31 @@ def CheckMemberVariableFormat(Name, Value, FileTable, TdId, ModelId): if Field.find(':') != -1: ColonPos = Field.find(':') Field = Field[0:ColonPos] - + Field = Field.strip() if Field == '': continue + if Field.startswith("#"): + continue # Enum could directly assign value to variable Field = Field.split('=')[0].strip() - TokenList = Field.split() + TokenList = Field.split() # Remove pointers before variable - if not Pattern.match(TokenList[-1].lstrip('*')): - ErrMsgList.append(TokenList[-1].lstrip('*')) - + Token = TokenList[-1] + if Token in ['OPTIONAL']: + Token = TokenList[-2] + if not Pattern.match(Token.lstrip('*')): + ErrMsgList.append(Token.lstrip('*')) + return ErrMsgList def CheckDeclTypedefFormat(FullFileName, ModelId): ErrorMsgList = [] - + FileID = GetTableID(FullFileName, ErrorMsgList) if FileID < 0: return ErrorMsgList - + Db = GetDB() FileTable = 'Identifier' + str(FileID) SqlStatement = """ select Name, StartLine, EndLine, ID, Value @@ -1634,7 +1664,7 @@ def CheckDeclTypedefFormat(FullFileName, ModelId): ResultList = [] for Result in ResultSet: ResultList.append(Result) - + ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_ALL if ModelId == DataClass.MODEL_IDENTIFIER_STRUCTURE: ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_STRUCTURE_DECLARATION @@ -1642,7 +1672,7 @@ def CheckDeclTypedefFormat(FullFileName, ModelId): ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_ENUMERATED_TYPE elif ModelId == DataClass.MODEL_IDENTIFIER_UNION: ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_UNION_TYPE - + SqlStatement = """ select Modifier, Name, Value, StartLine, EndLine, ID from %s where Model = %d @@ -1663,16 +1693,16 @@ def CheckDeclTypedefFormat(FullFileName, ModelId): ValueModelId = DataClass.MODEL_IDENTIFIER_UNION else: continue - + if ValueModelId != ModelId: continue # Check member variable format. ErrMsgList = CheckMemberVariableFormat(Name, Value, FileTable, Td[5], ModelId) for ErrMsg in ErrMsgList: - if EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Name+'.'+ErrMsg): + if EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Name + '.' + ErrMsg): continue - PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Member variable [%s] NOT follow naming convention.' % (Name+'.'+ErrMsg), FileTable, Td[5]) - + PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Member variable [%s] NOT follow naming convention.' % (Name + '.' + ErrMsg), FileTable, Td[5]) + # First check in current file to see whether struct/union/enum is typedef-ed. UntypedefedList = [] for Result in ResultList: @@ -1687,14 +1717,14 @@ def CheckDeclTypedefFormat(FullFileName, ModelId): ValueModelId = DataClass.MODEL_IDENTIFIER_UNION else: continue - + if ValueModelId != ModelId: continue ErrMsgList = CheckMemberVariableFormat(Name, Value, FileTable, Result[3], ModelId) for ErrMsg in ErrMsgList: - if EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Result[0]+'.'+ErrMsg): + if EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Result[0] + '.' + ErrMsg): continue - PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Member variable [%s] NOT follow naming convention.' % (Result[0]+'.'+ErrMsg), FileTable, Result[3]) + PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Member variable [%s] NOT follow naming convention.' % (Result[0] + '.' + ErrMsg), FileTable, Result[3]) # Check whether it is typedefed. Found = False for Td in TdList: @@ -1711,21 +1741,21 @@ def CheckDeclTypedefFormat(FullFileName, ModelId): PrintErrorMsg(ErrorType, 'Typedef should be UPPER case', FileTable, Td[5]) if Found: break - + if not Found: UntypedefedList.append(Result) continue - + if len(UntypedefedList) == 0: return - + IncludeFileList = GetAllIncludeFiles(FullFileName) TdList = [] for F in IncludeFileList: FileID = GetTableID(F, ErrorMsgList) if FileID < 0: continue - + IncludeFileTable = 'Identifier' + str(FileID) SqlStatement = """ select Modifier, Name, Value, StartLine, EndLine, ID from %s @@ -1733,13 +1763,13 @@ def CheckDeclTypedefFormat(FullFileName, ModelId): """ % (IncludeFileTable, DataClass.MODEL_IDENTIFIER_TYPEDEF) ResultSet = Db.TblFile.Exec(SqlStatement) TdList.extend(ResultSet) - + for Result in UntypedefedList: - + # Check whether it is typedefed. Found = False for Td in TdList: - + if len(Td[0]) > 0: continue if Result[1] >= Td[3] and Td[4] >= Result[2]: @@ -1752,27 +1782,27 @@ def CheckDeclTypedefFormat(FullFileName, ModelId): PrintErrorMsg(ErrorType, 'Typedef should be UPPER case', FileTable, Td[5]) if Found: break - + if not Found: PrintErrorMsg(ErrorType, 'No Typedef for %s' % Result[0], FileTable, Result[3]) continue - + def CheckDeclStructTypedef(FullFileName): CheckDeclTypedefFormat(FullFileName, DataClass.MODEL_IDENTIFIER_STRUCTURE) def CheckDeclEnumTypedef(FullFileName): CheckDeclTypedefFormat(FullFileName, DataClass.MODEL_IDENTIFIER_ENUMERATE) - + def CheckDeclUnionTypedef(FullFileName): CheckDeclTypedefFormat(FullFileName, DataClass.MODEL_IDENTIFIER_UNION) def CheckDeclArgModifier(FullFileName): ErrorMsgList = [] - + FileID = GetTableID(FullFileName, ErrorMsgList) if FileID < 0: return ErrorMsgList - + Db = GetDB() FileTable = 'Identifier' + str(FileID) SqlStatement = """ select Modifier, Name, ID @@ -1787,7 +1817,7 @@ def CheckDeclArgModifier(FullFileName): if PatternInModifier(Result[0], Modifier) and len(Result[0]) < MAX_MODIFIER_LENGTH: PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER, 'Variable Modifier %s' % Result[0], FileTable, Result[2]) break - + SqlStatement = """ select Modifier, Name, ID from %s where Model = %d @@ -1798,7 +1828,7 @@ def CheckDeclArgModifier(FullFileName): if PatternInModifier(Result[0], Modifier): PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER, 'Return Type Modifier %s' % Result[0], FileTable, Result[2]) break - + SqlStatement = """ select Modifier, Header, ID from Function where BelongsToFile = %d @@ -1812,11 +1842,11 @@ def CheckDeclArgModifier(FullFileName): def CheckDeclNoUseCType(FullFileName): ErrorMsgList = [] - + FileID = GetTableID(FullFileName, ErrorMsgList) if FileID < 0: return ErrorMsgList - + Db = GetDB() FileTable = 'Identifier' + str(FileID) SqlStatement = """ select Modifier, Name, ID @@ -1828,9 +1858,15 @@ def CheckDeclNoUseCType(FullFileName): for Result in ResultSet: for Type in CTypeTuple: if PatternInModifier(Result[0], Type): - PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, 'Variable type %s' % Type, FileTable, Result[2]) + if EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, + Result[0] + ' ' + Result[1]): + continue + PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, + 'Invalid variable type (%s) in definition [%s]' % (Type, Result[0] + ' ' + Result[1]), + FileTable, + Result[2]) break - + SqlStatement = """ select Modifier, Name, ID, Value from %s where Model = %d @@ -1844,11 +1880,11 @@ def CheckDeclNoUseCType(FullFileName): for Type in CTypeTuple: if PatternInModifier(Result[0], Type): PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, '%s Return type %s' % (FuncName, Result[0]), FileTable, Result[2]) - + for Param in ParamList: if PatternInModifier(Param.Modifier, Type): PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, 'Parameter %s' % Param.Name, FileTable, Result[2]) - + SqlStatement = """ select Modifier, Header, ID, Name from Function where BelongsToFile = %d @@ -1862,22 +1898,22 @@ def CheckDeclNoUseCType(FullFileName): for Type in CTypeTuple: if PatternInModifier(Result[0], Type): PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, '[%s] Return type %s' % (FuncName, Result[0]), FileTable, Result[2]) - + for Param in ParamList: if PatternInModifier(Param.Modifier, Type): PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, 'Parameter %s' % Param.Name, FileTable, Result[2]) - + def CheckPointerNullComparison(FullFileName): ErrorMsgList = [] - + FileID = GetTableID(FullFileName, ErrorMsgList) if FileID < 0: return ErrorMsgList - + # cache the found function return type to accelerate later checking in this file. FuncReturnTypeDict = {} - + Db = GetDB() FileTable = 'Identifier' + str(FileID) SqlStatement = """ select Value, StartLine, ID @@ -1890,7 +1926,7 @@ def CheckPointerNullComparison(FullFileName): PSL = [] for Result in ResultSet: PSL.append([Result[0], Result[1], Result[2]]) - + SqlStatement = """ select BodyStartLine, EndLine, Header, Modifier, ID from Function where BelongsToFile = %d @@ -1899,16 +1935,16 @@ def CheckPointerNullComparison(FullFileName): FL = [] for Result in ResultSet: FL.append([Result[0], Result[1], Result[2], Result[3], Result[4]]) - + p = GetFuncDeclPattern() for Str in PSL: FuncRecord = GetFuncContainsPE(Str[1], FL) - if FuncRecord == None: + if FuncRecord is None: continue - + for Exp in GetPredicateListFromPredicateExpStr(Str[0]): PredInfo = SplitPredicateStr(Exp) - if PredInfo[1] == None: + if PredInfo[1] is None: PredVarStr = PredInfo[0][0].strip() IsFuncCall = False SearchInCache = False @@ -1918,9 +1954,9 @@ def CheckPointerNullComparison(FullFileName): PredVarStr = PredVarStr[0:PredVarStr.find('(')] SearchInCache = True # Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable. - if TmpStr.startswith(PredVarStr): + if TmpStr.startswith(PredVarStr): IsFuncCall = True - + if PredVarStr.strip() in IgnoredKeywordList: continue StarList = [] @@ -1930,33 +1966,33 @@ def CheckPointerNullComparison(FullFileName): continue if SearchInCache: Type = FuncReturnTypeDict.get(PredVarStr) - if Type != None: - if Type.find('*') != -1: + if Type is not None: + if Type.find('*') != -1 and Type != 'BOOLEAN*': PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE, 'Predicate Expression: %s' % Exp, FileTable, Str[2]) continue - + if PredVarStr in FuncReturnTypeDict: continue - + Type = GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall, None, StarList) if SearchInCache: FuncReturnTypeDict[PredVarStr] = Type - if Type == None: + if Type is None: continue Type = GetTypeFromArray(Type, PredVarStr) - if Type.find('*') != -1: + if Type.find('*') != -1 and Type != 'BOOLEAN*': PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE, 'Predicate Expression: %s' % Exp, FileTable, Str[2]) def CheckNonBooleanValueComparison(FullFileName): ErrorMsgList = [] - + FileID = GetTableID(FullFileName, ErrorMsgList) if FileID < 0: return ErrorMsgList - + # cache the found function return type to accelerate later checking in this file. FuncReturnTypeDict = {} - + Db = GetDB() FileTable = 'Identifier' + str(FileID) SqlStatement = """ select Value, StartLine, ID @@ -1969,7 +2005,7 @@ def CheckNonBooleanValueComparison(FullFileName): PSL = [] for Result in ResultSet: PSL.append([Result[0], Result[1], Result[2]]) - + SqlStatement = """ select BodyStartLine, EndLine, Header, Modifier, ID from Function where BelongsToFile = %d @@ -1978,18 +2014,16 @@ def CheckNonBooleanValueComparison(FullFileName): FL = [] for Result in ResultSet: FL.append([Result[0], Result[1], Result[2], Result[3], Result[4]]) - + p = GetFuncDeclPattern() for Str in PSL: FuncRecord = GetFuncContainsPE(Str[1], FL) - if FuncRecord == None: + if FuncRecord is None: continue - + for Exp in GetPredicateListFromPredicateExpStr(Str[0]): -# if p.match(Exp): -# continue PredInfo = SplitPredicateStr(Exp) - if PredInfo[1] == None: + if PredInfo[1] is None: PredVarStr = PredInfo[0][0].strip() IsFuncCall = False SearchInCache = False @@ -1999,9 +2033,9 @@ def CheckNonBooleanValueComparison(FullFileName): PredVarStr = PredVarStr[0:PredVarStr.find('(')] SearchInCache = True # Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable. - if TmpStr.startswith(PredVarStr): + if TmpStr.startswith(PredVarStr): IsFuncCall = True - + if PredVarStr.strip() in IgnoredKeywordList: continue StarList = [] @@ -2009,36 +2043,35 @@ def CheckNonBooleanValueComparison(FullFileName): # No variable found, maybe value first? like (0 == VarName) if len(PredVarList) == 0: continue - + if SearchInCache: Type = FuncReturnTypeDict.get(PredVarStr) - if Type != None: + if Type is not None: if Type.find('BOOLEAN') == -1: PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR, 'Predicate Expression: %s' % Exp, FileTable, Str[2]) continue - + if PredVarStr in FuncReturnTypeDict: continue - Type = GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall, 'BOOLEAN', StarList) if SearchInCache: FuncReturnTypeDict[PredVarStr] = Type - if Type == None: + if Type is None: continue if Type.find('BOOLEAN') == -1: PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR, 'Predicate Expression: %s' % Exp, FileTable, Str[2]) - + def CheckBooleanValueComparison(FullFileName): ErrorMsgList = [] - + FileID = GetTableID(FullFileName, ErrorMsgList) if FileID < 0: return ErrorMsgList - + # cache the found function return type to accelerate later checking in this file. FuncReturnTypeDict = {} - + Db = GetDB() FileTable = 'Identifier' + str(FileID) SqlStatement = """ select Value, StartLine, ID @@ -2051,7 +2084,7 @@ def CheckBooleanValueComparison(FullFileName): PSL = [] for Result in ResultSet: PSL.append([Result[0], Result[1], Result[2]]) - + SqlStatement = """ select BodyStartLine, EndLine, Header, Modifier, ID from Function where BelongsToFile = %d @@ -2060,13 +2093,13 @@ def CheckBooleanValueComparison(FullFileName): FL = [] for Result in ResultSet: FL.append([Result[0], Result[1], Result[2], Result[3], Result[4]]) - + p = GetFuncDeclPattern() for Str in PSL: FuncRecord = GetFuncContainsPE(Str[1], FL) - if FuncRecord == None: + if FuncRecord is None: continue - + for Exp in GetPredicateListFromPredicateExpStr(Str[0]): PredInfo = SplitPredicateStr(Exp) if PredInfo[1] in ('==', '!=') and PredInfo[0][1] in ('TRUE', 'FALSE'): @@ -2079,9 +2112,9 @@ def CheckBooleanValueComparison(FullFileName): PredVarStr = PredVarStr[0:PredVarStr.find('(')] SearchInCache = True # Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable. - if TmpStr.startswith(PredVarStr): + if TmpStr.startswith(PredVarStr): IsFuncCall = True - + if PredVarStr.strip() in IgnoredKeywordList: continue StarList = [] @@ -2089,33 +2122,33 @@ def CheckBooleanValueComparison(FullFileName): # No variable found, maybe value first? like (0 == VarName) if len(PredVarList) == 0: continue - + if SearchInCache: Type = FuncReturnTypeDict.get(PredVarStr) - if Type != None: + if Type is not None: if Type.find('BOOLEAN') != -1: PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE, 'Predicate Expression: %s' % Exp, FileTable, Str[2]) continue - + if PredVarStr in FuncReturnTypeDict: continue - + Type = GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall, 'BOOLEAN', StarList) if SearchInCache: FuncReturnTypeDict[PredVarStr] = Type - if Type == None: + if Type is None: continue if Type.find('BOOLEAN') != -1: PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE, 'Predicate Expression: %s' % Exp, FileTable, Str[2]) - + def CheckHeaderFileData(FullFileName): ErrorMsgList = [] - + FileID = GetTableID(FullFileName, ErrorMsgList) if FileID < 0: return ErrorMsgList - + Db = GetDB() FileTable = 'Identifier' + str(FileID) SqlStatement = """ select ID, Modifier @@ -2126,7 +2159,7 @@ def CheckHeaderFileData(FullFileName): for Result in ResultSet: if not Result[1].startswith('extern'): PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_DATA, 'Variable definition appears in header file', FileTable, Result[0]) - + SqlStatement = """ select ID from Function where BelongsToFile = %d @@ -2139,11 +2172,11 @@ def CheckHeaderFileData(FullFileName): def CheckHeaderFileIfndef(FullFileName): ErrorMsgList = [] - + FileID = GetTableID(FullFileName, ErrorMsgList) if FileID < 0: return ErrorMsgList - + Db = GetDB() FileTable = 'Identifier' + str(FileID) SqlStatement = """ select Value, StartLine @@ -2164,7 +2197,7 @@ def CheckHeaderFileIfndef(FullFileName): if not Result[0].startswith('/*') and not Result[0].startswith('//'): PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_2, '', 'File', FileID) break - + SqlStatement = """ select Value from %s where StartLine > (select max(EndLine) from %s where Model = %d) @@ -2177,11 +2210,11 @@ def CheckHeaderFileIfndef(FullFileName): def CheckDoxygenCommand(FullFileName): ErrorMsgList = [] - + FileID = GetTableID(FullFileName, ErrorMsgList) if FileID < 0: return ErrorMsgList - + Db = GetDB() FileTable = 'Identifier' + str(FileID) SqlStatement = """ select Value, ID @@ -2189,7 +2222,8 @@ def CheckDoxygenCommand(FullFileName): where Model = %d or Model = %d """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT, DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER) ResultSet = Db.TblFile.Exec(SqlStatement) - DoxygenCommandList = ['bug', 'todo', 'example', 'file', 'attention', 'param', 'post', 'pre', 'retval', 'return', 'sa', 'since', 'test', 'note', 'par'] + DoxygenCommandList = ['bug', 'todo', 'example', 'file', 'attention', 'param', 'post', 'pre', 'retval', + 'return', 'sa', 'since', 'test', 'note', 'par', 'endcode', 'code'] for Result in ResultSet: CommentStr = Result[0] CommentPartList = CommentStr.split() @@ -2201,6 +2235,10 @@ def CheckDoxygenCommand(FullFileName): if Part.startswith('@'): if EccGlobalData.gException.IsException(ERROR_DOXYGEN_CHECK_COMMAND, Part): continue + if not Part.replace('@', '').strip(): + continue + if Part.lstrip('@') in ['{', '}']: + continue if Part.lstrip('@').isalpha(): if Part.lstrip('@') not in DoxygenCommandList: PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Unknown doxygen command %s' % Part, FileTable, Result[1]) @@ -2211,17 +2249,17 @@ def CheckDoxygenCommand(FullFileName): RealCmd = Part[1:Index] if RealCmd not in DoxygenCommandList: PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Unknown doxygen command %s' % Part, FileTable, Result[1]) - - + + def CheckDoxygenTripleForwardSlash(FullFileName): ErrorMsgList = [] - + FileID = GetTableID(FullFileName, ErrorMsgList) if FileID < 0: return ErrorMsgList - + Db = GetDB() - + SqlStatement = """ select ID, BodyStartLine, BodyStartColumn, EndLine, EndColumn from Function where BelongsToFile = %d @@ -2229,17 +2267,17 @@ def CheckDoxygenTripleForwardSlash(FullFileName): ResultSet = Db.TblFile.Exec(SqlStatement) if len(ResultSet) == 0: return - - FuncDefSet = [] + + FuncDefSet = [] for Result in ResultSet: FuncDefSet.append(Result) - - + + FileTable = 'Identifier' + str(FileID) SqlStatement = """ select Value, ID, StartLine, StartColumn, EndLine, EndColumn from %s - where Model = %d - + where Model = %d + """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT) ResultSet = Db.TblFile.Exec(SqlStatement) CommentSet = [] @@ -2248,8 +2286,8 @@ def CheckDoxygenTripleForwardSlash(FullFileName): CommentSet.append(Result) except: print 'Unrecognized chars in comment of file %s', FullFileName - - + + for Result in CommentSet: CommentStr = Result[0] StartLine = Result[2] @@ -2258,7 +2296,7 @@ def CheckDoxygenTripleForwardSlash(FullFileName): EndColumn = Result[5] if not CommentStr.startswith('///<'): continue - + Found = False for FuncDef in FuncDefSet: if StartLine == FuncDef[1] and StartColumn > FuncDef[2] and EndLine == FuncDef[3] and EndColumn < FuncDef[4]: @@ -2279,45 +2317,121 @@ def CheckDoxygenTripleForwardSlash(FullFileName): def CheckFileHeaderDoxygenComments(FullFileName): ErrorMsgList = [] - + FileID = GetTableID(FullFileName, ErrorMsgList) if FileID < 0: return ErrorMsgList - + Db = GetDB() FileTable = 'Identifier' + str(FileID) SqlStatement = """ select Value, ID from %s - where Model = %d and StartLine = 1 and StartColumn = 0 + where Model = %d and (StartLine = 1 or StartLine = 7 or StartLine = 8) and StartColumn = 0 """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT) ResultSet = Db.TblFile.Exec(SqlStatement) if len(ResultSet) == 0: - PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'No Comment appear at the very beginning of file.', 'File', FileID) + PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'No File License header appear at the very beginning of file.', 'File', FileID) return ErrorMsgList - + + NoHeaderCommentStartFlag = True + NoHeaderCommentEndFlag = True + NoHeaderCommentPeriodFlag = True + NoCopyrightFlag = True + NoLicenseFlag = True + NoRevReferFlag = True + NextLineIndex = 0 for Result in ResultSet: - CommentStr = Result[0] - if not CommentStr.startswith('/** @file'): - PrintErrorMsg(ERROR_DOXYGEN_CHECK_FILE_HEADER, 'File header comment should begin with ""/** @file""', FileTable, Result[1]) - if not CommentStr.endswith('**/'): - PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment should end with **/', FileTable, Result[1]) - if CommentStr.find('.') == -1: - PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMENT_DESCRIPTION, 'Comment description should end with period \'.\'', FileTable, Result[1]) + FileStartFlag = False + CommentStrList = [] + CommentStr = Result[0].strip() + CommentStrListTemp = CommentStr.split('\n') + if (len(CommentStrListTemp) <= 1): + # For Mac + CommentStrListTemp = CommentStr.split('\r') + # Skip the content before the file header + for CommentLine in CommentStrListTemp: + if CommentLine.strip().startswith('/** @file'): + FileStartFlag = True + if FileStartFlag == True: + CommentStrList.append(CommentLine) + + ID = Result[1] + Index = 0 + if CommentStrList and CommentStrList[0].strip().startswith('/** @file'): + NoHeaderCommentStartFlag = False + else: + continue + if CommentStrList and CommentStrList[-1].strip().endswith('**/'): + NoHeaderCommentEndFlag = False + else: + continue + + for CommentLine in CommentStrList: + Index = Index + 1 + NextLineIndex = Index + if CommentLine.startswith('/** @file'): + continue + if CommentLine.startswith('**/'): + break + # Check whether C File header Comment content start with two spaces. + if EccGlobalData.gConfig.HeaderCheckCFileCommentStartSpacesNum == '1' or EccGlobalData.gConfig.HeaderCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + if CommentLine.startswith('/** @file') == False and CommentLine.startswith('**/') == False and CommentLine.strip() and CommentLine.startswith(' ') == False: + PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment content should start with two spaces at each line', FileTable, ID) + + CommentLine = CommentLine.strip() + if CommentLine.startswith('Copyright'): + NoCopyrightFlag = False + if CommentLine.find('All rights reserved') == -1: + for Copyright in EccGlobalData.gConfig.Copyright: + if CommentLine.find(Copyright) > -1: + PrintErrorMsg(ERROR_HEADER_CHECK_FILE, '""All rights reserved"" announcement should be following the ""Copyright"" at the same line', FileTable, ID) + break + if CommentLine.endswith('
') == -1: + PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'The ""
"" at the end of the Copyright line is required', FileTable, ID) + if NextLineIndex < len(CommentStrList) and CommentStrList[NextLineIndex].strip().startswith('Copyright') == False and CommentStrList[NextLineIndex].strip(): + NoLicenseFlag = False + if CommentLine.startswith('@par Revision Reference:'): + NoRevReferFlag = False + RefListFlag = False + for RefLine in CommentStrList[NextLineIndex:]: + if RefLine.strip() and (NextLineIndex + 1) < len(CommentStrList) and CommentStrList[NextLineIndex+1].strip() and CommentStrList[NextLineIndex+1].strip().startswith('**/') == False: + RefListFlag = True + if RefLine.strip() == False or RefLine.strip().startswith('**/'): + RefListFlag = False + break + # Check whether C File header Comment's each reference at list should begin with a bullet character. + if EccGlobalData.gConfig.HeaderCheckCFileCommentReferenceFormat == '1' or EccGlobalData.gConfig.HeaderCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + if RefListFlag == True: + if RefLine.strip() and RefLine.strip().startswith('**/') == False and RefLine.startswith(' -') == False: + PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'Each reference on a separate line should begin with a bullet character ""-"" ', FileTable, ID) + + if NoHeaderCommentStartFlag: + PrintErrorMsg(ERROR_DOXYGEN_CHECK_FILE_HEADER, 'File header comment should begin with ""/** @file""', FileTable, ID) + return + if NoHeaderCommentEndFlag: + PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment should end with ""**/""', FileTable, ID) + return + if NoCopyrightFlag: + PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment missing the ""Copyright""', FileTable, ID) + #Check whether C File header Comment have the License immediately after the ""Copyright"" line. + if EccGlobalData.gConfig.HeaderCheckCFileCommentLicenseFormat == '1' or EccGlobalData.gConfig.HeaderCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + if NoLicenseFlag: + PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment should have the License immediately after the ""Copyright"" line', FileTable, ID) def CheckFuncHeaderDoxygenComments(FullFileName): ErrorMsgList = [] - + FileID = GetTableID(FullFileName, ErrorMsgList) if FileID < 0: return ErrorMsgList - + Db = GetDB() FileTable = 'Identifier' + str(FileID) SqlStatement = """ select Value, StartLine, EndLine, ID from %s where Model = %d """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT) - + ResultSet = Db.TblFile.Exec(SqlStatement) CommentSet = [] try: @@ -2325,7 +2439,7 @@ def CheckFuncHeaderDoxygenComments(FullFileName): CommentSet.append(Result) except: print 'Unrecognized chars in comment of file %s', FullFileName - + # Func Decl check SqlStatement = """ select Modifier, Name, StartLine, ID, Value from %s @@ -2342,13 +2456,13 @@ def CheckFuncHeaderDoxygenComments(FullFileName): continue ErrorMsgList.append('Line %d :Function %s has NO comment immediately preceding it.' % (Result[2], Result[1])) PrintErrorMsg(ERROR_HEADER_CHECK_FUNCTION, 'Function [%s] has NO comment immediately preceding it.' % (FuncName), FileTable, Result[3]) - + # Func Def check SqlStatement = """ select Value, StartLine, EndLine, ID from %s where Model = %d """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER) - + ResultSet = Db.TblFile.Exec(SqlStatement) CommentSet = [] try: @@ -2356,7 +2470,7 @@ def CheckFuncHeaderDoxygenComments(FullFileName): CommentSet.append(Result) except: print 'Unrecognized chars in comment of file %s', FullFileName - + SqlStatement = """ select Modifier, Header, StartLine, ID, Name from Function where BelongsToFile = %d @@ -2389,9 +2503,9 @@ def GetDoxygenStrFromComment(Str): while i < len(ParamTagList): DoxygenStrList.append('@param' + ParamTagList[i]) i += 1 - + Str = ParamTagList[0] - + RetvalTagList = ParamTagList[-1].split('@retval') if len(RetvalTagList) > 1: if len(ParamTagList) > 1: @@ -2400,7 +2514,7 @@ def GetDoxygenStrFromComment(Str): while i < len(RetvalTagList): DoxygenStrList.append('@retval' + RetvalTagList[i]) i += 1 - + ReturnTagList = RetvalTagList[-1].split('@return') if len(ReturnTagList) > 1: if len(RetvalTagList) > 1: @@ -2411,13 +2525,13 @@ def GetDoxygenStrFromComment(Str): while i < len(ReturnTagList): DoxygenStrList.append('@return' + ReturnTagList[i]) i += 1 - + if len(DoxygenStrList) > 0: DoxygenStrList[-1] = DoxygenStrList[-1].rstrip('--*/') - + return DoxygenStrList - -def CheckGeneralDoxygenCommentLayout(Str, StartLine, ErrorMsgList, CommentId = -1, TableName = ''): + +def CheckGeneralDoxygenCommentLayout(Str, StartLine, ErrorMsgList, CommentId= -1, TableName=''): #/** --*/ @retval after @param if not Str.startswith('/**'): ErrorMsgList.append('Line %d : Comment does NOT have prefix /** ' % StartLine) @@ -2430,10 +2544,10 @@ def CheckGeneralDoxygenCommentLayout(Str, StartLine, ErrorMsgList, CommentId = - if (FirstRetvalIndex > 0) and (LastParamIndex > 0) and (FirstRetvalIndex < LastParamIndex): ErrorMsgList.append('Line %d : @retval appear before @param ' % StartLine) PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, @retval appear before @param ', TableName, CommentId) - -def CheckFunctionHeaderConsistentWithDoxygenComment(FuncModifier, FuncHeader, FuncStartLine, CommentStr, CommentStartLine, ErrorMsgList, CommentId = -1, TableName = ''): - - ParamList = GetParamList(FuncHeader) + +def CheckFunctionHeaderConsistentWithDoxygenComment(FuncModifier, FuncHeader, FuncStartLine, CommentStr, CommentStartLine, ErrorMsgList, CommentId= -1, TableName=''): + + ParamList = GetParamList(FuncHeader) CheckGeneralDoxygenCommentLayout(CommentStr, CommentStartLine, ErrorMsgList, CommentId, TableName) DescriptionStr = CommentStr DoxygenStrList = GetDoxygenStrFromComment(DescriptionStr) @@ -2451,50 +2565,57 @@ def CheckFunctionHeaderConsistentWithDoxygenComment(FuncModifier, FuncHeader, Fu ParamName = ParamList[Index].Name.strip() Tag = DoxygenStrList[Index].strip(' ') if (not Tag[-1] == ('\n')) and (not Tag[-1] == ('\r')): - ErrorMsgList.append('Line %d : in Comment, \"%s\" does NOT end with new line ' % (CommentStartLine, Tag.replace('\n', '').replace('\r', ''))) - PrintErrorMsg(ERROR_HEADER_CHECK_FUNCTION, 'in Comment, \"%s\" does NOT end with new line ' % (Tag.replace('\n', '').replace('\r', '')), TableName, CommentId) + ErrorMsgList.append('Line %d : in Comment, <%s> does NOT end with new line ' % (CommentStartLine, Tag.replace('\n', '').replace('\r', ''))) + PrintErrorMsg(ERROR_HEADER_CHECK_FUNCTION, 'in Comment, <%s> does NOT end with new line ' % (Tag.replace('\n', '').replace('\r', '')), TableName, CommentId) TagPartList = Tag.split() if len(TagPartList) < 2: - ErrorMsgList.append('Line %d : in Comment, \"%s\" does NOT contain doxygen contents ' % (CommentStartLine, Tag.replace('\n', '').replace('\r', ''))) - PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, \"%s\" does NOT contain doxygen contents ' % (Tag.replace('\n', '').replace('\r', '')), TableName, CommentId) + ErrorMsgList.append('Line %d : in Comment, <%s> does NOT contain doxygen contents ' % (CommentStartLine, Tag.replace('\n', '').replace('\r', ''))) + PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, <%s> does NOT contain doxygen contents ' % (Tag.replace('\n', '').replace('\r', '')), TableName, CommentId) Index += 1 continue LBPos = Tag.find('[') RBPos = Tag.find(']') ParamToLBContent = Tag[len('@param'):LBPos].strip() - if LBPos > 0 and len(ParamToLBContent)==0 and RBPos > LBPos: + if LBPos > 0 and len(ParamToLBContent) == 0 and RBPos > LBPos: InOutStr = '' ModifierPartList = ParamModifier.split() for Part in ModifierPartList: if Part.strip() == 'IN': InOutStr += 'in' if Part.strip() == 'OUT': - if InOutStr != '': + if InOutStr != '': InOutStr += ', out' else: InOutStr = 'out' - + if InOutStr != '': - if Tag.find('['+InOutStr+']') == -1: - ErrorMsgList.append('Line %d : in Comment, \"%s\" does NOT have %s ' % (CommentStartLine, (TagPartList[0] + ' ' +TagPartList[1]).replace('\n', '').replace('\r', ''), '['+InOutStr+']')) - PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, \"%s\" does NOT have %s ' % ((TagPartList[0] + ' ' +TagPartList[1]).replace('\n', '').replace('\r', ''), '['+InOutStr+']'), TableName, CommentId) + if Tag.find('[' + InOutStr + ']') == -1: + if InOutStr != 'in, out': + ErrorMsgList.append('Line %d : in Comment, <%s> does NOT have %s ' % (CommentStartLine, (TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), '[' + InOutStr + ']')) + PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, <%s> does NOT have %s ' % ((TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), '[' + InOutStr + ']'), TableName, CommentId) + else: + if Tag.find('[in,out]') == -1: + ErrorMsgList.append('Line %d : in Comment, <%s> does NOT have %s ' % (CommentStartLine, (TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), '[' + InOutStr + ']')) + PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, <%s> does NOT have %s ' % ((TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), '[' + InOutStr + ']'), TableName, CommentId) + + if Tag.find(ParamName) == -1 and ParamName != 'VOID' and ParamName != 'void': - ErrorMsgList.append('Line %d : in Comment, \"%s\" does NOT consistent with parameter name %s ' % (CommentStartLine, (TagPartList[0] + ' ' +TagPartList[1]).replace('\n', '').replace('\r', ''), ParamName)) - 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) + ErrorMsgList.append('Line %d : in Comment, <%s> does NOT consistent with parameter name %s ' % (CommentStartLine, (TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), ParamName)) + 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) Index += 1 - + if Index < ParamNumber: ErrorMsgList.append('Line %d : Number of doxygen tags in comment less than number of function parameters' % CommentStartLine) PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'Number of doxygen tags in comment less than number of function parameters ', TableName, CommentId) # VOID return type, NOT VOID*. VOID* should be matched with a doxygen tag. if (FuncModifier.find('VOID') != -1 or FuncModifier.find('void') != -1) and FuncModifier.find('*') == -1: - + # assume we allow a return description tag for void func. return. that's why 'DoxygenTagNumber - 1' is used instead of 'DoxygenTagNumber' if Index < DoxygenTagNumber - 1 or (Index < DoxygenTagNumber and DoxygenStrList[Index].startswith('@retval')): ErrorMsgList.append('Line %d : VOID return type need NO doxygen tags in comment' % CommentStartLine) PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'VOID return type need no doxygen tags in comment ', TableName, CommentId) else: - if Index < DoxygenTagNumber and not DoxygenStrList[Index].startswith('@retval') and not DoxygenStrList[Index].startswith('@return'): + if Index < DoxygenTagNumber and not DoxygenStrList[Index].startswith('@retval') and not DoxygenStrList[Index].startswith('@return'): ErrorMsgList.append('Line %d : Number of @param doxygen tags in comment does NOT match number of function parameters' % CommentStartLine) PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'Number of @param doxygen tags in comment does NOT match number of function parameters ', TableName, CommentId) else: @@ -2509,8 +2630,13 @@ if __name__ == '__main__': # EdkLogger.Initialize() # EdkLogger.SetLevel(EdkLogger.QUIET) -# CollectSourceCodeDataIntoDB(sys.argv[1]) - MsgList = CheckFuncHeaderDoxygenComments('C:\\Combo\\R9\\LakeportX64Dev\\FlashDevicePkg\\Library\\SpiFlashChipM25P64\\SpiFlashChipM25P64.c') +# CollectSourceCodeDataIntoDB(sys.argv[1]) + try: + test_file = sys.argv[1] + except IndexError as v: + print "Usage: %s filename" % sys.argv[0] + sys.exit(1) + MsgList = CheckFuncHeaderDoxygenComments(test_file) for Msg in MsgList: print Msg print 'Done!'