2010-02-28 23:39:39 +00:00
## @file
# This file is used to be the c coding style checking of ECC tool
#
2015-06-25 07:43:03 +00:00
# Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
2010-05-18 05:04:32 +00:00
# This program and the accompanying materials
2010-02-28 23:39:39 +00:00
# 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.
#
2009-07-17 09:10:31 +00:00
import sys
2014-08-15 03:06:48 +00:00
import Common.LongFilePathOs as os
2009-07-17 09:10:31 +00:00
import re
import string
import CodeFragmentCollector
import FileProfile
from CommonDataClass import DataClass
import Database
from Common import EdkLogger
from EccToolError import *
import EccGlobalData
import MetaDataParser
IncludeFileListDict = {}
AllIncludeFileListDict = {}
IncludePathListDict = {}
ComplexTypeDict = {}
SUDict = {}
IgnoredKeywordList = [ 'EFI_ERROR' ]
def GetIgnoredDirListPattern ():
skipList = list ( EccGlobalData . gConfig . SkipDirList ) + [ '.svn' ]
DirString = string . join ( skipList , '|' )
p = re . compile ( r '.*[ \\ /](?: %s )[ \\ /]?.*' % DirString )
return p
def GetFuncDeclPattern ():
p = re . compile ( r '(?:EFIAPI|EFI_BOOT_SERVICE|EFI_RUNTIME_SERVICE)?\s*[_\w]+\s*\(.*\)$' , re . DOTALL )
return p
def GetArrayPattern ():
p = re . compile ( r '[_\w]*\s*[\[.*\]]+' )
return p
def GetTypedefFuncPointerPattern ():
p = re . compile ( '[_\w\s]*\([\w\s]*\*+\s*[_\w]+\s*\)\s*\(.*\)' , re . DOTALL )
return p
def GetDB ():
return EccGlobalData . gDb
def GetConfig ():
return EccGlobalData . gConfig
def PrintErrorMsg ( ErrorType , Msg , TableName , ItemId ):
Msg = Msg . replace ( ' \n ' , '' ) . replace ( ' \r ' , '' )
MsgPartList = Msg . split ()
Msg = ''
for Part in MsgPartList :
Msg += Part
Msg += ' '
2011-10-11 02:49:48 +00:00
GetDB () . TblReport . Insert ( ErrorType , OtherMsg = Msg , BelongsToTable = TableName , BelongsToItem = ItemId )
2009-07-17 09:10:31 +00:00
def GetIdType ( Str ):
Type = DataClass . MODEL_UNKNOWN
Str = Str . replace ( '#' , '# ' )
List = Str . split ()
if List [ 1 ] == 'include' :
Type = DataClass . MODEL_IDENTIFIER_INCLUDE
elif List [ 1 ] == 'define' :
Type = DataClass . MODEL_IDENTIFIER_MACRO_DEFINE
elif List [ 1 ] == 'ifdef' :
Type = DataClass . MODEL_IDENTIFIER_MACRO_IFDEF
elif List [ 1 ] == 'ifndef' :
Type = DataClass . MODEL_IDENTIFIER_MACRO_IFNDEF
elif List [ 1 ] == 'endif' :
Type = DataClass . MODEL_IDENTIFIER_MACRO_ENDIF
elif List [ 1 ] == 'pragma' :
Type = DataClass . MODEL_IDENTIFIER_MACRO_PROGMA
else :
Type = DataClass . MODEL_UNKNOWN
return Type
def SuOccurInTypedef ( Su , TdList ):
for Td in TdList :
if Su . StartPos [ 0 ] == Td . StartPos [ 0 ] and Su . EndPos [ 0 ] == Td . EndPos [ 0 ]:
return True
return False
def GetIdentifierList ():
IdList = []
for comment in FileProfile . CommentList :
2011-10-11 02:49:48 +00:00
IdComment = DataClass . IdentifierClass ( - 1 , '' , '' , '' , comment . Content , DataClass . MODEL_IDENTIFIER_COMMENT , - 1 , - 1 , comment . StartPos [ 0 ], comment . StartPos [ 1 ], comment . EndPos [ 0 ], comment . EndPos [ 1 ])
2009-07-17 09:10:31 +00:00
IdList . append ( IdComment )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
for pp in FileProfile . PPDirectiveList :
Type = GetIdType ( pp . Content )
2011-10-11 02:49:48 +00:00
IdPP = DataClass . IdentifierClass ( - 1 , '' , '' , '' , pp . Content , Type , - 1 , - 1 , pp . StartPos [ 0 ], pp . StartPos [ 1 ], pp . EndPos [ 0 ], pp . EndPos [ 1 ])
2009-07-17 09:10:31 +00:00
IdList . append ( IdPP )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
for pe in FileProfile . PredicateExpressionList :
2011-10-11 02:49:48 +00:00
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 ])
2009-07-17 09:10:31 +00:00
IdList . append ( IdPE )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FuncDeclPattern = GetFuncDeclPattern ()
ArrayPattern = GetArrayPattern ()
for var in FileProfile . VariableDeclarationList :
DeclText = var . Declarator . lstrip ()
FuncPointerPattern = GetTypedefFuncPointerPattern ()
if FuncPointerPattern . match ( DeclText ):
continue
VarNameStartLine = var . NameStartPos [ 0 ]
VarNameStartColumn = var . NameStartPos [ 1 ]
FirstChar = DeclText [ 0 ]
while not FirstChar . isalpha () and FirstChar != '_' :
if FirstChar == '*' :
var . Modifier += '*'
VarNameStartColumn += 1
DeclText = DeclText . lstrip ( '*' )
elif FirstChar == ' \r ' :
DeclText = DeclText . lstrip ( ' \r\n ' ) . lstrip ( ' \r ' )
VarNameStartLine += 1
VarNameStartColumn = 0
elif FirstChar == ' \n ' :
DeclText = DeclText . lstrip ( ' \n ' )
VarNameStartLine += 1
VarNameStartColumn = 0
elif FirstChar == ' ' :
DeclText = DeclText . lstrip ( ' ' )
VarNameStartColumn += 1
elif FirstChar == ' \t ' :
DeclText = DeclText . lstrip ( ' \t ' )
VarNameStartColumn += 8
else :
DeclText = DeclText [ 1 :]
VarNameStartColumn += 1
FirstChar = DeclText [ 0 ]
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
var . Declarator = DeclText
if FuncDeclPattern . match ( var . Declarator ):
2010-02-28 23:39:39 +00:00
DeclSplitList = var . Declarator . split ( '(' )
2009-07-17 09:10:31 +00:00
FuncName = DeclSplitList [ 0 ] . strip ()
FuncNamePartList = FuncName . split ()
if len ( FuncNamePartList ) > 1 :
FuncName = FuncNamePartList [ - 1 ] . strip ()
NameStart = DeclSplitList [ 0 ] . rfind ( FuncName )
var . Declarator = var . Declarator [ NameStart :]
if NameStart > 0 :
var . Modifier += ' ' + DeclSplitList [ 0 ][ 0 : NameStart ]
Index = 0
PreChar = ''
while Index < NameStart :
FirstChar = DeclSplitList [ 0 ][ Index ]
if DeclSplitList [ 0 ][ Index :] . startswith ( 'EFIAPI' ):
Index += 6
VarNameStartColumn += 6
PreChar = ''
continue
elif FirstChar == ' \r ' :
Index += 1
VarNameStartLine += 1
VarNameStartColumn = 0
elif FirstChar == ' \n ' :
Index += 1
if PreChar != ' \r ' :
VarNameStartLine += 1
VarNameStartColumn = 0
elif FirstChar == ' ' :
Index += 1
VarNameStartColumn += 1
elif FirstChar == ' \t ' :
Index += 1
VarNameStartColumn += 8
else :
Index += 1
VarNameStartColumn += 1
PreChar = FirstChar
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
2010-02-28 23:39:39 +00:00
if var . Declarator . find ( '{' ) == - 1 :
2009-07-17 09:10:31 +00:00
for decl in var . Declarator . split ( ',' ):
DeclList = decl . split ( '=' )
Name = DeclList [ 0 ] . strip ()
if ArrayPattern . match ( Name ):
LSBPos = var . Declarator . find ( '[' )
var . Modifier += ' ' + Name [ LSBPos :]
Name = Name [ 0 : LSBPos ]
2010-02-28 23:39:39 +00:00
2011-10-11 02:49:48 +00:00
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 )
2009-07-17 09:10:31 +00:00
IdList . append ( IdVar )
else :
DeclList = var . Declarator . split ( '=' )
Name = DeclList [ 0 ] . strip ()
if ArrayPattern . match ( Name ):
LSBPos = var . Declarator . find ( '[' )
var . Modifier += ' ' + Name [ LSBPos :]
Name = Name [ 0 : LSBPos ]
2011-10-11 02:49:48 +00:00
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 )
2009-07-17 09:10:31 +00:00
IdList . append ( IdVar )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
for enum in FileProfile . EnumerationDefinitionList :
LBPos = enum . Content . find ( '{' )
RBPos = enum . Content . find ( '}' )
Name = enum . Content [ 4 : LBPos ] . strip ()
2011-10-11 02:49:48 +00:00
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 ])
2009-07-17 09:10:31 +00:00
IdList . append ( IdEnum )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
for su in FileProfile . StructUnionDefinitionList :
if SuOccurInTypedef ( su , FileProfile . TypedefDefinitionList ):
continue
Type = DataClass . MODEL_IDENTIFIER_STRUCTURE
SkipLen = 6
if su . Content . startswith ( 'union' ):
Type = DataClass . MODEL_IDENTIFIER_UNION
SkipLen = 5
LBPos = su . Content . find ( '{' )
RBPos = su . Content . find ( '}' )
if LBPos == - 1 or RBPos == - 1 :
Name = su . Content [ SkipLen :] . strip ()
Value = ''
else :
Name = su . Content [ SkipLen : LBPos ] . strip ()
2011-10-11 02:49:48 +00:00
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 ])
2009-07-17 09:10:31 +00:00
IdList . append ( IdPE )
2010-02-28 23:39:39 +00:00
TdFuncPointerPattern = GetTypedefFuncPointerPattern ()
2009-07-17 09:10:31 +00:00
for td in FileProfile . TypedefDefinitionList :
Modifier = ''
Name = td . ToType
Value = td . FromType
if TdFuncPointerPattern . match ( td . ToType ):
Modifier = td . FromType
LBPos = td . ToType . find ( '(' )
2011-10-11 02:49:48 +00:00
TmpStr = td . ToType [ LBPos + 1 :] . strip ()
2009-07-17 09:10:31 +00:00
StarPos = TmpStr . find ( '*' )
if StarPos != - 1 :
Modifier += ' ' + TmpStr [ 0 : StarPos ]
while TmpStr [ StarPos ] == '*' :
# Modifier += ' ' + '*'
StarPos += 1
TmpStr = TmpStr [ StarPos :] . strip ()
RBPos = TmpStr . find ( ')' )
Name = TmpStr [ 0 : RBPos ]
Value = 'FP' + TmpStr [ RBPos + 1 :]
else :
while Name . startswith ( '*' ):
Value += ' ' + '*'
Name = Name . lstrip ( '*' ) . strip ()
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
if Name . find ( '[' ) != - 1 :
LBPos = Name . find ( '[' )
RBPos = Name . rfind ( ']' )
Value += Name [ LBPos : RBPos + 1 ]
Name = Name [ 0 : LBPos ]
2010-02-28 23:39:39 +00:00
2011-10-11 02:49:48 +00:00
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 ])
2009-07-17 09:10:31 +00:00
IdList . append ( IdTd )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
for funcCall in FileProfile . FunctionCallingList :
2011-10-11 02:49:48 +00:00
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 ])
2009-07-17 09:10:31 +00:00
IdList . append ( IdFC )
return IdList
def StripNonAlnumChars ( Str ):
StrippedStr = ''
for Char in Str :
if Char . isalnum ():
StrippedStr += Char
return StrippedStr
2011-10-11 02:49:48 +00:00
def GetParamList ( FuncDeclarator , FuncNameLine = 0 , FuncNameOffset = 0 ):
2009-07-17 09:10:31 +00:00
FuncDeclarator = StripComments ( FuncDeclarator )
ParamIdList = []
#DeclSplitList = FuncDeclarator.split('(')
LBPos = FuncDeclarator . find ( '(' )
#if len(DeclSplitList) < 2:
if LBPos == - 1 :
return ParamIdList
#FuncName = DeclSplitList[0]
FuncName = FuncDeclarator [ 0 : LBPos ]
#ParamStr = DeclSplitList[1].rstrip(')')
ParamStr = FuncDeclarator [ LBPos + 1 :] . rstrip ( ')' )
LineSkipped = 0
OffsetSkipped = 0
TailChar = FuncName [ - 1 ]
while not TailChar . isalpha () and TailChar != '_' :
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
if TailChar == ' \n ' :
FuncName = FuncName . rstrip ( ' \r\n ' ) . rstrip ( ' \n ' )
LineSkipped += 1
OffsetSkipped = 0
elif TailChar == ' \r ' :
FuncName = FuncName . rstrip ( ' \r ' )
LineSkipped += 1
OffsetSkipped = 0
elif TailChar == ' ' :
FuncName = FuncName . rstrip ( ' ' )
OffsetSkipped += 1
elif TailChar == ' \t ' :
FuncName = FuncName . rstrip ( ' \t ' )
OffsetSkipped += 8
else :
FuncName = FuncName [: - 1 ]
TailChar = FuncName [ - 1 ]
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
OffsetSkipped += 1 #skip '('
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
for p in ParamStr . split ( ',' ):
ListP = p . split ()
if len ( ListP ) == 0 :
continue
ParamName = ListP [ - 1 ]
DeclText = ParamName . strip ()
RightSpacePos = p . rfind ( ParamName )
ParamModifier = p [ 0 : RightSpacePos ]
if ParamName == 'OPTIONAL' :
if ParamModifier == '' :
ParamModifier += ' ' + 'OPTIONAL'
DeclText = ''
else :
ParamName = ListP [ - 2 ]
DeclText = ParamName . strip ()
RightSpacePos = p . rfind ( ParamName )
ParamModifier = p [ 0 : RightSpacePos ]
ParamModifier += 'OPTIONAL'
while DeclText . startswith ( '*' ):
ParamModifier += ' ' + '*'
DeclText = DeclText . lstrip ( '*' ) . strip ()
ParamName = DeclText
# ignore array length if exists.
LBIndex = ParamName . find ( '[' )
if LBIndex != - 1 :
ParamName = ParamName [ 0 : LBIndex ]
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Start = RightSpacePos
Index = 0
PreChar = ''
while Index < Start :
FirstChar = p [ Index ]
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
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 = FirstChar
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
ParamBeginLine = FuncNameLine + LineSkipped
ParamBeginOffset = FuncNameOffset + OffsetSkipped
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Index = Start + len ( ParamName )
PreChar = ''
while Index < len ( p ):
FirstChar = p [ Index ]
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
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 = FirstChar
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
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 )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
OffsetSkipped += 1 #skip ','
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
return ParamIdList
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
def GetFunctionList ():
FuncObjList = []
for FuncDef in FileProfile . FunctionDefinitionList :
ParamIdList = []
DeclText = FuncDef . Declarator . lstrip ()
FuncNameStartLine = FuncDef . NamePos [ 0 ]
FuncNameStartColumn = FuncDef . NamePos [ 1 ]
FirstChar = DeclText [ 0 ]
while not FirstChar . isalpha () and FirstChar != '_' :
if FirstChar == '*' :
FuncDef . Modifier += '*'
FuncNameStartColumn += 1
DeclText = DeclText . lstrip ( '*' )
elif FirstChar == ' \r ' :
DeclText = DeclText . lstrip ( ' \r\n ' ) . lstrip ( ' \r ' )
FuncNameStartLine += 1
FuncNameStartColumn = 0
elif FirstChar == ' \n ' :
DeclText = DeclText . lstrip ( ' \n ' )
FuncNameStartLine += 1
FuncNameStartColumn = 0
elif FirstChar == ' ' :
DeclText = DeclText . lstrip ( ' ' )
FuncNameStartColumn += 1
elif FirstChar == ' \t ' :
DeclText = DeclText . lstrip ( ' \t ' )
FuncNameStartColumn += 8
else :
DeclText = DeclText [ 1 :]
FuncNameStartColumn += 1
FirstChar = DeclText [ 0 ]
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FuncDef . Declarator = DeclText
DeclSplitList = FuncDef . Declarator . split ( '(' )
if len ( DeclSplitList ) < 2 :
continue
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FuncName = DeclSplitList [ 0 ]
FuncNamePartList = FuncName . split ()
if len ( FuncNamePartList ) > 1 :
FuncName = FuncNamePartList [ - 1 ]
NameStart = DeclSplitList [ 0 ] . rfind ( FuncName )
if NameStart > 0 :
FuncDef . Modifier += ' ' + DeclSplitList [ 0 ][ 0 : NameStart ]
Index = 0
PreChar = ''
while Index < NameStart :
FirstChar = DeclSplitList [ 0 ][ Index ]
if DeclSplitList [ 0 ][ Index :] . startswith ( 'EFIAPI' ):
Index += 6
FuncNameStartColumn += 6
PreChar = ''
continue
elif FirstChar == ' \r ' :
Index += 1
FuncNameStartLine += 1
FuncNameStartColumn = 0
elif FirstChar == ' \n ' :
Index += 1
if PreChar != ' \r ' :
FuncNameStartLine += 1
FuncNameStartColumn = 0
elif FirstChar == ' ' :
Index += 1
FuncNameStartColumn += 1
elif FirstChar == ' \t ' :
Index += 1
FuncNameStartColumn += 8
else :
Index += 1
FuncNameStartColumn += 1
PreChar = FirstChar
2010-02-28 23:39:39 +00:00
2011-10-11 02:49:48 +00:00
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 )
2009-07-17 09:10:31 +00:00
FuncObjList . append ( FuncObj )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
return FuncObjList
def GetFileModificationTimeFromDB ( FullFileName ):
TimeValue = 0.0
Db = GetDB ()
SqlStatement = """ select TimeStamp
from File
where FullPath = \' %s \'
""" % ( FullFileName )
ResultSet = Db . TblFile . Exec ( SqlStatement )
for Result in ResultSet :
TimeValue = Result [ 0 ]
return TimeValue
def CollectSourceCodeDataIntoDB ( RootDir ):
FileObjList = []
tuple = os . walk ( RootDir )
IgnoredPattern = GetIgnoredDirListPattern ()
ParseErrorFileList = []
for dirpath , dirnames , filenames in tuple :
if IgnoredPattern . match ( dirpath . upper ()):
continue
for Dir in dirnames :
Dirname = os . path . join ( dirpath , Dir )
if os . path . islink ( Dirname ):
Dirname = os . path . realpath ( Dirname )
if os . path . isdir ( Dirname ):
# symlinks to directories are treated as directories
dirnames . remove ( Dir )
dirnames . append ( Dirname )
for f in filenames :
2015-06-25 07:43:03 +00:00
if f . lower () in EccGlobalData . gConfig . SkipFileList :
continue
2010-09-06 01:58:00 +00:00
collector = None
2009-07-17 09:10:31 +00:00
FullName = os . path . normpath ( os . path . join ( dirpath , f ))
2010-09-06 01:58:00 +00:00
model = DataClass . MODEL_FILE_OTHERS
2009-07-17 09:10:31 +00:00
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
collector = CodeFragmentCollector . CodeFragmentCollector ( FullName )
try :
collector . ParseFile ()
except UnicodeError :
ParseErrorFileList . append ( FullName )
collector . CleanFileProfileBuffer ()
collector . ParseFileWithClearedPPDirective ()
# collector.PrintFragments()
2010-09-06 01:58:00 +00:00
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 :
2010-02-28 23:39:39 +00:00
collector . CleanFileProfileBuffer ()
2009-07-17 09:10:31 +00:00
if len ( ParseErrorFileList ) > 0 :
EdkLogger . info ( "Found unrecoverable error during parsing: \n\t %s \n " % " \n\t " . join ( ParseErrorFileList ))
2010-02-28 23:39:39 +00:00
Db = GetDB ()
for file in FileObjList :
2010-09-06 01:58:00 +00:00
if file . ExtName . upper () not in [ 'INF' , 'DEC' , 'DSC' , 'FDF' ]:
Db . InsertOneFile ( file )
2009-07-17 09:10:31 +00:00
Db . UpdateIdentifierBelongsToFunction ()
2011-10-11 02:49:48 +00:00
def GetTableID ( FullFileName , ErrorMsgList = None ):
2009-07-17 09:10:31 +00:00
if ErrorMsgList == None :
ErrorMsgList = []
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
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 )
2011-10-11 02:49:48 +00:00
return - 2
2009-07-17 09:10:31 +00:00
FileID = Result [ 0 ]
if FileID == - 1 :
ErrorMsgList . append ( 'NO file ID found in DB for file %s ' % FullFileName )
2011-10-11 02:49:48 +00:00
return - 1
2009-07-17 09:10:31 +00:00
return FileID
def GetIncludeFileList ( FullFileName ):
2010-09-06 01:58:00 +00:00
if os . path . splitext ( FullFileName )[ 1 ] . upper () not in ( '.H' ):
return []
2009-07-17 09:10:31 +00:00
IFList = IncludeFileListDict . get ( FullFileName )
if IFList != None :
return IFList
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FileID = GetTableID ( FullFileName )
if FileID < 0 :
return []
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Db = GetDB ()
FileTable = 'Identifier' + str ( FileID )
SqlStatement = """ select Value
from %s
where Model = %d
""" % ( FileTable , DataClass . MODEL_IDENTIFIER_INCLUDE )
ResultSet = Db . TblFile . Exec ( SqlStatement )
IncludeFileListDict [ FullFileName ] = ResultSet
return ResultSet
def GetFullPathOfIncludeFile ( Str , IncludePathList ):
for IncludePath in IncludePathList :
FullPath = os . path . join ( IncludePath , Str )
FullPath = os . path . normpath ( FullPath )
if os . path . exists ( FullPath ):
return FullPath
return None
def GetAllIncludeFiles ( FullFileName ):
if AllIncludeFileListDict . get ( FullFileName ) != None :
return AllIncludeFileListDict . get ( FullFileName )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FileDirName = os . path . dirname ( FullFileName )
IncludePathList = IncludePathListDict . get ( FileDirName )
if IncludePathList == None :
IncludePathList = MetaDataParser . GetIncludeListOfFile ( EccGlobalData . gWorkspace , FullFileName , GetDB ())
if FileDirName not in IncludePathList :
IncludePathList . insert ( 0 , FileDirName )
IncludePathListDict [ FileDirName ] = IncludePathList
IncludeFileQueue = []
for IncludeFile in GetIncludeFileList ( FullFileName ):
FileName = IncludeFile [ 0 ] . lstrip ( '#' ) . strip ()
FileName = FileName . lstrip ( 'include' ) . strip ()
FileName = FileName . strip ( ' \" ' )
FileName = FileName . lstrip ( '<' ) . rstrip ( '>' ) . strip ()
FullPath = GetFullPathOfIncludeFile ( FileName , IncludePathList )
if FullPath != None :
IncludeFileQueue . append ( FullPath )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
i = 0
while i < len ( IncludeFileQueue ):
for IncludeFile in GetIncludeFileList ( IncludeFileQueue [ i ]):
FileName = IncludeFile [ 0 ] . lstrip ( '#' ) . strip ()
FileName = FileName . lstrip ( 'include' ) . strip ()
FileName = FileName . strip ( ' \" ' )
FileName = FileName . lstrip ( '<' ) . rstrip ( '>' ) . strip ()
FullPath = GetFullPathOfIncludeFile ( FileName , IncludePathList )
if FullPath != None and FullPath not in IncludeFileQueue :
IncludeFileQueue . insert ( i + 1 , FullPath )
i += 1
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
AllIncludeFileListDict [ FullFileName ] = IncludeFileQueue
return IncludeFileQueue
def GetPredicateListFromPredicateExpStr ( PES ):
PredicateList = []
i = 0
PredicateBegin = 0
#PredicateEnd = 0
LogicOpPos = - 1
p = GetFuncDeclPattern ()
while i < len ( PES ) - 1 :
if ( PES [ i ] . isalnum () or PES [ i ] == '_' or PES [ i ] == '*' ) and LogicOpPos > PredicateBegin :
PredicateBegin = i
2011-10-11 02:49:48 +00:00
if ( PES [ i ] == '&' and PES [ i + 1 ] == '&' ) or ( PES [ i ] == '|' and PES [ i + 1 ] == '|' ):
2009-07-17 09:10:31 +00:00
LogicOpPos = i
Exp = PES [ PredicateBegin : i ] . strip ()
# Exp may contain '.' or '->'
TmpExp = Exp . replace ( '.' , '' ) . replace ( '->' , '' )
if p . match ( TmpExp ):
PredicateList . append ( Exp )
else :
PredicateList . append ( Exp . rstrip ( ';' ) . rstrip ( ')' ) . strip ())
i += 1
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
if PredicateBegin > LogicOpPos :
while PredicateBegin < len ( PES ):
if PES [ PredicateBegin ] . isalnum () or PES [ PredicateBegin ] == '_' or PES [ PredicateBegin ] == '*' :
break
PredicateBegin += 1
Exp = PES [ PredicateBegin : len ( PES )] . strip ()
# Exp may contain '.' or '->'
TmpExp = Exp . replace ( '.' , '' ) . replace ( '->' , '' )
if p . match ( TmpExp ):
PredicateList . append ( Exp )
else :
PredicateList . append ( Exp . rstrip ( ';' ) . rstrip ( ')' ) . strip ())
return PredicateList
2010-02-28 23:39:39 +00:00
2011-10-11 02:49:48 +00:00
def GetCNameList ( Lvalue , StarList = []):
2009-07-17 09:10:31 +00:00
Lvalue += ' '
i = 0
SearchBegin = 0
VarStart = - 1
VarEnd = - 1
VarList = []
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
while SearchBegin < len ( Lvalue ):
while i < len ( Lvalue ):
if Lvalue [ i ] . isalnum () or Lvalue [ i ] == '_' :
if VarStart == - 1 :
VarStart = i
VarEnd = i
i += 1
elif VarEnd != - 1 :
2011-10-11 02:49:48 +00:00
VarList . append ( Lvalue [ VarStart : VarEnd + 1 ])
2009-07-17 09:10:31 +00:00
i += 1
break
else :
if VarStart == - 1 and Lvalue [ i ] == '*' :
StarList . append ( '*' )
i += 1
if VarEnd == - 1 :
break
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
DotIndex = Lvalue [ VarEnd :] . find ( '.' )
ArrowIndex = Lvalue [ VarEnd :] . find ( '->' )
if DotIndex == - 1 and ArrowIndex == - 1 :
break
elif DotIndex == - 1 and ArrowIndex != - 1 :
SearchBegin = VarEnd + ArrowIndex
elif ArrowIndex == - 1 and DotIndex != - 1 :
SearchBegin = VarEnd + DotIndex
else :
2010-02-28 23:39:39 +00:00
SearchBegin = VarEnd + (( DotIndex < ArrowIndex ) and DotIndex or ArrowIndex )
2009-07-17 09:10:31 +00:00
i = SearchBegin
VarStart = - 1
VarEnd = - 1
2010-02-28 23:39:39 +00:00
return VarList
2009-07-17 09:10:31 +00:00
2011-10-11 02:49:48 +00:00
def SplitPredicateByOp ( Str , Op , IsFuncCalling = False ):
2009-07-17 09:10:31 +00:00
Name = Str . strip ()
Value = None
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
if IsFuncCalling :
Index = 0
LBFound = False
UnmatchedLBCount = 0
while Index < len ( Str ):
while not LBFound and Str [ Index ] != '_' and not Str [ Index ] . isalnum ():
Index += 1
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
while not LBFound and ( Str [ Index ] . isalnum () or Str [ Index ] == '_' ):
Index += 1
# maybe type-cast at the begining, skip it.
RemainingStr = Str [ Index :] . lstrip ()
if RemainingStr . startswith ( ')' ) and not LBFound :
Index += 1
continue
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
if RemainingStr . startswith ( '(' ) and not LBFound :
LBFound = True
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
if Str [ Index ] == '(' :
UnmatchedLBCount += 1
Index += 1
continue
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
if Str [ Index ] == ')' :
UnmatchedLBCount -= 1
Index += 1
if UnmatchedLBCount == 0 :
break
continue
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Index += 1
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
if UnmatchedLBCount > 0 :
return [ Name ]
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
IndexInRemainingStr = Str [ Index :] . find ( Op )
if IndexInRemainingStr == - 1 :
return [ Name ]
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Name = Str [ 0 : Index + IndexInRemainingStr ] . strip ()
2011-10-11 02:49:48 +00:00
Value = Str [ Index + IndexInRemainingStr + len ( Op ):] . strip () . strip ( ')' )
2009-07-17 09:10:31 +00:00
return [ Name , Value ]
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
TmpStr = Str . rstrip ( ';' ) . rstrip ( ')' )
while True :
Index = TmpStr . rfind ( Op )
if Index == - 1 :
return [ Name ]
2010-02-28 23:39:39 +00:00
2011-10-11 02:49:48 +00:00
if Str [ Index - 1 ] . isalnum () or Str [ Index - 1 ] . isspace () or Str [ Index - 1 ] == ')' or Str [ Index - 1 ] == ']' :
2009-07-17 09:10:31 +00:00
Name = Str [ 0 : Index ] . strip ()
Value = Str [ Index + len ( Op ):] . strip ()
2010-02-28 23:39:39 +00:00
return [ Name , Value ]
2009-07-17 09:10:31 +00:00
TmpStr = Str [ 0 : Index - 1 ]
def SplitPredicateStr ( Str ):
2010-02-28 23:39:39 +00:00
Str = Str . lstrip ( '(' )
2009-07-17 09:10:31 +00:00
IsFuncCalling = False
p = GetFuncDeclPattern ()
TmpStr = Str . replace ( '.' , '' ) . replace ( '->' , '' )
if p . match ( TmpStr ):
IsFuncCalling = True
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
PredPartList = SplitPredicateByOp ( Str , '==' , IsFuncCalling )
if len ( PredPartList ) > 1 :
return [ PredPartList , '==' ]
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
PredPartList = SplitPredicateByOp ( Str , '!=' , IsFuncCalling )
if len ( PredPartList ) > 1 :
return [ PredPartList , '!=' ]
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
PredPartList = SplitPredicateByOp ( Str , '>=' , IsFuncCalling )
if len ( PredPartList ) > 1 :
return [ PredPartList , '>=' ]
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
PredPartList = SplitPredicateByOp ( Str , '<=' , IsFuncCalling )
if len ( PredPartList ) > 1 :
return [ PredPartList , '<=' ]
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
PredPartList = SplitPredicateByOp ( Str , '>' , IsFuncCalling )
if len ( PredPartList ) > 1 :
return [ PredPartList , '>' ]
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
PredPartList = SplitPredicateByOp ( Str , '<' , IsFuncCalling )
if len ( PredPartList ) > 1 :
return [ PredPartList , '<' ]
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
return [[ Str , None ], None ]
def GetFuncContainsPE ( ExpLine , ResultSet ):
for Result in ResultSet :
if Result [ 0 ] < ExpLine and Result [ 1 ] > ExpLine :
return Result
return None
def PatternInModifier ( Modifier , SubStr ):
PartList = Modifier . split ()
for Part in PartList :
if Part == SubStr :
return True
return False
def GetDataTypeFromModifier ( ModifierStr ):
MList = ModifierStr . split ()
ReturnType = ''
for M in MList :
2011-10-11 02:49:48 +00:00
if M in EccGlobalData . gConfig . ModifierList :
continue
# remove array sufix
if M . startswith ( '[' ) or M . endswith ( ']' ):
continue
2009-07-17 09:10:31 +00:00
ReturnType += M + ' '
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
ReturnType = ReturnType . strip ()
if len ( ReturnType ) == 0 :
ReturnType = 'VOID'
return ReturnType
def DiffModifier ( Str1 , Str2 ):
PartList1 = Str1 . split ()
PartList2 = Str2 . split ()
if PartList1 == PartList2 :
return False
else :
return True
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
def GetTypedefDict ( FullFileName ):
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Dict = ComplexTypeDict . get ( FullFileName )
if Dict != None :
return Dict
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FileID = GetTableID ( FullFileName )
FileTable = 'Identifier' + str ( FileID )
Db = GetDB ()
SqlStatement = """ select Modifier, Name, Value, ID
from %s
where Model = %d
""" % ( FileTable , DataClass . MODEL_IDENTIFIER_TYPEDEF )
ResultSet = Db . TblFile . Exec ( SqlStatement )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Dict = {}
for Result in ResultSet :
if len ( Result [ 0 ]) == 0 :
Dict [ Result [ 1 ]] = Result [ 2 ]
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
IncludeFileList = GetAllIncludeFiles ( FullFileName )
for F in IncludeFileList :
FileID = GetTableID ( F )
if FileID < 0 :
continue
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
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 )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
for Result in ResultSet :
if not Result [ 2 ] . startswith ( 'FP (' ):
Dict [ Result [ 1 ]] = Result [ 2 ]
else :
if len ( Result [ 0 ]) == 0 :
Dict [ Result [ 1 ]] = 'VOID'
else :
Dict [ Result [ 1 ]] = GetDataTypeFromModifier ( Result [ 0 ])
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
ComplexTypeDict [ FullFileName ] = Dict
return Dict
def GetSUDict ( FullFileName ):
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Dict = SUDict . get ( FullFileName )
if Dict != None :
return Dict
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FileID = GetTableID ( FullFileName )
FileTable = 'Identifier' + str ( FileID )
Db = GetDB ()
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 )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Dict = {}
for Result in ResultSet :
if len ( Result [ 1 ]) > 0 :
Dict [ Result [ 0 ]] = Result [ 1 ]
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
IncludeFileList = GetAllIncludeFiles ( FullFileName )
for F in IncludeFileList :
FileID = GetTableID ( F )
if FileID < 0 :
continue
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
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 )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
for Result in ResultSet :
if len ( Result [ 1 ]) > 0 :
Dict [ Result [ 0 ]] = Result [ 1 ]
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
SUDict [ FullFileName ] = Dict
return Dict
def StripComments ( Str ):
Str += ' '
ListFromStr = list ( Str )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
InComment = False
DoubleSlashComment = False
Index = 0
while Index < len ( ListFromStr ):
# meet new line, then no longer in a comment for //
if ListFromStr [ Index ] == ' \n ' :
if InComment and DoubleSlashComment :
InComment = False
DoubleSlashComment = False
Index += 1
# check for */ comment end
2011-10-11 02:49:48 +00:00
elif InComment and not DoubleSlashComment and ListFromStr [ Index ] == '*' and ListFromStr [ Index + 1 ] == '/' :
2009-07-17 09:10:31 +00:00
ListFromStr [ Index ] = ' '
Index += 1
ListFromStr [ Index ] = ' '
Index += 1
InComment = False
# set comments to spaces
elif InComment :
ListFromStr [ Index ] = ' '
Index += 1
# check for // comment
2011-10-11 02:49:48 +00:00
elif ListFromStr [ Index ] == '/' and ListFromStr [ Index + 1 ] == '/' and ListFromStr [ Index + 2 ] != ' \n ' :
2009-07-17 09:10:31 +00:00
InComment = True
DoubleSlashComment = True
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
# check for /* comment start
2011-10-11 02:49:48 +00:00
elif ListFromStr [ Index ] == '/' and ListFromStr [ Index + 1 ] == '*' :
2009-07-17 09:10:31 +00:00
ListFromStr [ Index ] = ' '
Index += 1
ListFromStr [ Index ] = ' '
Index += 1
InComment = True
else :
Index += 1
# restore from List to String
Str = "" . join ( ListFromStr )
Str = Str . rstrip ( ' ' )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
return Str
def GetFinalTypeValue ( Type , FieldName , TypedefDict , SUDict ):
Value = TypedefDict . get ( Type )
if Value == None :
Value = SUDict . get ( Type )
if Value == None :
return None
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
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 :
Value = SUDict . get ( FT )
break
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
if Value == None :
return None
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
LBPos = Value . find ( '{' )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
# RBPos = Value.find('}')
Fields = Value [ LBPos + 1 :]
Fields = StripComments ( Fields )
FieldsList = Fields . split ( ';' )
for Field in FieldsList :
Field = Field . strip ()
Index = Field . rfind ( FieldName )
if Index < 1 :
continue
if not Field [ Index - 1 ] . isalnum ():
if Index + len ( FieldName ) == len ( Field ):
Type = GetDataTypeFromModifier ( Field [ 0 : Index ])
return Type . strip ()
else :
2010-02-28 23:39:39 +00:00
# For the condition that the field in struct is an array with [] sufixes...
2009-07-17 09:10:31 +00:00
if not Field [ Index + len ( FieldName )] . isalnum ():
Type = GetDataTypeFromModifier ( Field [ 0 : Index ])
return Type . strip ()
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
return None
2010-02-28 23:39:39 +00:00
2011-10-11 02:49:48 +00:00
def GetRealType ( Type , TypedefDict , TargetType = None ):
2009-07-17 09:10:31 +00:00
if TargetType != None and Type == TargetType :
return Type
while TypedefDict . get ( Type ):
Type = TypedefDict . get ( Type )
if TargetType != None and Type == TargetType :
return Type
return Type
2011-10-11 02:49:48 +00:00
def GetTypeInfo ( RefList , Modifier , FullFileName , TargetType = None ):
2009-07-17 09:10:31 +00:00
TypedefDict = GetTypedefDict ( FullFileName )
SUDict = GetSUDict ( FullFileName )
Type = GetDataTypeFromModifier ( Modifier ) . replace ( '*' , '' ) . strip ()
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Type = Type . split ()[ - 1 ]
Index = 0
while Index < len ( RefList ):
FieldName = RefList [ Index ]
FromType = GetFinalTypeValue ( Type , FieldName , TypedefDict , SUDict )
if FromType == None :
return None
# we want to determine the exact type.
if TargetType != None :
Type = FromType . split ()[ 0 ]
# we only want to check if it is a pointer
else :
Type = FromType
2011-10-11 02:49:48 +00:00
if Type . find ( '*' ) != - 1 and Index == len ( RefList ) - 1 :
2009-07-17 09:10:31 +00:00
return Type
Type = FromType . split ()[ 0 ]
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Index += 1
Type = GetRealType ( Type , TypedefDict , TargetType )
return Type
2011-10-11 02:49:48 +00:00
def GetVarInfo ( PredVarList , FuncRecord , FullFileName , IsFuncCall = False , TargetType = None , StarList = None ):
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
PredVar = PredVarList [ 0 ]
FileID = GetTableID ( FullFileName )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Db = GetDB ()
FileTable = 'Identifier' + str ( FileID )
# search variable in include files
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
# it is a function call, search function declarations and definitions
if IsFuncCall :
SqlStatement = """ select Modifier, ID
from %s
where Model = %d and Value = \' %s \'
""" % ( FileTable , DataClass . MODEL_IDENTIFIER_FUNCTION_DECLARATION , PredVar )
ResultSet = Db . TblFile . Exec ( SqlStatement )
2010-02-28 23:39:39 +00:00
for Result in ResultSet :
2009-07-17 09:10:31 +00:00
Type = GetDataTypeFromModifier ( Result [ 0 ]) . split ()[ - 1 ]
TypedefDict = GetTypedefDict ( FullFileName )
Type = GetRealType ( Type , TypedefDict , TargetType )
return Type
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
IncludeFileList = GetAllIncludeFiles ( FullFileName )
for F in IncludeFileList :
FileID = GetTableID ( F )
if FileID < 0 :
continue
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
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 )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
for Result in ResultSet :
Type = GetDataTypeFromModifier ( Result [ 0 ]) . split ()[ - 1 ]
TypedefDict = GetTypedefDict ( FullFileName )
Type = GetRealType ( Type , TypedefDict , TargetType )
return Type
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FileID = GetTableID ( FullFileName )
SqlStatement = """ select Modifier, ID
from Function
where BelongsToFile = %d and Name = \' %s \'
""" % ( FileID , PredVar )
ResultSet = Db . TblFile . Exec ( SqlStatement )
2010-02-28 23:39:39 +00:00
for Result in ResultSet :
2009-07-17 09:10:31 +00:00
Type = GetDataTypeFromModifier ( Result [ 0 ]) . split ()[ - 1 ]
TypedefDict = GetTypedefDict ( FullFileName )
Type = GetRealType ( Type , TypedefDict , TargetType )
return Type
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
for F in IncludeFileList :
FileID = GetTableID ( F )
if FileID < 0 :
continue
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FileTable = 'Identifier' + str ( FileID )
SqlStatement = """ select Modifier, ID
from Function
where BelongsToFile = %d and Name = \' %s \'
""" % ( FileID , PredVar )
ResultSet = Db . TblFile . Exec ( SqlStatement )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
for Result in ResultSet :
Type = GetDataTypeFromModifier ( Result [ 0 ]) . split ()[ - 1 ]
TypedefDict = GetTypedefDict ( FullFileName )
Type = GetRealType ( Type , TypedefDict , TargetType )
return Type
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
return None
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
# really variable, search local variable first
SqlStatement = """ select Modifier, ID
from %s
where Model = %d and Name = \' %s \' and StartLine >= %d and StartLine <= %d
""" % ( FileTable , DataClass . MODEL_IDENTIFIER_VARIABLE , PredVar , FuncRecord [ 0 ], FuncRecord [ 1 ])
ResultSet = Db . TblFile . Exec ( SqlStatement )
VarFound = False
for Result in ResultSet :
if len ( PredVarList ) > 1 :
Type = GetTypeInfo ( PredVarList [ 1 :], Result [ 0 ], FullFileName , TargetType )
return Type
else :
# Type = GetDataTypeFromModifier(Result[0]).split()[-1]
TypeList = GetDataTypeFromModifier ( Result [ 0 ]) . split ()
Type = TypeList [ - 1 ]
if len ( TypeList ) > 1 and StarList != None :
for Star in StarList :
Type = Type . strip ()
Type = Type . rstrip ( Star )
# Get real type after de-reference pointers.
if len ( Type . strip ()) == 0 :
Type = TypeList [ - 2 ]
TypedefDict = GetTypedefDict ( FullFileName )
Type = GetRealType ( Type , TypedefDict , TargetType )
return Type
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
# search function parameters second
ParamList = GetParamList ( FuncRecord [ 2 ])
for Param in ParamList :
if Param . Name . strip () == PredVar :
if len ( PredVarList ) > 1 :
Type = GetTypeInfo ( PredVarList [ 1 :], Param . Modifier , FullFileName , TargetType )
return Type
else :
TypeList = GetDataTypeFromModifier ( Param . Modifier ) . split ()
Type = TypeList [ - 1 ]
2015-06-25 08:10:51 +00:00
if Type == '*' and len ( TypeList ) >= 2 :
Type = TypeList [ - 2 ]
2009-07-17 09:10:31 +00:00
if len ( TypeList ) > 1 and StarList != None :
for Star in StarList :
Type = Type . strip ()
Type = Type . rstrip ( Star )
# Get real type after de-reference pointers.
if len ( Type . strip ()) == 0 :
Type = TypeList [ - 2 ]
TypedefDict = GetTypedefDict ( FullFileName )
Type = GetRealType ( Type , TypedefDict , TargetType )
return Type
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
# search global variable next
SqlStatement = """ select Modifier, ID
from %s
where Model = %d and Name = \' %s \' and BelongsToFunction = -1
""" % ( FileTable , DataClass . MODEL_IDENTIFIER_VARIABLE , PredVar )
ResultSet = Db . TblFile . Exec ( SqlStatement )
for Result in ResultSet :
if len ( PredVarList ) > 1 :
Type = GetTypeInfo ( PredVarList [ 1 :], Result [ 0 ], FullFileName , TargetType )
return Type
else :
TypeList = GetDataTypeFromModifier ( Result [ 0 ]) . split ()
Type = TypeList [ - 1 ]
if len ( TypeList ) > 1 and StarList != None :
for Star in StarList :
Type = Type . strip ()
Type = Type . rstrip ( Star )
# Get real type after de-reference pointers.
if len ( Type . strip ()) == 0 :
Type = TypeList [ - 2 ]
TypedefDict = GetTypedefDict ( FullFileName )
Type = GetRealType ( Type , TypedefDict , TargetType )
return Type
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
IncludeFileList = GetAllIncludeFiles ( FullFileName )
for F in IncludeFileList :
FileID = GetTableID ( F )
if FileID < 0 :
continue
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FileTable = 'Identifier' + str ( FileID )
SqlStatement = """ select Modifier, ID
from %s
where Model = %d and BelongsToFunction = -1 and Name = \' %s \'
""" % ( FileTable , DataClass . MODEL_IDENTIFIER_VARIABLE , PredVar )
ResultSet = Db . TblFile . Exec ( SqlStatement )
for Result in ResultSet :
if len ( PredVarList ) > 1 :
Type = GetTypeInfo ( PredVarList [ 1 :], Result [ 0 ], FullFileName , TargetType )
return Type
else :
TypeList = GetDataTypeFromModifier ( Result [ 0 ]) . split ()
Type = TypeList [ - 1 ]
if len ( TypeList ) > 1 and StarList != None :
for Star in StarList :
Type = Type . strip ()
Type = Type . rstrip ( Star )
# Get real type after de-reference pointers.
if len ( Type . strip ()) == 0 :
Type = TypeList [ - 2 ]
TypedefDict = GetTypedefDict ( FullFileName )
Type = GetRealType ( Type , TypedefDict , TargetType )
return Type
2010-02-28 23:39:39 +00:00
def GetTypeFromArray ( Type , Var ):
Count = Var . count ( '[' )
while Count > 0 :
Type = Type . strip ()
Type = Type . rstrip ( '*' )
Count = Count - 1
return Type
2009-07-17 09:10:31 +00:00
def CheckFuncLayoutReturnType ( FullFileName ):
ErrorMsgList = []
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FileID = GetTableID ( FullFileName , ErrorMsgList )
if FileID < 0 :
return ErrorMsgList
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Db = GetDB ()
FileTable = 'Identifier' + str ( FileID )
2010-02-28 23:39:39 +00:00
SqlStatement = """ select Modifier, ID, StartLine, StartColumn, EndLine, Value
2009-07-17 09:10:31 +00:00
from %s
where Model = %d
""" % ( FileTable , DataClass . MODEL_IDENTIFIER_FUNCTION_DECLARATION )
ResultSet = Db . TblFile . Exec ( SqlStatement )
for Result in ResultSet :
ReturnType = GetDataTypeFromModifier ( Result [ 0 ])
TypeStart = ReturnType . split ()[ 0 ]
FuncName = Result [ 5 ]
if EccGlobalData . gException . IsException ( ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE , FuncName ):
continue
2015-09-14 07:12:29 +00:00
Result0 = Result [ 0 ]
if Result0 . upper () . startswith ( 'STATIC' ):
Result0 = Result0 [ 6 :] . strip ()
Index = Result0 . find ( TypeStart )
2009-07-17 09:10:31 +00:00
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 ])
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
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 ])
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
SqlStatement = """ select Modifier, ID, StartLine, StartColumn, FunNameStartLine, Name
from Function
where BelongsToFile = %d
""" % ( FileID )
ResultSet = Db . TblFile . Exec ( SqlStatement )
for Result in ResultSet :
ReturnType = GetDataTypeFromModifier ( Result [ 0 ])
TypeStart = ReturnType . split ()[ 0 ]
FuncName = Result [ 5 ]
if EccGlobalData . gException . IsException ( ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE , FuncName ):
continue
2015-08-24 02:53:27 +00:00
Result0 = Result [ 0 ]
if Result0 . upper () . startswith ( 'STATIC' ):
Result0 = Result0 [ 6 :] . strip ()
Index = Result0 . find ( ReturnType )
2009-07-17 09:10:31 +00:00
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 ])
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
def CheckFuncLayoutModifier ( FullFileName ):
ErrorMsgList = []
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FileID = GetTableID ( FullFileName , ErrorMsgList )
if FileID < 0 :
return ErrorMsgList
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Db = GetDB ()
FileTable = 'Identifier' + str ( FileID )
SqlStatement = """ select Modifier, ID
from %s
where Model = %d
""" % ( FileTable , DataClass . MODEL_IDENTIFIER_FUNCTION_DECLARATION )
ResultSet = Db . TblFile . Exec ( SqlStatement )
for Result in ResultSet :
ReturnType = GetDataTypeFromModifier ( Result [ 0 ])
TypeStart = ReturnType . split ()[ 0 ]
2015-09-14 07:12:29 +00:00
Result0 = Result [ 0 ]
if Result0 . upper () . startswith ( 'STATIC' ):
Result0 = Result0 [ 6 :] . strip ()
Index = Result0 . find ( TypeStart )
2009-07-17 09:10:31 +00:00
if Index != 0 :
PrintErrorMsg ( ERROR_C_FUNCTION_LAYOUT_CHECK_OPTIONAL_FUNCTIONAL_MODIFIER , '' , FileTable , Result [ 1 ])
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
SqlStatement = """ select Modifier, ID
from Function
where BelongsToFile = %d
""" % ( FileID )
ResultSet = Db . TblFile . Exec ( SqlStatement )
for Result in ResultSet :
ReturnType = GetDataTypeFromModifier ( Result [ 0 ])
TypeStart = ReturnType . split ()[ 0 ]
2015-08-24 02:53:27 +00:00
Result0 = Result [ 0 ]
if Result0 . upper () . startswith ( 'STATIC' ):
Result0 = Result0 [ 6 :] . strip ()
Index = Result0 . find ( TypeStart )
2009-07-17 09:10:31 +00:00
if Index != 0 :
PrintErrorMsg ( ERROR_C_FUNCTION_LAYOUT_CHECK_OPTIONAL_FUNCTIONAL_MODIFIER , '' , 'Function' , Result [ 1 ])
def CheckFuncLayoutName ( FullFileName ):
ErrorMsgList = []
# Parameter variable format pattern.
Pattern = re . compile ( r '^[A-Z]+\S*[a-z]\S*$' )
ParamIgnoreList = ( 'VOID' , '...' )
FileID = GetTableID ( FullFileName , ErrorMsgList )
if FileID < 0 :
return ErrorMsgList
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Db = GetDB ()
FileTable = 'Identifier' + str ( FileID )
SqlStatement = """ select Name, ID, EndColumn, Value
from %s
where Model = %d
""" % ( FileTable , DataClass . MODEL_IDENTIFIER_FUNCTION_DECLARATION )
ResultSet = Db . TblFile . Exec ( SqlStatement )
for Result in ResultSet :
FuncName = Result [ 3 ]
if EccGlobalData . gException . IsException ( ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME , FuncName ):
continue
if Result [ 2 ] != 0 :
PrintErrorMsg ( ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME , 'Function name [ %s ] should appear at the start of a line' % FuncName , FileTable , Result [ 1 ])
ParamList = GetParamList ( Result [ 0 ])
if len ( ParamList ) == 0 :
continue
StartLine = 0
for Param in ParamList :
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 :
2010-02-28 23:39:39 +00:00
PrintErrorMsg ( ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME , 'Empty line appears before Parameter %s .' % Param . Name , FileTable , Result [ 1 ])
2009-07-17 09:10:31 +00:00
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
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
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 ])
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
SqlStatement = """ select Modifier, ID, FunNameStartColumn, Name
from Function
where BelongsToFile = %d
""" % ( FileID )
ResultSet = Db . TblFile . Exec ( SqlStatement )
for Result in ResultSet :
FuncName = Result [ 3 ]
if EccGlobalData . gException . IsException ( ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME , FuncName ):
continue
if Result [ 2 ] != 0 :
PrintErrorMsg ( ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME , 'Function name [ %s ] should appear at the start of a line' % FuncName , 'Function' , Result [ 1 ])
ParamList = GetParamList ( Result [ 0 ])
if len ( ParamList ) == 0 :
continue
StartLine = 0
for Param in ParamList :
if Param . StartLine <= StartLine :
PrintErrorMsg ( ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME , 'Parameter %s should be in its own line.' % Param . Name , 'Function' , Result [ 1 ])
if Param . StartLine - StartLine > 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 ])
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' , 'Function' , Result [ 1 ])
def CheckFuncLayoutPrototype ( FullFileName ):
ErrorMsgList = []
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FileID = GetTableID ( FullFileName , ErrorMsgList )
if FileID < 0 :
return ErrorMsgList
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FileTable = 'Identifier' + str ( FileID )
Db = GetDB ()
SqlStatement = """ select Modifier, Header, Name, ID
from Function
where BelongsToFile = %d
""" % ( FileID )
ResultSet = Db . TblFile . Exec ( SqlStatement )
if len ( ResultSet ) == 0 :
return ErrorMsgList
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FuncDefList = []
for Result in ResultSet :
FuncDefList . append ( Result )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
SqlStatement = """ select Modifier, Name, ID
from %s
where Model = %d
""" % ( FileTable , DataClass . MODEL_IDENTIFIER_FUNCTION_DECLARATION )
ResultSet = Db . TblFile . Exec ( SqlStatement )
FuncDeclList = []
for Result in ResultSet :
FuncDeclList . append ( Result )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
UndeclFuncList = []
for FuncDef in FuncDefList :
FuncName = FuncDef [ 2 ] . strip ()
FuncModifier = FuncDef [ 0 ]
FuncDefHeader = FuncDef [ 1 ]
for FuncDecl in FuncDeclList :
LBPos = FuncDecl [ 1 ] . find ( '(' )
DeclName = FuncDecl [ 1 ][ 0 : LBPos ] . strip ()
DeclModifier = FuncDecl [ 0 ]
if DeclName == FuncName :
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 ])
ParamListOfDef = GetParamList ( FuncDefHeader )
ParamListOfDecl = GetParamList ( FuncDecl [ 1 ])
2010-02-28 23:39:39 +00:00
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 ])
2009-07-17 09:10:31 +00:00
break
Index = 0
while Index < len ( ParamListOfDef ):
2010-02-28 23:39:39 +00:00
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 ])
2009-07-17 09:10:31 +00:00
Index += 1
break
else :
UndeclFuncList . append ( FuncDef )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
IncludeFileList = GetAllIncludeFiles ( FullFileName )
FuncDeclList = []
for F in IncludeFileList :
FileID = GetTableID ( F , ErrorMsgList )
if FileID < 0 :
continue
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FileTable = 'Identifier' + str ( FileID )
SqlStatement = """ select Modifier, Name, ID
from %s
where Model = %d
""" % ( FileTable , DataClass . MODEL_IDENTIFIER_FUNCTION_DECLARATION )
ResultSet = Db . TblFile . Exec ( SqlStatement )
for Result in ResultSet :
FuncDeclList . append ( Result )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
for FuncDef in UndeclFuncList :
FuncName = FuncDef [ 2 ] . strip ()
FuncModifier = FuncDef [ 0 ]
FuncDefHeader = FuncDef [ 1 ]
for FuncDecl in FuncDeclList :
LBPos = FuncDecl [ 1 ] . find ( '(' )
DeclName = FuncDecl [ 1 ][ 0 : LBPos ] . strip ()
DeclModifier = FuncDecl [ 0 ]
if DeclName == FuncName :
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 ])
ParamListOfDef = GetParamList ( FuncDefHeader )
ParamListOfDecl = GetParamList ( FuncDecl [ 1 ])
2010-02-28 23:39:39 +00:00
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 ])
2009-07-17 09:10:31 +00:00
break
Index = 0
while Index < len ( ParamListOfDef ):
2010-02-28 23:39:39 +00:00
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 ])
2009-07-17 09:10:31 +00:00
Index += 1
break
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
def CheckFuncLayoutBody ( FullFileName ):
ErrorMsgList = []
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FileID = GetTableID ( FullFileName , ErrorMsgList )
if FileID < 0 :
return ErrorMsgList
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FileTable = 'Identifier' + str ( FileID )
Db = GetDB ()
SqlStatement = """ select BodyStartColumn, EndColumn, ID
from Function
where BelongsToFile = %d
""" % ( FileID )
ResultSet = Db . TblFile . Exec ( SqlStatement )
if len ( ResultSet ) == 0 :
return ErrorMsgList
for Result in ResultSet :
if Result [ 0 ] != 0 :
PrintErrorMsg ( ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY , 'open brace should be at the very beginning of a line.' , 'Function' , Result [ 2 ])
if Result [ 1 ] != 0 :
PrintErrorMsg ( ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY , 'close brace should be at the very beginning of a line.' , 'Function' , Result [ 2 ])
def CheckFuncLayoutLocalVariable ( FullFileName ):
ErrorMsgList = []
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FileID = GetTableID ( FullFileName , ErrorMsgList )
if FileID < 0 :
return ErrorMsgList
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Db = GetDB ()
FileTable = 'Identifier' + str ( FileID )
SqlStatement = """ select ID
from Function
where BelongsToFile = %d
""" % ( FileID )
ResultSet = Db . TblFile . Exec ( SqlStatement )
if len ( ResultSet ) == 0 :
return ErrorMsgList
FL = []
for Result in ResultSet :
FL . append ( Result )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
for F in FL :
2011-10-11 02:49:48 +00:00
SqlStatement = """ select Name, Value, ID, Modifier
2009-07-17 09:10:31 +00:00
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
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
for Result in ResultSet :
2011-10-11 02:49:48 +00:00
if len ( Result [ 1 ]) > 0 and 'CONST' not in Result [ 3 ]:
2009-07-17 09:10:31 +00:00
PrintErrorMsg ( ERROR_C_FUNCTION_LAYOUT_CHECK_NO_INIT_OF_VARIABLE , 'Variable Name: %s ' % Result [ 0 ], FileTable , Result [ 2 ])
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
def CheckMemberVariableFormat ( Name , Value , FileTable , TdId , ModelId ):
ErrMsgList = []
# Member variable format pattern.
Pattern = re . compile ( r '^[A-Z]+\S*[a-z]\S*$' )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
LBPos = Value . find ( '{' )
RBPos = Value . rfind ( '}' )
if LBPos == - 1 or RBPos == - 1 :
return ErrMsgList
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Fields = Value [ LBPos + 1 : RBPos ]
Fields = StripComments ( Fields ) . strip ()
NestPos = Fields . find ( 'struct' )
if NestPos != - 1 and ( NestPos + len ( 'struct' ) < len ( Fields )):
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 )
return ErrMsgList
NestPos = Fields . find ( 'union' )
if NestPos != - 1 and ( NestPos + len ( 'union' ) < len ( Fields )):
if not Fields [ NestPos + len ( 'union' ) + 1 ] . isalnum ():
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
NestPos = Fields . find ( 'enum' )
if NestPos != - 1 and ( NestPos + len ( 'enum' ) < len ( Fields )):
if not Fields [ NestPos + len ( 'enum' ) + 1 ] . isalnum ():
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
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
if ModelId == DataClass . MODEL_IDENTIFIER_ENUMERATE :
FieldsList = Fields . split ( ',' )
# deal with enum is pre-assigned a value by function call ( , , , ...)
QuoteCount = 0
Index = 0
RemoveCurrentElement = False
while Index < len ( FieldsList ):
Field = FieldsList [ Index ]
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
if Field . find ( '(' ) != - 1 :
QuoteCount += 1
RemoveCurrentElement = True
Index += 1
continue
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
if Field . find ( ')' ) != - 1 and QuoteCount > 0 :
QuoteCount -= 1
2010-02-28 23:39:39 +00:00
if RemoveCurrentElement :
2009-07-17 09:10:31 +00:00
FieldsList . remove ( Field )
if QuoteCount == 0 :
RemoveCurrentElement = False
continue
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
if QuoteCount == 0 :
RemoveCurrentElement = False
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Index += 1
else :
FieldsList = Fields . split ( ';' )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
for Field in FieldsList :
Field = Field . strip ()
if Field == '' :
continue
2010-02-28 23:39:39 +00:00
# For the condition that the field in struct is an array with [] sufixes...
2009-07-17 09:10:31 +00:00
if Field [ - 1 ] == ']' :
LBPos = Field . find ( '[' )
Field = Field [ 0 : LBPos ]
# For the condition that bit field ": Number"
if Field . find ( ':' ) != - 1 :
ColonPos = Field . find ( ':' )
Field = Field [ 0 : ColonPos ]
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Field = Field . strip ()
if Field == '' :
continue
2015-09-14 07:12:29 +00:00
if Field . startswith ( "#" ):
continue
2009-07-17 09:10:31 +00:00
# Enum could directly assign value to variable
Field = Field . split ( '=' )[ 0 ] . strip ()
2010-02-28 23:39:39 +00:00
TokenList = Field . split ()
2009-07-17 09:10:31 +00:00
# Remove pointers before variable
2015-07-02 06:02:42 +00:00
Token = TokenList [ - 1 ]
if Token in [ 'OPTIONAL' ]:
Token = TokenList [ - 2 ]
if not Pattern . match ( Token . lstrip ( '*' )):
ErrMsgList . append ( Token . lstrip ( '*' ))
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
return ErrMsgList
def CheckDeclTypedefFormat ( FullFileName , ModelId ):
ErrorMsgList = []
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FileID = GetTableID ( FullFileName , ErrorMsgList )
if FileID < 0 :
return ErrorMsgList
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Db = GetDB ()
FileTable = 'Identifier' + str ( FileID )
SqlStatement = """ select Name, StartLine, EndLine, ID, Value
from %s
where Model = %d
""" % ( FileTable , ModelId )
ResultSet = Db . TblFile . Exec ( SqlStatement )
ResultList = []
for Result in ResultSet :
ResultList . append ( Result )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_ALL
if ModelId == DataClass . MODEL_IDENTIFIER_STRUCTURE :
ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_STRUCTURE_DECLARATION
elif ModelId == DataClass . MODEL_IDENTIFIER_ENUMERATE :
ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_ENUMERATED_TYPE
elif ModelId == DataClass . MODEL_IDENTIFIER_UNION :
ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_UNION_TYPE
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
SqlStatement = """ select Modifier, Name, Value, StartLine, EndLine, ID
from %s
where Model = %d
""" % ( FileTable , DataClass . MODEL_IDENTIFIER_TYPEDEF )
TdSet = Db . TblFile . Exec ( SqlStatement )
TdList = []
for Td in TdSet :
TdList . append ( Td )
# Check member variable name format that from typedefs of ONLY this file.
for Td in TdList :
Name = Td [ 1 ] . strip ()
Value = Td [ 2 ] . strip ()
if Value . startswith ( 'enum' ):
ValueModelId = DataClass . MODEL_IDENTIFIER_ENUMERATE
elif Value . startswith ( 'struct' ):
ValueModelId = DataClass . MODEL_IDENTIFIER_STRUCTURE
elif Value . startswith ( 'union' ):
ValueModelId = DataClass . MODEL_IDENTIFIER_UNION
else :
continue
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
if ValueModelId != ModelId :
continue
# Check member variable format.
ErrMsgList = CheckMemberVariableFormat ( Name , Value , FileTable , Td [ 5 ], ModelId )
for ErrMsg in ErrMsgList :
2011-10-11 02:49:48 +00:00
if EccGlobalData . gException . IsException ( ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME , Name + '.' + ErrMsg ):
2009-07-17 09:10:31 +00:00
continue
2011-10-11 02:49:48 +00:00
PrintErrorMsg ( ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME , 'Member variable [ %s ] NOT follow naming convention.' % ( Name + '.' + ErrMsg ), FileTable , Td [ 5 ])
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
# First check in current file to see whether struct/union/enum is typedef-ed.
UntypedefedList = []
for Result in ResultList :
# Check member variable format.
Name = Result [ 0 ] . strip ()
Value = Result [ 4 ] . strip ()
if Value . startswith ( 'enum' ):
ValueModelId = DataClass . MODEL_IDENTIFIER_ENUMERATE
elif Value . startswith ( 'struct' ):
ValueModelId = DataClass . MODEL_IDENTIFIER_STRUCTURE
elif Value . startswith ( 'union' ):
ValueModelId = DataClass . MODEL_IDENTIFIER_UNION
else :
continue
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
if ValueModelId != ModelId :
continue
ErrMsgList = CheckMemberVariableFormat ( Name , Value , FileTable , Result [ 3 ], ModelId )
for ErrMsg in ErrMsgList :
2011-10-11 02:49:48 +00:00
if EccGlobalData . gException . IsException ( ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME , Result [ 0 ] + '.' + ErrMsg ):
2009-07-17 09:10:31 +00:00
continue
2011-10-11 02:49:48 +00:00
PrintErrorMsg ( ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME , 'Member variable [ %s ] NOT follow naming convention.' % ( Result [ 0 ] + '.' + ErrMsg ), FileTable , Result [ 3 ])
2009-07-17 09:10:31 +00:00
# Check whether it is typedefed.
Found = False
for Td in TdList :
# skip function pointer
if len ( Td [ 0 ]) > 0 :
continue
if Result [ 1 ] >= Td [ 3 ] and Td [ 4 ] >= Result [ 2 ]:
Found = True
if not Td [ 1 ] . isupper ():
PrintErrorMsg ( ErrorType , 'Typedef should be UPPER case' , FileTable , Td [ 5 ])
if Result [ 0 ] in Td [ 2 ] . split ():
Found = True
if not Td [ 1 ] . isupper ():
PrintErrorMsg ( ErrorType , 'Typedef should be UPPER case' , FileTable , Td [ 5 ])
if Found :
break
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
if not Found :
UntypedefedList . append ( Result )
continue
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
if len ( UntypedefedList ) == 0 :
return
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
IncludeFileList = GetAllIncludeFiles ( FullFileName )
TdList = []
for F in IncludeFileList :
FileID = GetTableID ( F , ErrorMsgList )
if FileID < 0 :
continue
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
IncludeFileTable = 'Identifier' + str ( FileID )
SqlStatement = """ select Modifier, Name, Value, StartLine, EndLine, ID
from %s
where Model = %d
""" % ( IncludeFileTable , DataClass . MODEL_IDENTIFIER_TYPEDEF )
ResultSet = Db . TblFile . Exec ( SqlStatement )
TdList . extend ( ResultSet )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
for Result in UntypedefedList :
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
# Check whether it is typedefed.
Found = False
for Td in TdList :
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
if len ( Td [ 0 ]) > 0 :
continue
if Result [ 1 ] >= Td [ 3 ] and Td [ 4 ] >= Result [ 2 ]:
Found = True
if not Td [ 1 ] . isupper ():
PrintErrorMsg ( ErrorType , 'Typedef should be UPPER case' , FileTable , Td [ 5 ])
if Result [ 0 ] in Td [ 2 ] . split ():
Found = True
if not Td [ 1 ] . isupper ():
PrintErrorMsg ( ErrorType , 'Typedef should be UPPER case' , FileTable , Td [ 5 ])
if Found :
break
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
if not Found :
PrintErrorMsg ( ErrorType , 'No Typedef for %s ' % Result [ 0 ], FileTable , Result [ 3 ])
continue
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
def CheckDeclStructTypedef ( FullFileName ):
CheckDeclTypedefFormat ( FullFileName , DataClass . MODEL_IDENTIFIER_STRUCTURE )
def CheckDeclEnumTypedef ( FullFileName ):
CheckDeclTypedefFormat ( FullFileName , DataClass . MODEL_IDENTIFIER_ENUMERATE )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
def CheckDeclUnionTypedef ( FullFileName ):
CheckDeclTypedefFormat ( FullFileName , DataClass . MODEL_IDENTIFIER_UNION )
def CheckDeclArgModifier ( FullFileName ):
ErrorMsgList = []
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FileID = GetTableID ( FullFileName , ErrorMsgList )
if FileID < 0 :
return ErrorMsgList
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Db = GetDB ()
FileTable = 'Identifier' + str ( FileID )
SqlStatement = """ select Modifier, Name, ID
from %s
where Model = %d
""" % ( FileTable , DataClass . MODEL_IDENTIFIER_VARIABLE )
ResultSet = Db . TblFile . Exec ( SqlStatement )
ModifierTuple = ( 'IN' , 'OUT' , 'OPTIONAL' , 'UNALIGNED' )
MAX_MODIFIER_LENGTH = 100
for Result in ResultSet :
for Modifier in ModifierTuple :
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
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
SqlStatement = """ select Modifier, Name, ID
from %s
where Model = %d
""" % ( FileTable , DataClass . MODEL_IDENTIFIER_FUNCTION_DECLARATION )
ResultSet = Db . TblFile . Exec ( SqlStatement )
for Result in ResultSet :
for Modifier in ModifierTuple :
if PatternInModifier ( Result [ 0 ], Modifier ):
PrintErrorMsg ( ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER , 'Return Type Modifier %s ' % Result [ 0 ], FileTable , Result [ 2 ])
break
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
SqlStatement = """ select Modifier, Header, ID
from Function
where BelongsToFile = %d
""" % ( FileID )
ResultSet = Db . TblFile . Exec ( SqlStatement )
for Result in ResultSet :
for Modifier in ModifierTuple :
if PatternInModifier ( Result [ 0 ], Modifier ):
PrintErrorMsg ( ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER , 'Return Type Modifier %s ' % Result [ 0 ], FileTable , Result [ 2 ])
break
def CheckDeclNoUseCType ( FullFileName ):
ErrorMsgList = []
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FileID = GetTableID ( FullFileName , ErrorMsgList )
if FileID < 0 :
return ErrorMsgList
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Db = GetDB ()
FileTable = 'Identifier' + str ( FileID )
SqlStatement = """ select Modifier, Name, ID
from %s
where Model = %d
""" % ( FileTable , DataClass . MODEL_IDENTIFIER_VARIABLE )
ResultSet = Db . TblFile . Exec ( SqlStatement )
CTypeTuple = ( 'int' , 'unsigned' , 'char' , 'void' , 'static' , 'long' )
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 ])
break
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
SqlStatement = """ select Modifier, Name, ID, Value
from %s
where Model = %d
""" % ( FileTable , DataClass . MODEL_IDENTIFIER_FUNCTION_DECLARATION )
ResultSet = Db . TblFile . Exec ( SqlStatement )
for Result in ResultSet :
ParamList = GetParamList ( Result [ 1 ])
FuncName = Result [ 3 ]
if EccGlobalData . gException . IsException ( ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE , FuncName ):
continue
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 ])
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
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 ])
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
SqlStatement = """ select Modifier, Header, ID, Name
from Function
where BelongsToFile = %d
""" % ( FileID )
ResultSet = Db . TblFile . Exec ( SqlStatement )
for Result in ResultSet :
ParamList = GetParamList ( Result [ 1 ])
FuncName = Result [ 3 ]
if EccGlobalData . gException . IsException ( ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE , FuncName ):
continue
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 ])
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
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 ])
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
def CheckPointerNullComparison ( FullFileName ):
ErrorMsgList = []
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FileID = GetTableID ( FullFileName , ErrorMsgList )
if FileID < 0 :
return ErrorMsgList
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
# cache the found function return type to accelerate later checking in this file.
FuncReturnTypeDict = {}
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Db = GetDB ()
FileTable = 'Identifier' + str ( FileID )
SqlStatement = """ select Value, StartLine, ID
from %s
where Model = %d
""" % ( FileTable , DataClass . MODEL_IDENTIFIER_PREDICATE_EXPRESSION )
ResultSet = Db . TblFile . Exec ( SqlStatement )
if len ( ResultSet ) == 0 :
return
PSL = []
for Result in ResultSet :
PSL . append ([ Result [ 0 ], Result [ 1 ], Result [ 2 ]])
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
SqlStatement = """ select BodyStartLine, EndLine, Header, Modifier, ID
from Function
where BelongsToFile = %d
""" % ( FileID )
ResultSet = Db . TblFile . Exec ( SqlStatement )
FL = []
for Result in ResultSet :
FL . append ([ Result [ 0 ], Result [ 1 ], Result [ 2 ], Result [ 3 ], Result [ 4 ]])
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
p = GetFuncDeclPattern ()
for Str in PSL :
FuncRecord = GetFuncContainsPE ( Str [ 1 ], FL )
if FuncRecord == None :
continue
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
for Exp in GetPredicateListFromPredicateExpStr ( Str [ 0 ]):
PredInfo = SplitPredicateStr ( Exp )
if PredInfo [ 1 ] == None :
PredVarStr = PredInfo [ 0 ][ 0 ] . strip ()
IsFuncCall = False
SearchInCache = False
# PredVarStr may contain '.' or '->'
TmpStr = PredVarStr . replace ( '.' , '' ) . replace ( '->' , '' )
if p . match ( TmpStr ):
PredVarStr = PredVarStr [ 0 : PredVarStr . find ( '(' )]
SearchInCache = True
# Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable.
2010-02-28 23:39:39 +00:00
if TmpStr . startswith ( PredVarStr ):
2009-07-17 09:10:31 +00:00
IsFuncCall = True
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
if PredVarStr . strip () in IgnoredKeywordList :
continue
StarList = []
PredVarList = GetCNameList ( PredVarStr , StarList )
# No variable found, maybe value first? like (0 == VarName)
if len ( PredVarList ) == 0 :
continue
if SearchInCache :
Type = FuncReturnTypeDict . get ( PredVarStr )
if Type != None :
2011-10-11 02:49:48 +00:00
if Type . find ( '*' ) != - 1 and Type != 'BOOLEAN*' :
2009-07-17 09:10:31 +00:00
PrintErrorMsg ( ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE , 'Predicate Expression: %s ' % Exp , FileTable , Str [ 2 ])
continue
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
if PredVarStr in FuncReturnTypeDict :
continue
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Type = GetVarInfo ( PredVarList , FuncRecord , FullFileName , IsFuncCall , None , StarList )
if SearchInCache :
FuncReturnTypeDict [ PredVarStr ] = Type
if Type == None :
continue
2010-02-28 23:39:39 +00:00
Type = GetTypeFromArray ( Type , PredVarStr )
2011-10-11 02:49:48 +00:00
if Type . find ( '*' ) != - 1 and Type != 'BOOLEAN*' :
2009-07-17 09:10:31 +00:00
PrintErrorMsg ( ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE , 'Predicate Expression: %s ' % Exp , FileTable , Str [ 2 ])
def CheckNonBooleanValueComparison ( FullFileName ):
ErrorMsgList = []
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FileID = GetTableID ( FullFileName , ErrorMsgList )
if FileID < 0 :
return ErrorMsgList
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
# cache the found function return type to accelerate later checking in this file.
FuncReturnTypeDict = {}
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Db = GetDB ()
FileTable = 'Identifier' + str ( FileID )
SqlStatement = """ select Value, StartLine, ID
from %s
where Model = %d
""" % ( FileTable , DataClass . MODEL_IDENTIFIER_PREDICATE_EXPRESSION )
ResultSet = Db . TblFile . Exec ( SqlStatement )
if len ( ResultSet ) == 0 :
return
PSL = []
for Result in ResultSet :
PSL . append ([ Result [ 0 ], Result [ 1 ], Result [ 2 ]])
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
SqlStatement = """ select BodyStartLine, EndLine, Header, Modifier, ID
from Function
where BelongsToFile = %d
""" % ( FileID )
ResultSet = Db . TblFile . Exec ( SqlStatement )
FL = []
for Result in ResultSet :
FL . append ([ Result [ 0 ], Result [ 1 ], Result [ 2 ], Result [ 3 ], Result [ 4 ]])
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
p = GetFuncDeclPattern ()
for Str in PSL :
FuncRecord = GetFuncContainsPE ( Str [ 1 ], FL )
if FuncRecord == None :
continue
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
for Exp in GetPredicateListFromPredicateExpStr ( Str [ 0 ]):
PredInfo = SplitPredicateStr ( Exp )
if PredInfo [ 1 ] == None :
PredVarStr = PredInfo [ 0 ][ 0 ] . strip ()
IsFuncCall = False
SearchInCache = False
# PredVarStr may contain '.' or '->'
TmpStr = PredVarStr . replace ( '.' , '' ) . replace ( '->' , '' )
if p . match ( TmpStr ):
PredVarStr = PredVarStr [ 0 : PredVarStr . find ( '(' )]
SearchInCache = True
# Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable.
2010-02-28 23:39:39 +00:00
if TmpStr . startswith ( PredVarStr ):
2009-07-17 09:10:31 +00:00
IsFuncCall = True
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
if PredVarStr . strip () in IgnoredKeywordList :
continue
StarList = []
PredVarList = GetCNameList ( PredVarStr , StarList )
# No variable found, maybe value first? like (0 == VarName)
if len ( PredVarList ) == 0 :
continue
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
if SearchInCache :
Type = FuncReturnTypeDict . get ( PredVarStr )
if Type != None :
if Type . find ( 'BOOLEAN' ) == - 1 :
PrintErrorMsg ( ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR , 'Predicate Expression: %s ' % Exp , FileTable , Str [ 2 ])
continue
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
if PredVarStr in FuncReturnTypeDict :
continue
Type = GetVarInfo ( PredVarList , FuncRecord , FullFileName , IsFuncCall , 'BOOLEAN' , StarList )
if SearchInCache :
FuncReturnTypeDict [ PredVarStr ] = Type
if Type == None :
continue
if Type . find ( 'BOOLEAN' ) == - 1 :
PrintErrorMsg ( ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR , 'Predicate Expression: %s ' % Exp , FileTable , Str [ 2 ])
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
def CheckBooleanValueComparison ( FullFileName ):
ErrorMsgList = []
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FileID = GetTableID ( FullFileName , ErrorMsgList )
if FileID < 0 :
return ErrorMsgList
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
# cache the found function return type to accelerate later checking in this file.
FuncReturnTypeDict = {}
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Db = GetDB ()
FileTable = 'Identifier' + str ( FileID )
SqlStatement = """ select Value, StartLine, ID
from %s
where Model = %d
""" % ( FileTable , DataClass . MODEL_IDENTIFIER_PREDICATE_EXPRESSION )
ResultSet = Db . TblFile . Exec ( SqlStatement )
if len ( ResultSet ) == 0 :
return
PSL = []
for Result in ResultSet :
PSL . append ([ Result [ 0 ], Result [ 1 ], Result [ 2 ]])
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
SqlStatement = """ select BodyStartLine, EndLine, Header, Modifier, ID
from Function
where BelongsToFile = %d
""" % ( FileID )
ResultSet = Db . TblFile . Exec ( SqlStatement )
FL = []
for Result in ResultSet :
FL . append ([ Result [ 0 ], Result [ 1 ], Result [ 2 ], Result [ 3 ], Result [ 4 ]])
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
p = GetFuncDeclPattern ()
for Str in PSL :
FuncRecord = GetFuncContainsPE ( Str [ 1 ], FL )
if FuncRecord == None :
continue
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
for Exp in GetPredicateListFromPredicateExpStr ( Str [ 0 ]):
PredInfo = SplitPredicateStr ( Exp )
if PredInfo [ 1 ] in ( '==' , '!=' ) and PredInfo [ 0 ][ 1 ] in ( 'TRUE' , 'FALSE' ):
PredVarStr = PredInfo [ 0 ][ 0 ] . strip ()
IsFuncCall = False
SearchInCache = False
# PredVarStr may contain '.' or '->'
TmpStr = PredVarStr . replace ( '.' , '' ) . replace ( '->' , '' )
if p . match ( TmpStr ):
PredVarStr = PredVarStr [ 0 : PredVarStr . find ( '(' )]
SearchInCache = True
# Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable.
2010-02-28 23:39:39 +00:00
if TmpStr . startswith ( PredVarStr ):
2009-07-17 09:10:31 +00:00
IsFuncCall = True
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
if PredVarStr . strip () in IgnoredKeywordList :
continue
StarList = []
PredVarList = GetCNameList ( PredVarStr , StarList )
# No variable found, maybe value first? like (0 == VarName)
if len ( PredVarList ) == 0 :
continue
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
if SearchInCache :
Type = FuncReturnTypeDict . get ( PredVarStr )
if Type != None :
if Type . find ( 'BOOLEAN' ) != - 1 :
PrintErrorMsg ( ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE , 'Predicate Expression: %s ' % Exp , FileTable , Str [ 2 ])
continue
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
if PredVarStr in FuncReturnTypeDict :
continue
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Type = GetVarInfo ( PredVarList , FuncRecord , FullFileName , IsFuncCall , 'BOOLEAN' , StarList )
if SearchInCache :
FuncReturnTypeDict [ PredVarStr ] = Type
if Type == None :
continue
if Type . find ( 'BOOLEAN' ) != - 1 :
PrintErrorMsg ( ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE , 'Predicate Expression: %s ' % Exp , FileTable , Str [ 2 ])
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
def CheckHeaderFileData ( FullFileName ):
ErrorMsgList = []
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FileID = GetTableID ( FullFileName , ErrorMsgList )
if FileID < 0 :
return ErrorMsgList
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Db = GetDB ()
FileTable = 'Identifier' + str ( FileID )
SqlStatement = """ select ID, Modifier
from %s
where Model = %d
""" % ( FileTable , DataClass . MODEL_IDENTIFIER_VARIABLE )
ResultSet = Db . TblFile . Exec ( SqlStatement )
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 ])
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
SqlStatement = """ select ID
from Function
where BelongsToFile = %d
""" % FileID
ResultSet = Db . TblFile . Exec ( SqlStatement )
for Result in ResultSet :
PrintErrorMsg ( ERROR_INCLUDE_FILE_CHECK_DATA , 'Function definition appears in header file' , 'Function' , Result [ 0 ])
return ErrorMsgList
def CheckHeaderFileIfndef ( FullFileName ):
ErrorMsgList = []
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FileID = GetTableID ( FullFileName , ErrorMsgList )
if FileID < 0 :
return ErrorMsgList
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Db = GetDB ()
FileTable = 'Identifier' + str ( FileID )
SqlStatement = """ select Value, StartLine
from %s
where Model = %d order by StartLine
""" % ( FileTable , DataClass . MODEL_IDENTIFIER_MACRO_IFNDEF )
ResultSet = Db . TblFile . Exec ( SqlStatement )
if len ( ResultSet ) == 0 :
PrintErrorMsg ( ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_1 , '' , 'File' , FileID )
return ErrorMsgList
for Result in ResultSet :
SqlStatement = """ select Value, EndLine
from %s
where EndLine < %d
""" % ( FileTable , Result [ 1 ])
ResultSet = Db . TblFile . Exec ( SqlStatement )
for Result in ResultSet :
if not Result [ 0 ] . startswith ( '/*' ) and not Result [ 0 ] . startswith ( '//' ):
PrintErrorMsg ( ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_2 , '' , 'File' , FileID )
break
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
SqlStatement = """ select Value
from %s
where StartLine > (select max(EndLine) from %s where Model = %d )
""" % ( FileTable , FileTable , DataClass . MODEL_IDENTIFIER_MACRO_ENDIF )
ResultSet = Db . TblFile . Exec ( SqlStatement )
for Result in ResultSet :
if not Result [ 0 ] . startswith ( '/*' ) and not Result [ 0 ] . startswith ( '//' ):
PrintErrorMsg ( ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_3 , '' , 'File' , FileID )
return ErrorMsgList
def CheckDoxygenCommand ( FullFileName ):
ErrorMsgList = []
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FileID = GetTableID ( FullFileName , ErrorMsgList )
if FileID < 0 :
return ErrorMsgList
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Db = GetDB ()
FileTable = 'Identifier' + str ( FileID )
SqlStatement = """ select Value, ID
from %s
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' ]
for Result in ResultSet :
CommentStr = Result [ 0 ]
CommentPartList = CommentStr . split ()
for Part in CommentPartList :
if Part . upper () == 'BUGBUG' :
PrintErrorMsg ( ERROR_DOXYGEN_CHECK_COMMAND , 'Bug should be marked with doxygen tag @bug' , FileTable , Result [ 1 ])
if Part . upper () == 'TODO' :
PrintErrorMsg ( ERROR_DOXYGEN_CHECK_COMMAND , 'ToDo should be marked with doxygen tag @todo' , FileTable , Result [ 1 ])
if Part . startswith ( '@' ):
if EccGlobalData . gException . IsException ( ERROR_DOXYGEN_CHECK_COMMAND , Part ):
continue
if Part . lstrip ( '@' ) . isalpha ():
if Part . lstrip ( '@' ) not in DoxygenCommandList :
PrintErrorMsg ( ERROR_DOXYGEN_CHECK_COMMAND , 'Unknown doxygen command %s ' % Part , FileTable , Result [ 1 ])
else :
Index = Part . find ( '[' )
if Index == - 1 :
PrintErrorMsg ( ERROR_DOXYGEN_CHECK_COMMAND , 'Unknown doxygen command %s ' % Part , FileTable , Result [ 1 ])
RealCmd = Part [ 1 : Index ]
if RealCmd not in DoxygenCommandList :
PrintErrorMsg ( ERROR_DOXYGEN_CHECK_COMMAND , 'Unknown doxygen command %s ' % Part , FileTable , Result [ 1 ])
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
def CheckDoxygenTripleForwardSlash ( FullFileName ):
ErrorMsgList = []
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FileID = GetTableID ( FullFileName , ErrorMsgList )
if FileID < 0 :
return ErrorMsgList
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Db = GetDB ()
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
SqlStatement = """ select ID, BodyStartLine, BodyStartColumn, EndLine, EndColumn
from Function
where BelongsToFile = %d
""" % ( FileID )
ResultSet = Db . TblFile . Exec ( SqlStatement )
if len ( ResultSet ) == 0 :
return
2010-02-28 23:39:39 +00:00
FuncDefSet = []
2009-07-17 09:10:31 +00:00
for Result in ResultSet :
FuncDefSet . append ( Result )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FileTable = 'Identifier' + str ( FileID )
SqlStatement = """ select Value, ID, StartLine, StartColumn, EndLine, EndColumn
from %s
2010-02-28 23:39:39 +00:00
where Model = %d
2009-07-17 09:10:31 +00:00
""" % ( FileTable , DataClass . MODEL_IDENTIFIER_COMMENT )
ResultSet = Db . TblFile . Exec ( SqlStatement )
CommentSet = []
try :
for Result in ResultSet :
CommentSet . append ( Result )
except :
print 'Unrecognized chars in comment of file %s ' , FullFileName
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
for Result in CommentSet :
CommentStr = Result [ 0 ]
StartLine = Result [ 2 ]
StartColumn = Result [ 3 ]
EndLine = Result [ 4 ]
EndColumn = Result [ 5 ]
if not CommentStr . startswith ( '///<' ):
continue
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Found = False
for FuncDef in FuncDefSet :
if StartLine == FuncDef [ 1 ] and StartColumn > FuncDef [ 2 ] and EndLine == FuncDef [ 3 ] and EndColumn < FuncDef [ 4 ]:
Found = True
break
if StartLine > FuncDef [ 1 ] and EndLine < FuncDef [ 3 ]:
Found = True
break
if StartLine == FuncDef [ 1 ] and StartColumn > FuncDef [ 2 ] and EndLine < FuncDef [ 3 ]:
Found = True
break
if StartLine > FuncDef [ 1 ] and EndLine == FuncDef [ 3 ] and EndColumn < FuncDef [ 4 ]:
Found = True
break
if Found :
PrintErrorMsg ( ERROR_DOXYGEN_CHECK_COMMENT_FORMAT , '' , FileTable , Result [ 1 ])
def CheckFileHeaderDoxygenComments ( FullFileName ):
ErrorMsgList = []
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FileID = GetTableID ( FullFileName , ErrorMsgList )
if FileID < 0 :
return ErrorMsgList
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Db = GetDB ()
FileTable = 'Identifier' + str ( FileID )
SqlStatement = """ select Value, ID
from %s
2010-09-06 01:58:00 +00:00
where Model = %d and (StartLine = 1 or StartLine = 7 or StartLine = 8) and StartColumn = 0
2009-07-17 09:10:31 +00:00
""" % ( FileTable , DataClass . MODEL_IDENTIFIER_COMMENT )
ResultSet = Db . TblFile . Exec ( SqlStatement )
if len ( ResultSet ) == 0 :
2011-12-07 06:19:28 +00:00
PrintErrorMsg ( ERROR_HEADER_CHECK_FILE , 'No File License header appear at the very beginning of file.' , 'File' , FileID )
2009-07-17 09:10:31 +00:00
return ErrorMsgList
2010-02-28 23:39:39 +00:00
2011-12-07 06:19:28 +00:00
NoHeaderCommentStartFlag = True
NoHeaderCommentEndFlag = True
NoHeaderCommentPeriodFlag = True
NoCopyrightFlag = True
NoLicenseFlag = True
NoRevReferFlag = True
NextLineIndex = 0
2009-07-17 09:10:31 +00:00
for Result in ResultSet :
2011-12-07 06:19:28 +00:00
FileStartFlag = False
CommentStrList = []
2010-09-06 01:58:00 +00:00
CommentStr = Result [ 0 ] . strip ()
2011-12-07 06:19:28 +00:00
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 )
2010-09-06 01:58:00 +00:00
ID = Result [ 1 ]
2011-12-07 06:19:28 +00:00
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
2010-09-06 01:58:00 +00:00
2011-12-07 06:19:28 +00:00
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 :
2015-07-02 06:05:26 +00:00
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
2011-12-07 06:19:28 +00:00
if CommentLine . endswith ( '<BR>' ) == - 1 :
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 ():
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 :
2010-09-06 01:58:00 +00:00
PrintErrorMsg ( ERROR_DOXYGEN_CHECK_FILE_HEADER , 'File header comment should begin with ""/** @file""' , FileTable , ID )
2011-12-07 06:19:28 +00:00
return
if NoHeaderCommentEndFlag :
2010-09-06 01:58:00 +00:00
PrintErrorMsg ( ERROR_HEADER_CHECK_FILE , 'File header comment should end with ""**/""' , FileTable , ID )
2011-12-07 06:19:28 +00:00
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 )
2009-07-17 09:10:31 +00:00
def CheckFuncHeaderDoxygenComments ( FullFileName ):
ErrorMsgList = []
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
FileID = GetTableID ( FullFileName , ErrorMsgList )
if FileID < 0 :
return ErrorMsgList
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Db = GetDB ()
FileTable = 'Identifier' + str ( FileID )
SqlStatement = """ select Value, StartLine, EndLine, ID
from %s
where Model = %d
""" % ( FileTable , DataClass . MODEL_IDENTIFIER_COMMENT )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
ResultSet = Db . TblFile . Exec ( SqlStatement )
CommentSet = []
try :
for Result in ResultSet :
CommentSet . append ( Result )
except :
print 'Unrecognized chars in comment of file %s ' , FullFileName
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
# Func Decl check
SqlStatement = """ select Modifier, Name, StartLine, ID, Value
from %s
where Model = %d
""" % ( FileTable , DataClass . MODEL_IDENTIFIER_FUNCTION_DECLARATION )
ResultSet = Db . TblFile . Exec ( SqlStatement )
for Result in ResultSet :
FuncName = Result [ 4 ]
FunctionHeaderComment = CheckCommentImmediatelyPrecedeFunctionHeader ( Result [ 1 ], Result [ 2 ], CommentSet )
if FunctionHeaderComment :
CheckFunctionHeaderConsistentWithDoxygenComment ( Result [ 0 ], Result [ 1 ], Result [ 2 ], FunctionHeaderComment [ 0 ], FunctionHeaderComment [ 1 ], ErrorMsgList , FunctionHeaderComment [ 3 ], FileTable )
else :
if EccGlobalData . gException . IsException ( ERROR_HEADER_CHECK_FUNCTION , FuncName ):
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 ])
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
# Func Def check
SqlStatement = """ select Value, StartLine, EndLine, ID
from %s
where Model = %d
""" % ( FileTable , DataClass . MODEL_IDENTIFIER_FUNCTION_HEADER )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
ResultSet = Db . TblFile . Exec ( SqlStatement )
CommentSet = []
try :
for Result in ResultSet :
CommentSet . append ( Result )
except :
print 'Unrecognized chars in comment of file %s ' , FullFileName
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
SqlStatement = """ select Modifier, Header, StartLine, ID, Name
from Function
where BelongsToFile = %d
""" % ( FileID )
ResultSet = Db . TblFile . Exec ( SqlStatement )
for Result in ResultSet :
FuncName = Result [ 4 ]
FunctionHeaderComment = CheckCommentImmediatelyPrecedeFunctionHeader ( Result [ 1 ], Result [ 2 ], CommentSet )
if FunctionHeaderComment :
CheckFunctionHeaderConsistentWithDoxygenComment ( Result [ 0 ], Result [ 1 ], Result [ 2 ], FunctionHeaderComment [ 0 ], FunctionHeaderComment [ 1 ], ErrorMsgList , FunctionHeaderComment [ 3 ], FileTable )
else :
if EccGlobalData . gException . IsException ( ERROR_HEADER_CHECK_FUNCTION , FuncName ):
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
def CheckCommentImmediatelyPrecedeFunctionHeader ( FuncName , FuncStartLine , CommentSet ):
for Comment in CommentSet :
if Comment [ 2 ] == FuncStartLine - 1 :
return Comment
return None
def GetDoxygenStrFromComment ( Str ):
DoxygenStrList = []
ParamTagList = Str . split ( '@param' )
if len ( ParamTagList ) > 1 :
i = 1
while i < len ( ParamTagList ):
DoxygenStrList . append ( '@param' + ParamTagList [ i ])
i += 1
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
Str = ParamTagList [ 0 ]
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
RetvalTagList = ParamTagList [ - 1 ] . split ( '@retval' )
if len ( RetvalTagList ) > 1 :
if len ( ParamTagList ) > 1 :
DoxygenStrList [ - 1 ] = '@param' + RetvalTagList [ 0 ]
i = 1
while i < len ( RetvalTagList ):
DoxygenStrList . append ( '@retval' + RetvalTagList [ i ])
i += 1
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
ReturnTagList = RetvalTagList [ - 1 ] . split ( '@return' )
if len ( ReturnTagList ) > 1 :
if len ( RetvalTagList ) > 1 :
DoxygenStrList [ - 1 ] = '@retval' + ReturnTagList [ 0 ]
elif len ( ParamTagList ) > 1 :
DoxygenStrList [ - 1 ] = '@param' + ReturnTagList [ 0 ]
i = 1
while i < len ( ReturnTagList ):
DoxygenStrList . append ( '@return' + ReturnTagList [ i ])
i += 1
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
if len ( DoxygenStrList ) > 0 :
DoxygenStrList [ - 1 ] = DoxygenStrList [ - 1 ] . rstrip ( '--*/' )
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
return DoxygenStrList
2010-02-28 23:39:39 +00:00
2011-10-11 02:49:48 +00:00
def CheckGeneralDoxygenCommentLayout ( Str , StartLine , ErrorMsgList , CommentId = - 1 , TableName = '' ):
2009-07-17 09:10:31 +00:00
#/** --*/ @retval after @param
if not Str . startswith ( '/**' ):
ErrorMsgList . append ( 'Line %d : Comment does NOT have prefix /** ' % StartLine )
PrintErrorMsg ( ERROR_DOXYGEN_CHECK_FUNCTION_HEADER , 'Comment does NOT have prefix /** ' , TableName , CommentId )
if not Str . endswith ( '**/' ):
ErrorMsgList . append ( 'Line %d : Comment does NOT have tail **/ ' % StartLine )
PrintErrorMsg ( ERROR_DOXYGEN_CHECK_FUNCTION_HEADER , 'Comment does NOT have tail **/ ' , TableName , CommentId )
FirstRetvalIndex = Str . find ( '@retval' )
LastParamIndex = Str . rfind ( '@param' )
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 )
2010-02-28 23:39:39 +00:00
2011-10-11 02:49:48 +00:00
def CheckFunctionHeaderConsistentWithDoxygenComment ( FuncModifier , FuncHeader , FuncStartLine , CommentStr , CommentStartLine , ErrorMsgList , CommentId = - 1 , TableName = '' ):
2010-02-28 23:39:39 +00:00
ParamList = GetParamList ( FuncHeader )
2009-07-17 09:10:31 +00:00
CheckGeneralDoxygenCommentLayout ( CommentStr , CommentStartLine , ErrorMsgList , CommentId , TableName )
DescriptionStr = CommentStr
DoxygenStrList = GetDoxygenStrFromComment ( DescriptionStr )
if DescriptionStr . find ( '.' ) == - 1 :
PrintErrorMsg ( ERROR_DOXYGEN_CHECK_COMMENT_DESCRIPTION , 'Comment description should end with period \' . \' ' , TableName , CommentId )
DoxygenTagNumber = len ( DoxygenStrList )
ParamNumber = len ( ParamList )
for Param in ParamList :
if Param . Name . upper () == 'VOID' and ParamNumber == 1 :
ParamNumber -= 1
Index = 0
if ParamNumber > 0 and DoxygenTagNumber > 0 :
while Index < ParamNumber and Index < DoxygenTagNumber :
ParamModifier = ParamList [ Index ] . Modifier
ParamName = ParamList [ Index ] . Name . strip ()
Tag = DoxygenStrList [ Index ] . strip ( ' ' )
if ( not Tag [ - 1 ] == ( ' \n ' )) and ( not Tag [ - 1 ] == ( ' \r ' )):
2011-10-11 02:49:48 +00:00
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 )
2009-07-17 09:10:31 +00:00
TagPartList = Tag . split ()
if len ( TagPartList ) < 2 :
2011-10-11 02:49:48 +00:00
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 )
2009-07-17 09:10:31 +00:00
Index += 1
continue
LBPos = Tag . find ( '[' )
RBPos = Tag . find ( ']' )
ParamToLBContent = Tag [ len ( '@param' ): LBPos ] . strip ()
2011-10-11 02:49:48 +00:00
if LBPos > 0 and len ( ParamToLBContent ) == 0 and RBPos > LBPos :
2009-07-17 09:10:31 +00:00
InOutStr = ''
ModifierPartList = ParamModifier . split ()
for Part in ModifierPartList :
if Part . strip () == 'IN' :
InOutStr += 'in'
if Part . strip () == 'OUT' :
2010-02-28 23:39:39 +00:00
if InOutStr != '' :
2009-07-17 09:10:31 +00:00
InOutStr += ', out'
else :
InOutStr = 'out'
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
if InOutStr != '' :
2011-10-11 02:49:48 +00:00
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 )
2009-07-17 09:10:31 +00:00
if Tag . find ( ParamName ) == - 1 and ParamName != 'VOID' and ParamName != 'void' :
2011-10-11 02:49:48 +00:00
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 )
2009-07-17 09:10:31 +00:00
Index += 1
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
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 :
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
# 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 :
2010-02-28 23:39:39 +00:00
if Index < DoxygenTagNumber and not DoxygenStrList [ Index ] . startswith ( '@retval' ) and not DoxygenStrList [ Index ] . startswith ( '@return' ):
2009-07-17 09:10:31 +00:00
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 )
if ParamNumber != 0 and DoxygenTagNumber == 0 :
ErrorMsgList . append ( 'Line %d : No doxygen tags in comment' % CommentStartLine )
PrintErrorMsg ( ERROR_DOXYGEN_CHECK_FUNCTION_HEADER , 'No doxygen tags in comment ' , TableName , CommentId )
if __name__ == '__main__' :
# EdkLogger.Initialize()
# EdkLogger.SetLevel(EdkLogger.QUIET)
2010-02-28 23:39:39 +00:00
# CollectSourceCodeDataIntoDB(sys.argv[1])
2011-09-18 12:17:25 +00:00
try :
test_file = sys . argv [ 1 ]
except IndexError , v :
print "Usage: %s filename" % sys . argv [ 0 ]
sys . exit ( 1 )
MsgList = CheckFuncHeaderDoxygenComments ( test_file )
2009-07-17 09:10:31 +00:00
for Msg in MsgList :
print Msg
print 'Done!'