## @file
# This file is used to be the c coding style checking of ECC tool
#
# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
# 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
#
# 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 re
import string
import CodeFragmentCollector
import FileProfile
import Database
from EccToolError import *
import EccGlobalData
import MetaDataParser
IncludeFileListDict = {}
IncludePathListDict = {}
ComplexTypeDict = {}
SUDict = {}
def GetIgnoredDirListPattern():
return p
def GetFuncDeclPattern():
return p
def GetArrayPattern():
return p
def GetTypedefFuncPointerPattern():
return p
def GetDB():
return EccGlobalData.gDb
def GetConfig():
return EccGlobalData.gConfig
Msg = ''
for Part in MsgPartList:
Msg += ' '
else:
return Type
return True
return False
def GetIdentifierList():
IdList = []
IdComment = DataClass.IdentifierClass(-1, '', '', '', comment.Content, DataClass.MODEL_IDENTIFIER_COMMENT, -1, -1, comment.StartPos[0], comment.StartPos[1], comment.EndPos[0], comment.EndPos[1])
IdPP = DataClass.IdentifierClass(-1, '', '', '', pp.Content, Type, -1, -1, pp.StartPos[0], pp.StartPos[1], pp.EndPos[0], pp.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])
continue
if FirstChar == '*':
VarNameStartColumn += 1
elif FirstChar == '\r':
VarNameStartLine += 1
elif FirstChar == '\n':
VarNameStartLine += 1
elif FirstChar == ' ':
VarNameStartColumn += 1
elif FirstChar == '\t':
VarNameStartColumn += 8
else:
VarNameStartColumn += 1
if NameStart > 0:
Index = 0
PreChar = ''
Index += 6
VarNameStartColumn += 6
PreChar = ''
continue
elif FirstChar == '\r':
Index += 1
VarNameStartLine += 1
elif FirstChar == '\n':
Index += 1
if PreChar != '\r':
VarNameStartLine += 1
elif FirstChar == ' ':
Index += 1
VarNameStartColumn += 1
elif FirstChar == '\t':
Index += 1
VarNameStartColumn += 8
else:
Index += 1
VarNameStartColumn += 1
IdVar = DataClass.IdentifierClass(-1, var.Modifier, '', var.Declarator, FuncName, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION, -1, -1, var.StartPos[0], var.StartPos[1], VarNameStartLine, VarNameStartColumn)
continue
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)
else:
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)
IdEnum = DataClass.IdentifierClass(-1, '', '', Name, Value, DataClass.MODEL_IDENTIFIER_ENUMERATE, -1, -1, enum.StartPos[0], enum.StartPos[1], enum.EndPos[0], enum.EndPos[1])
continue
SkipLen = 6
SkipLen = 5
Value = ''
else:
IdPE = DataClass.IdentifierClass(-1, '', '', Name, Value, Type, -1, -1, su.StartPos[0], su.StartPos[1], su.EndPos[0], su.EndPos[1])
Modifier = ''
if StarPos != -1:
# Modifier += ' ' + '*'
StarPos += 1
else:
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])
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])
return IdList
StrippedStr = ''
StrippedStr += Char
return StrippedStr
ParamIdList = []
#DeclSplitList = FuncDeclarator.split('(')
#if len(DeclSplitList) < 2:
if LBPos == -1:
return ParamIdList
#FuncName = DeclSplitList[0]
#ParamStr = DeclSplitList[1].rstrip(')')
LineSkipped = 0
OffsetSkipped = 0
if TailChar == '\n':
LineSkipped += 1
OffsetSkipped = 0
elif TailChar == '\r':
LineSkipped += 1
OffsetSkipped = 0
elif TailChar == ' ':
OffsetSkipped += 1
elif TailChar == '\t':
OffsetSkipped += 8
else:
continue
if ParamName == 'OPTIONAL':
if ParamModifier == '':
DeclText = ''
else:
ParamModifier += 'OPTIONAL'
# ignore array length if exists.
if LBIndex != -1:
Index = 0
PreChar = ''
if FirstChar == '\r':
Index += 1
LineSkipped += 1
OffsetSkipped = 0
elif FirstChar == '\n':
Index += 1
if PreChar != '\r':
LineSkipped += 1
OffsetSkipped = 0
elif FirstChar == ' ':
Index += 1
OffsetSkipped += 1
elif FirstChar == '\t':
Index += 1
OffsetSkipped += 8
else:
Index += 1
OffsetSkipped += 1
PreChar = ''
if FirstChar == '\r':
Index += 1
LineSkipped += 1
OffsetSkipped = 0
elif FirstChar == '\n':
Index += 1
if PreChar != '\r':
LineSkipped += 1
OffsetSkipped = 0
elif FirstChar == ' ':
Index += 1
OffsetSkipped += 1
elif FirstChar == '\t':
Index += 1
OffsetSkipped += 8
else:
Index += 1
OffsetSkipped += 1
if ParamName != '...':
IdParam = DataClass.IdentifierClass(-1, ParamModifier, '', ParamName, '', DataClass.MODEL_IDENTIFIER_PARAMETER, -1, -1, ParamBeginLine, ParamBeginOffset, ParamEndLine, ParamEndOffset)
return ParamIdList
def GetFunctionList():
FuncObjList = []
ParamIdList = []
if FirstChar == '*':
FuncNameStartColumn += 1
elif FirstChar == '\r':
FuncNameStartLine += 1
elif FirstChar == '\n':
FuncNameStartLine += 1
elif FirstChar == ' ':
FuncNameStartColumn += 1
elif FirstChar == '\t':
FuncNameStartColumn += 8
else:
FuncNameStartColumn += 1
continue
if NameStart > 0:
Index = 0
PreChar = ''
Index += 6
FuncNameStartColumn += 6
PreChar = ''
continue
elif FirstChar == '\r':
Index += 1
FuncNameStartLine += 1
elif FirstChar == '\n':
Index += 1
if PreChar != '\r':
FuncNameStartLine += 1
elif FirstChar == ' ':
Index += 1
FuncNameStartColumn += 1
elif FirstChar == '\t':
Index += 1
FuncNameStartColumn += 8
else:
Index += 1
FuncNameStartColumn += 1
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)
return FuncObjList
TimeValue = 0.0
SqlStatement = """ select TimeStamp
from File
where FullPath = \'%s\'
""" % (FullFileName)
return TimeValue
FileObjList = []
ParseErrorFileList = []
continue
# symlinks to directories are treated as directories
for f in filenames:
collector = None
try:
except UnicodeError:
# collector.PrintFragments()
FileObj = DataClass.FileClass(-1, BaseName, Ext, DirName, FullName, model, ModifiedTime, GetFunctionList(), GetIdentifierList(), [])
if collector:
EdkLogger.info("Found unrecoverable error during parsing:\n\t%s\n" % "\n\t".join(ParseErrorFileList))
for file in FileObjList:
if ErrorMsgList == None:
ErrorMsgList = []
SqlStatement = """ select ID
from File
where FullPath like '%s'
""" % FullFileName
FileID = -1
if FileID != -1:
return - 2
if FileID == -1:
return - 1
return FileID
return []
if IFList != None:
return IFList
if FileID < 0:
return []
SqlStatement = """ select Value
from %s
where Model = %d
return ResultSet
for IncludePath in IncludePathList:
return FullPath
return None
if IncludePathList == None:
IncludePathList = MetaDataParser.GetIncludeListOfFile(EccGlobalData.gWorkspace, FullFileName, GetDB())
if FileDirName not in IncludePathList:
IncludeFileQueue = []
if FullPath != None:
i = 0
while i < len(IncludeFileQueue):
i += 1
return IncludeFileQueue
PredicateList = []
i = 0
PredicateBegin = 0
#PredicateEnd = 0
LogicOpPos = -1
p = GetFuncDeclPattern()
PredicateBegin = i
LogicOpPos = i
# Exp may contain '.' or '->'
else:
i += 1
if PredicateBegin > LogicOpPos:
break
PredicateBegin += 1
# Exp may contain '.' or '->'
else:
return PredicateList
Lvalue += ' '
i = 0
SearchBegin = 0
VarStart = -1
VarEnd = -1
VarList = []
if VarStart == -1:
VarStart = i
VarEnd = i
i += 1
elif VarEnd != -1:
i += 1
break
else:
i += 1
if VarEnd == -1:
break
break
else:
i = SearchBegin
VarStart = -1
VarEnd = -1
return VarList
Value = None
if IsFuncCalling:
Index = 0
UnmatchedLBCount = 0
Index += 1
Index += 1
# maybe type-cast at the begining, skip it.
Index += 1
continue
UnmatchedLBCount += 1
Index += 1
continue
UnmatchedLBCount -= 1
Index += 1
if UnmatchedLBCount == 0:
break
continue
Index += 1
if UnmatchedLBCount > 0:
return [Name]
if IndexInRemainingStr == -1:
return [Name]
while True:
if Index == -1:
return [Name]
if Str[Index - 1].isalnum() or Str[Index - 1].isspace() or Str[Index - 1] == ')' or Str[Index - 1] == ']':
p = GetFuncDeclPattern()
return [PredPartList, '==']
return [PredPartList, '!=']
return [PredPartList, '>=']
return [PredPartList, '<=']
return [PredPartList, '>']
return [PredPartList, '<']
return [[Str, None], None]
return Result
return None
return True
return False
ReturnType = ''
for M in MList:
continue
# remove array sufix
continue
ReturnType += M + ' '
ReturnType = 'VOID'
return ReturnType
return False
else:
return True
if Dict != None:
return Dict
SqlStatement = """ select Modifier, Name, Value, ID
from %s
where Model = %d
Dict = {}
for F in IncludeFileList:
FileID = GetTableID(F)
if FileID < 0:
continue
SqlStatement = """ select Modifier, Name, Value, ID
from %s
where Model = %d
else:
else:
return Dict
if Dict != None:
return Dict
SqlStatement = """ select Name, Value, ID
from %s
where Model = %d or Model = %d
Dict = {}
for F in IncludeFileList:
FileID = GetTableID(F)
if FileID < 0:
continue
SqlStatement = """ select Name, Value, ID
from %s
where Model = %d or Model = %d
return Dict
Str += ' '
Index = 0
# meet new line, then no longer in a comment for //
if InComment and DoubleSlashComment:
Index += 1
# check for */ comment end
elif InComment and not DoubleSlashComment and ListFromStr[Index] == '*' and ListFromStr[Index + 1] == '/':
Index += 1
Index += 1
# set comments to spaces
elif InComment:
Index += 1
# check for // comment
elif ListFromStr[Index] == '/' and ListFromStr[Index + 1] == '/' and ListFromStr[Index + 2] != '\n':
# check for /* comment start
Index += 1
Index += 1
else:
Index += 1
# restore from List to String
return Str
if Value == None:
if Value == None:
return None
while LBPos == -1:
if Value == None:
break
if Value == None:
return None
# RBPos = Value.find('}')
for Field in FieldsList:
if Index < 1:
continue
else:
# For the condition that the field in struct is an array with [] sufixes...
return None
return Type
return Type
return Type
Index = 0
if FromType == None:
return None
# we want to determine the exact type.
if TargetType != None:
# we only want to check if it is a pointer
else:
return Type
Index += 1
return Type
def GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall=False, TargetType=None, StarList=None):
# search variable in include files
# it is a function call, search function declarations and definitions
if IsFuncCall:
SqlStatement = """ select Modifier, ID
from %s
where Model = %d and Value = \'%s\'
return Type
for F in IncludeFileList:
FileID = GetTableID(F)
if FileID < 0:
continue
SqlStatement = """ select Modifier, ID
from %s
where Model = %d and Value = \'%s\'
return Type
SqlStatement = """ select Modifier, ID
from Function
where BelongsToFile = %d and Name = \'%s\'
return Type
for F in IncludeFileList:
FileID = GetTableID(F)
if FileID < 0:
continue
SqlStatement = """ select Modifier, ID
from Function
where BelongsToFile = %d and Name = \'%s\'
return Type
return None
# really variable, search local variable first
SqlStatement = """ select Modifier, ID
from %s
where Model = %d and Name = \'%s\' and StartLine >= %d and StartLine <= %d
return Type
else:
# Type = GetDataTypeFromModifier(Result[0]).split()[-1]
# Get real type after de-reference pointers.
return Type
# search function parameters second
return Type
else:
# Get real type after de-reference pointers.
return Type
# search global variable next
SqlStatement = """ select Modifier, ID
from %s
where Model = %d and Name = \'%s\' and BelongsToFunction = -1
return Type
else:
# Get real type after de-reference pointers.
return Type
for F in IncludeFileList:
FileID = GetTableID(F)
if FileID < 0:
continue
SqlStatement = """ select Modifier, ID
from %s
where Model = %d and BelongsToFunction = -1 and Name = \'%s\'
return Type
else:
# Get real type after de-reference pointers.
return Type
while Count > 0:
return Type
ErrorMsgList = []
if FileID < 0:
return ErrorMsgList
SqlStatement = """ select Modifier, ID, StartLine, StartColumn, EndLine, Value
from %s
where Model = %d
continue
PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '[%s] Return Type should appear at the start of line' % FuncName, FileTable, Result[1])
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
""" % (FileID)
continue
PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '[%s] Return Type should appear at the start of line' % FuncName, 'Function', Result[1])
PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '[%s] Return Type should appear on its own line' % FuncName, 'Function', Result[1])
ErrorMsgList = []
if FileID < 0:
return ErrorMsgList
SqlStatement = """ select Modifier, ID
from %s
where Model = %d
# if len(ReturnType) == 0:
# continue
if Index != 0:
SqlStatement = """ select Modifier, ID
from Function
where BelongsToFile = %d
""" % (FileID)
# if len(ReturnType) == 0:
# continue
if Index != 0:
PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_OPTIONAL_FUNCTIONAL_MODIFIER, '', 'Function', Result[1])
ErrorMsgList = []
# Parameter variable format pattern.
if FileID < 0:
return ErrorMsgList
SqlStatement = """ select Name, ID, EndColumn, Value
from %s
where Model = %d
continue
PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Function name [%s] should appear at the start of a line' % FuncName, FileTable, Result[1])
continue
StartLine = 0
PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Parameter %s should be in its own line.' % 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])
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
""" % (FileID)
continue
PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Function name [%s] should appear at the start of a line' % FuncName, 'Function', Result[1])
continue
StartLine = 0
PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Parameter %s should be in its own line.' % Param.Name, 'Function', Result[1])
PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Empty line appears before Parameter %s.' % Param.Name, 'Function', 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])
PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, '\')\' should be on a new line and indented two spaces', 'Function', Result[1])
ErrorMsgList = []
if FileID < 0:
return ErrorMsgList
SqlStatement = """ select Modifier, Header, Name, ID
from Function
where BelongsToFile = %d
""" % (FileID)
return ErrorMsgList
FuncDefList = []
SqlStatement = """ select Modifier, Name, ID
from %s
where Model = %d
FuncDeclList = []
UndeclFuncList = []
for FuncDef in FuncDefList:
for FuncDecl in FuncDeclList:
if DiffModifier(FuncModifier, DeclModifier) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, FuncName):
PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, 'Function [%s] modifier different with prototype.' % FuncName, '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
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:
FuncDeclList = []
for F in IncludeFileList:
if FileID < 0:
continue
SqlStatement = """ select Modifier, Name, ID
from %s
where Model = %d
for FuncDef in UndeclFuncList:
for FuncDecl in FuncDeclList:
if DiffModifier(FuncModifier, DeclModifier) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, FuncName):
PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, 'Function [%s] modifier different with prototype.' % FuncName, '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
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
ErrorMsgList = []
if FileID < 0:
return ErrorMsgList
SqlStatement = """ select BodyStartColumn, EndColumn, ID
from Function
where BelongsToFile = %d
""" % (FileID)
return ErrorMsgList
PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY, 'open brace should be at the very beginning of a line.', 'Function', Result[2])
PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY, 'close brace should be at the very beginning of a line.', 'Function', Result[2])
ErrorMsgList = []
if FileID < 0:
return ErrorMsgList
SqlStatement = """ select ID
from Function
where BelongsToFile = %d
""" % (FileID)
return ErrorMsgList
FL = []
for F in FL:
SqlStatement = """ select Name, Value, ID, Modifier
from %s
where Model = %d and BelongsToFunction = %d
continue
PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_NO_INIT_OF_VARIABLE, 'Variable Name: %s' % Result[0], FileTable, Result[2])
ErrMsgList = []
# Member variable format pattern.
return ErrMsgList
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)
return ErrMsgList
if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, Name):
PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, 'Nested union in [%s].' % (Name), FileTable, TdId)
return ErrMsgList
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
# deal with enum is pre-assigned a value by function call ( , , , ...)
QuoteCount = 0
Index = 0
QuoteCount += 1
Index += 1
continue
QuoteCount -= 1
if QuoteCount == 0:
continue
if QuoteCount == 0:
Index += 1
else:
for Field in FieldsList:
if Field == '':
continue
# For the condition that the field in struct is an array with [] sufixes...
# For the condition that bit field ": Number"
if Field == '':
continue
# Enum could directly assign value to variable
# Remove pointers before variable
return ErrMsgList
ErrorMsgList = []
if FileID < 0:
return ErrorMsgList
SqlStatement = """ select Name, StartLine, EndLine, ID, Value
from %s
where Model = %d
ResultList = []
SqlStatement = """ select Modifier, Name, Value, StartLine, EndLine, ID
from %s
where Model = %d
TdList = []
# Check member variable name format that from typedefs of ONLY this file.
else:
continue
if ValueModelId != ModelId:
continue
# Check member variable format.
for ErrMsg in ErrMsgList:
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])
UntypedefedList = []
for Result in ResultList:
# Check member variable format.
else:
continue
if ValueModelId != ModelId:
continue
for ErrMsg in ErrMsgList:
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])
# Check whether it is typedefed.
# skip function pointer
continue
if Found:
break
if not Found:
continue
return
TdList = []
for F in IncludeFileList:
if FileID < 0:
continue
SqlStatement = """ select Modifier, Name, Value, StartLine, EndLine, ID
from %s
where Model = %d
for Result in UntypedefedList:
# Check whether it is typedefed.
continue
if Found:
break
if not Found:
continue
ErrorMsgList = []
if FileID < 0:
return ErrorMsgList
SqlStatement = """ select Modifier, Name, ID
from %s
where Model = %d
MAX_MODIFIER_LENGTH = 100
for Modifier in ModifierTuple:
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
for Modifier in ModifierTuple:
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
""" % (FileID)
for Modifier in ModifierTuple:
PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER, 'Return Type Modifier %s' % Result[0], FileTable, Result[2])
break
ErrorMsgList = []
if FileID < 0:
return ErrorMsgList
SqlStatement = """ select Modifier, Name, ID
from %s
where Model = %d
for Type in CTypeTuple:
PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, 'Variable type %s' % Type, FileTable, Result[2])
break
SqlStatement = """ select Modifier, Name, ID, Value
from %s
where Model = %d
continue
for Type in CTypeTuple:
PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, '%s Return type %s' % (FuncName, Result[0]), FileTable, Result[2])
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
""" % (FileID)
continue
for Type in CTypeTuple:
PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, '[%s] Return type %s' % (FuncName, Result[0]), FileTable, Result[2])
PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, 'Parameter %s' % Param.Name, FileTable, Result[2])
ErrorMsgList = []
if FileID < 0:
return ErrorMsgList
# cache the found function return type to accelerate later checking in this file.
FuncReturnTypeDict = {}
SqlStatement = """ select Value, StartLine, ID
from %s
where Model = %d
return
PSL = []
SqlStatement = """ select BodyStartLine, EndLine, Header, Modifier, ID
from Function
where BelongsToFile = %d
""" % (FileID)
FL = []
p = GetFuncDeclPattern()
if FuncRecord == None:
continue
if PredInfo[1] == None:
# PredVarStr may contain '.' or '->'
# Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable.
continue
StarList = []
# No variable found, maybe value first? like (0 == VarName)
continue
if SearchInCache:
if Type != None:
PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])
continue
if PredVarStr in FuncReturnTypeDict:
continue
if SearchInCache:
if Type == None:
continue
PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])
ErrorMsgList = []
if FileID < 0:
return ErrorMsgList
# cache the found function return type to accelerate later checking in this file.
FuncReturnTypeDict = {}
SqlStatement = """ select Value, StartLine, ID
from %s
where Model = %d
return
PSL = []
SqlStatement = """ select BodyStartLine, EndLine, Header, Modifier, ID
from Function
where BelongsToFile = %d
""" % (FileID)
FL = []
p = GetFuncDeclPattern()
if FuncRecord == None:
continue
if PredInfo[1] == None:
# PredVarStr may contain '.' or '->'
# Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable.
continue
StarList = []
# No variable found, maybe value first? like (0 == VarName)
continue
if SearchInCache:
if Type != None:
PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR, 'Predicate Expression: %s' % Exp, FileTable, Str[2])
continue
if PredVarStr in FuncReturnTypeDict:
continue
if SearchInCache:
if Type == None:
continue
PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR, 'Predicate Expression: %s' % Exp, FileTable, Str[2])
ErrorMsgList = []
if FileID < 0:
return ErrorMsgList
# cache the found function return type to accelerate later checking in this file.
FuncReturnTypeDict = {}
SqlStatement = """ select Value, StartLine, ID
from %s
where Model = %d
return
PSL = []
SqlStatement = """ select BodyStartLine, EndLine, Header, Modifier, ID
from Function
where BelongsToFile = %d
""" % (FileID)
FL = []
p = GetFuncDeclPattern()
if FuncRecord == None:
continue
# PredVarStr may contain '.' or '->'
# Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable.
continue
StarList = []
# No variable found, maybe value first? like (0 == VarName)
continue
if SearchInCache:
if Type != None:
PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])
continue
if PredVarStr in FuncReturnTypeDict:
continue
if SearchInCache:
if Type == None:
continue
PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])
ErrorMsgList = []
if FileID < 0:
return ErrorMsgList
SqlStatement = """ select ID, Modifier
from %s
where Model = %d
PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_DATA, 'Variable definition appears in header file', FileTable, Result[0])
SqlStatement = """ select ID
from Function
where BelongsToFile = %d
""" % FileID
PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_DATA, 'Function definition appears in header file', 'Function', Result[0])
return ErrorMsgList
ErrorMsgList = []
if FileID < 0:
return ErrorMsgList
SqlStatement = """ select Value, StartLine
from %s
where Model = %d order by StartLine
return ErrorMsgList
SqlStatement = """ select Value, EndLine
from %s
where EndLine < %d
break
SqlStatement = """ select Value
from %s
where StartLine > (select max(EndLine) from %s where Model = %d)
return ErrorMsgList
ErrorMsgList = []
if FileID < 0:
return ErrorMsgList
SqlStatement = """ select Value, ID
from %s
where Model = %d or Model = %d
DoxygenCommandList = ['bug', 'todo', 'example', 'file', 'attention', 'param', 'post', 'pre', 'retval', 'return', 'sa', 'since', 'test', 'note', 'par']
for Part in CommentPartList:
PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Bug should be marked with doxygen tag @bug', FileTable, Result[1])
PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'ToDo should be marked with doxygen tag @todo', FileTable, Result[1])
continue
PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Unknown doxygen command %s' % Part, FileTable, Result[1])
else:
if Index == -1:
PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Unknown doxygen command %s' % Part, FileTable, Result[1])
if RealCmd not in DoxygenCommandList:
PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Unknown doxygen command %s' % Part, FileTable, Result[1])
ErrorMsgList = []
if FileID < 0:
return ErrorMsgList
SqlStatement = """ select ID, BodyStartLine, BodyStartColumn, EndLine, EndColumn
from Function
where BelongsToFile = %d
""" % (FileID)
return
FuncDefSet = []
SqlStatement = """ select Value, ID, StartLine, StartColumn, EndLine, EndColumn
from %s
where Model = %d
CommentSet = []
try:
except:
print 'Unrecognized chars in comment of file %s', FullFileName
for Result in CommentSet:
continue
for FuncDef in FuncDefSet:
if StartLine == FuncDef[1] and StartColumn > FuncDef[2] and EndLine == FuncDef[3] and EndColumn < FuncDef[4]:
break
break
break
break
if Found:
ErrorMsgList = []
if FileID < 0:
return ErrorMsgList
SqlStatement = """ select Value, ID
from %s
where Model = %d and (StartLine = 1 or StartLine = 7 or StartLine = 8) and StartColumn = 0
PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'No File License header appear at the very beginning of file.', 'File', FileID)
return ErrorMsgList
NextLineIndex = 0
CommentStrList = []
# For Mac
# Skip the content before the file header
for CommentLine in CommentStrListTemp:
if FileStartFlag == True:
Index = 0
else:
continue
else:
continue
for CommentLine in CommentStrList:
continue
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)
PrintErrorMsg(ERROR_HEADER_CHECK_FILE, '""All rights reserved"" announcement should be following the ""Copyright"" at the same line', FileTable, ID)
PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'The ""<BR>"" 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():
if RefLine.strip() and (NextLineIndex + 1) < len(CommentStrList) and CommentStrList[NextLineIndex+1].strip() and CommentStrList[NextLineIndex+1].strip().startswith('**/') == 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)
PrintErrorMsg(ERROR_DOXYGEN_CHECK_FILE_HEADER, 'File header comment should begin with ""/** @file""', FileTable, ID)
return
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)
ErrorMsgList = []
if FileID < 0:
return ErrorMsgList
SqlStatement = """ select Value, StartLine, EndLine, ID
from %s
where Model = %d
CommentSet = []
try:
except:
print 'Unrecognized chars in comment of file %s', FullFileName
# Func Decl check
SqlStatement = """ select Modifier, Name, StartLine, ID, Value
from %s
where Model = %d
FunctionHeaderComment = CheckCommentImmediatelyPrecedeFunctionHeader(Result[1], Result[2], CommentSet)
CheckFunctionHeaderConsistentWithDoxygenComment(Result[0], Result[1], Result[2], FunctionHeaderComment[0], FunctionHeaderComment[1], ErrorMsgList, FunctionHeaderComment[3], FileTable)
else:
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
CommentSet = []
try:
except:
print 'Unrecognized chars in comment of file %s', FullFileName
SqlStatement = """ select Modifier, Header, StartLine, ID, Name
from Function
where BelongsToFile = %d
""" % (FileID)
FunctionHeaderComment = CheckCommentImmediatelyPrecedeFunctionHeader(Result[1], Result[2], CommentSet)
CheckFunctionHeaderConsistentWithDoxygenComment(Result[0], Result[1], Result[2], FunctionHeaderComment[0], FunctionHeaderComment[1], ErrorMsgList, FunctionHeaderComment[3], FileTable)
else:
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), 'Function', Result[3])
return ErrorMsgList
for Comment in CommentSet:
return Comment
return None
DoxygenStrList = []
i = 1
while i < len(ParamTagList):
i += 1
i = 1
while i < len(RetvalTagList):
i += 1
i = 1
while i < len(ReturnTagList):
i += 1
return DoxygenStrList
#/** --*/ @retval after @param
PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'Comment does NOT have prefix /** ', TableName, CommentId)
PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'Comment does NOT have tail **/ ', TableName, CommentId)
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=''):
PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMENT_DESCRIPTION, 'Comment description should end with period \'.\'', TableName, CommentId)
ParamNumber -= 1
Index = 0
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 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
InOutStr = ''
for Part in ModifierPartList:
InOutStr += 'in'
if InOutStr != '':
InOutStr += ', out'
else:
InOutStr = 'out'
if InOutStr != '':
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:
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)
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'):
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:
if ParamNumber == 0 and DoxygenTagNumber != 0 and ((FuncModifier.find('VOID') != -1 or FuncModifier.find('void') != -1) and FuncModifier.find('*') == -1):
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)
PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'No doxygen tags in comment ', TableName, CommentId)
if __name__ == '__main__':
# EdkLogger.Initialize()
# EdkLogger.SetLevel(EdkLogger.QUIET)
# CollectSourceCodeDataIntoDB(sys.argv[1])
try:
except IndexError, v:
print Msg
print 'Done!'