summaryrefslogtreecommitdiff
path: root/BaseTools/Source/Python/Ecc/c.py
diff options
context:
space:
mode:
Diffstat (limited to 'BaseTools/Source/Python/Ecc/c.py')
-rw-r--r--BaseTools/Source/Python/Ecc/c.py2636
1 files changed, 0 insertions, 2636 deletions
diff --git a/BaseTools/Source/Python/Ecc/c.py b/BaseTools/Source/Python/Ecc/c.py
deleted file mode 100644
index 35b7405e55..0000000000
--- a/BaseTools/Source/Python/Ecc/c.py
+++ /dev/null
@@ -1,2636 +0,0 @@
-## @file
-# This file is used to be the c coding style checking of ECC tool
-#
-# Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<BR>
-# This program and the accompanying materials
-# are licensed and made available under the terms and conditions of the BSD License
-# which accompanies this distribution. The full text of the license may be found at
-# http://opensource.org/licenses/bsd-license.php
-#
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-#
-
-import sys
-import Common.LongFilePathOs as os
-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 += ' '
- GetDB().TblReport.Insert(ErrorType, OtherMsg=Msg, BelongsToTable=TableName, BelongsToItem=ItemId)
-
-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:
- IdComment = DataClass.IdentifierClass(-1, '', '', '', comment.Content, DataClass.MODEL_IDENTIFIER_COMMENT, -1, -1, comment.StartPos[0], comment.StartPos[1], comment.EndPos[0], comment.EndPos[1])
- IdList.append(IdComment)
-
- for pp in FileProfile.PPDirectiveList:
- Type = GetIdType(pp.Content)
- IdPP = DataClass.IdentifierClass(-1, '', '', '', pp.Content, Type, -1, -1, pp.StartPos[0], pp.StartPos[1], pp.EndPos[0], pp.EndPos[1])
- IdList.append(IdPP)
-
- for pe in FileProfile.PredicateExpressionList:
- IdPE = DataClass.IdentifierClass(-1, '', '', '', pe.Content, DataClass.MODEL_IDENTIFIER_PREDICATE_EXPRESSION, -1, -1, pe.StartPos[0], pe.StartPos[1], pe.EndPos[0], pe.EndPos[1])
- IdList.append(IdPE)
-
- 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]
-
- var.Declarator = DeclText
- if FuncDeclPattern.match(var.Declarator):
- DeclSplitList = var.Declarator.split('(')
- 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
-
- if var.Declarator.find('{') == -1:
- 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]
-
- IdVar = DataClass.IdentifierClass(-1, var.Modifier, '', Name, (len(DeclList) > 1 and [DeclList[1]]or [''])[0], DataClass.MODEL_IDENTIFIER_VARIABLE, -1, -1, var.StartPos[0], var.StartPos[1], VarNameStartLine, VarNameStartColumn)
- IdList.append(IdVar)
- else:
- DeclList = var.Declarator.split('=')
- Name = DeclList[0].strip()
- if ArrayPattern.match(Name):
- LSBPos = var.Declarator.find('[')
- var.Modifier += ' ' + Name[LSBPos:]
- Name = Name[0:LSBPos]
- IdVar = DataClass.IdentifierClass(-1, var.Modifier, '', Name, (len(DeclList) > 1 and [DeclList[1]]or [''])[0], DataClass.MODEL_IDENTIFIER_VARIABLE, -1, -1, var.StartPos[0], var.StartPos[1], VarNameStartLine, VarNameStartColumn)
- IdList.append(IdVar)
-
- for enum in FileProfile.EnumerationDefinitionList:
- LBPos = enum.Content.find('{')
- RBPos = enum.Content.find('}')
- Name = enum.Content[4:LBPos].strip()
- Value = enum.Content[LBPos + 1:RBPos]
- IdEnum = DataClass.IdentifierClass(-1, '', '', Name, Value, DataClass.MODEL_IDENTIFIER_ENUMERATE, -1, -1, enum.StartPos[0], enum.StartPos[1], enum.EndPos[0], enum.EndPos[1])
- IdList.append(IdEnum)
-
- 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()
- Value = su.Content[LBPos:RBPos + 1]
- IdPE = DataClass.IdentifierClass(-1, '', '', Name, Value, Type, -1, -1, su.StartPos[0], su.StartPos[1], su.EndPos[0], su.EndPos[1])
- IdList.append(IdPE)
-
- TdFuncPointerPattern = GetTypedefFuncPointerPattern()
- for td in FileProfile.TypedefDefinitionList:
- Modifier = ''
- Name = td.ToType
- Value = td.FromType
- if TdFuncPointerPattern.match(td.ToType):
- Modifier = td.FromType
- LBPos = td.ToType.find('(')
- TmpStr = td.ToType[LBPos + 1:].strip()
- 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()
-
- if Name.find('[') != -1:
- LBPos = Name.find('[')
- RBPos = Name.rfind(']')
- Value += Name[LBPos : RBPos + 1]
- Name = Name[0 : LBPos]
-
- IdTd = DataClass.IdentifierClass(-1, Modifier, '', Name, Value, DataClass.MODEL_IDENTIFIER_TYPEDEF, -1, -1, td.StartPos[0], td.StartPos[1], td.EndPos[0], td.EndPos[1])
- IdList.append(IdTd)
-
- for funcCall in FileProfile.FunctionCallingList:
- IdFC = DataClass.IdentifierClass(-1, '', '', funcCall.FuncName, funcCall.ParamList, DataClass.MODEL_IDENTIFIER_FUNCTION_CALLING, -1, -1, funcCall.StartPos[0], funcCall.StartPos[1], funcCall.EndPos[0], funcCall.EndPos[1])
- IdList.append(IdFC)
- return IdList
-
-def StripNonAlnumChars(Str):
- StrippedStr = ''
- for Char in Str:
- if Char.isalnum() or Char == '_':
- StrippedStr += Char
- return StrippedStr
-
-def GetParamList(FuncDeclarator, FuncNameLine=0, FuncNameOffset=0):
- 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 != '_':
-
- 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]
-
- OffsetSkipped += 1 #skip '('
-
- 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]
-
- Start = RightSpacePos
- Index = 0
- PreChar = ''
- while Index < Start:
- FirstChar = p[Index]
-
- 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
-
- ParamBeginLine = FuncNameLine + LineSkipped
- ParamBeginOffset = FuncNameOffset + OffsetSkipped
-
- Index = Start + len(ParamName)
- PreChar = ''
- while Index < len(p):
- FirstChar = p[Index]
-
- if FirstChar == '\r':
- Index += 1
- LineSkipped += 1
- 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
-
- ParamEndLine = FuncNameLine + LineSkipped
- ParamEndOffset = FuncNameOffset + OffsetSkipped
- if ParamName != '...':
- ParamName = StripNonAlnumChars(ParamName)
- IdParam = DataClass.IdentifierClass(-1, ParamModifier, '', ParamName, '', DataClass.MODEL_IDENTIFIER_PARAMETER, -1, -1, ParamBeginLine, ParamBeginOffset, ParamEndLine, ParamEndOffset)
- ParamIdList.append(IdParam)
-
- OffsetSkipped += 1 #skip ','
-
- return ParamIdList
-
-def GetFunctionList():
- FuncObjList = []
- for FuncDef in FileProfile.FunctionDefinitionList:
- 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]
-
- FuncDef.Declarator = DeclText
- DeclSplitList = FuncDef.Declarator.split('(')
- if len(DeclSplitList) < 2:
- continue
-
- 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
-
- FuncObj = DataClass.FunctionClass(-1, FuncDef.Declarator, FuncDef.Modifier, FuncName.strip(), '', FuncDef.StartPos[0], FuncDef.StartPos[1], FuncDef.EndPos[0], FuncDef.EndPos[1], FuncDef.LeftBracePos[0], FuncDef.LeftBracePos[1], -1, ParamIdList, [], FuncNameStartLine, FuncNameStartColumn)
- FuncObjList.append(FuncObj)
-
- return FuncObjList
-
-def GetFileModificationTimeFromDB(FullFileName):
- 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:
- if f.lower() in EccGlobalData.gConfig.SkipFileList:
- continue
- collector = None
- FullName = os.path.normpath(os.path.join(dirpath, f))
- model = DataClass.MODEL_FILE_OTHERS
- if os.path.splitext(f)[1] in ('.h', '.c'):
- EdkLogger.info("Parsing " + FullName)
- model = f.endswith('c') and DataClass.MODEL_FILE_C or DataClass.MODEL_FILE_H
- collector = CodeFragmentCollector.CodeFragmentCollector(FullName)
- try:
- collector.ParseFile()
- except UnicodeError:
- ParseErrorFileList.append(FullName)
- collector.CleanFileProfileBuffer()
- collector.ParseFileWithClearedPPDirective()
-# collector.PrintFragments()
- BaseName = os.path.basename(f)
- DirName = os.path.dirname(FullName)
- Ext = os.path.splitext(f)[1].lstrip('.')
- ModifiedTime = os.path.getmtime(FullName)
- FileObj = DataClass.FileClass(-1, BaseName, Ext, DirName, FullName, model, ModifiedTime, GetFunctionList(), GetIdentifierList(), [])
- FileObjList.append(FileObj)
- if collector:
- collector.CleanFileProfileBuffer()
-
- if len(ParseErrorFileList) > 0:
- EdkLogger.info("Found unrecoverable error during parsing:\n\t%s\n" % "\n\t".join(ParseErrorFileList))
-
- Db = GetDB()
- for file in FileObjList:
- if file.ExtName.upper() not in ['INF', 'DEC', 'DSC', 'FDF']:
- Db.InsertOneFile(file)
-
- Db.UpdateIdentifierBelongsToFunction()
-
-def GetTableID(FullFileName, ErrorMsgList=None):
- if ErrorMsgList == None:
- ErrorMsgList = []
-
- Db = GetDB()
- SqlStatement = """ select ID
- from File
- where FullPath like '%s'
- """ % FullFileName
- ResultSet = Db.TblFile.Exec(SqlStatement)
-
- FileID = -1
- for Result in ResultSet:
- if FileID != -1:
- ErrorMsgList.append('Duplicate file ID found in DB for file %s' % FullFileName)
- return - 2
- FileID = Result[0]
- if FileID == -1:
- ErrorMsgList.append('NO file ID found in DB for file %s' % FullFileName)
- return - 1
- return FileID
-
-def GetIncludeFileList(FullFileName):
- if os.path.splitext(FullFileName)[1].upper() not in ('.H'):
- return []
- IFList = IncludeFileListDict.get(FullFileName)
- if IFList != None:
- return IFList
-
- FileID = GetTableID(FullFileName)
- if FileID < 0:
- return []
-
- 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)
-
- 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)
-
- 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
-
- 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
- if (PES[i] == '&' and PES[i + 1] == '&') or (PES[i] == '|' and PES[i + 1] == '|'):
- LogicOpPos = i
- Exp = PES[PredicateBegin:i].strip()
- # Exp may contain '.' or '->'
- TmpExp = Exp.replace('.', '').replace('->', '')
- if p.match(TmpExp):
- PredicateList.append(Exp)
- else:
- PredicateList.append(Exp.rstrip(';').rstrip(')').strip())
- i += 1
-
- if PredicateBegin > LogicOpPos:
- while PredicateBegin < len(PES):
- if PES[PredicateBegin].isalnum() or PES[PredicateBegin] == '_' or PES[PredicateBegin] == '*':
- 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
-
-def GetCNameList(Lvalue, StarList=[]):
- Lvalue += ' '
- i = 0
- SearchBegin = 0
- VarStart = -1
- VarEnd = -1
- VarList = []
-
- while SearchBegin < len(Lvalue):
- while i < len(Lvalue):
- if Lvalue[i].isalnum() or Lvalue[i] == '_':
- if VarStart == -1:
- VarStart = i
- VarEnd = i
- i += 1
- elif VarEnd != -1:
- VarList.append(Lvalue[VarStart:VarEnd + 1])
- i += 1
- break
- else:
- if VarStart == -1 and Lvalue[i] == '*':
- StarList.append('*')
- i += 1
- if VarEnd == -1:
- break
-
-
- 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:
- SearchBegin = VarEnd + ((DotIndex < ArrowIndex) and DotIndex or ArrowIndex)
-
- i = SearchBegin
- VarStart = -1
- VarEnd = -1
-
- return VarList
-
-def SplitPredicateByOp(Str, Op, IsFuncCalling=False):
-
- Name = Str.strip()
- Value = None
-
- 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
-
- 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
-
- if RemainingStr.startswith('(') and not LBFound:
- LBFound = True
-
- if Str[Index] == '(':
- UnmatchedLBCount += 1
- Index += 1
- continue
-
- if Str[Index] == ')':
- UnmatchedLBCount -= 1
- Index += 1
- if UnmatchedLBCount == 0:
- break
- continue
-
- Index += 1
-
- if UnmatchedLBCount > 0:
- return [Name]
-
- IndexInRemainingStr = Str[Index:].find(Op)
- if IndexInRemainingStr == -1:
- return [Name]
-
- Name = Str[0:Index + IndexInRemainingStr].strip()
- Value = Str[Index + IndexInRemainingStr + len(Op):].strip().strip(')')
- return [Name, Value]
-
- TmpStr = Str.rstrip(';').rstrip(')')
- while True:
- Index = TmpStr.rfind(Op)
- if Index == -1:
- return [Name]
-
- if Str[Index - 1].isalnum() or Str[Index - 1].isspace() or Str[Index - 1] == ')' or Str[Index - 1] == ']':
- Name = Str[0:Index].strip()
- Value = Str[Index + len(Op):].strip()
- return [Name, Value]
-
- TmpStr = Str[0:Index - 1]
-
-def SplitPredicateStr(Str):
-
- Str = Str.lstrip('(')
- IsFuncCalling = False
- p = GetFuncDeclPattern()
- TmpStr = Str.replace('.', '').replace('->', '')
- if p.match(TmpStr):
- IsFuncCalling = True
-
- PredPartList = SplitPredicateByOp(Str, '==', IsFuncCalling)
- if len(PredPartList) > 1:
- return [PredPartList, '==']
-
- PredPartList = SplitPredicateByOp(Str, '!=', IsFuncCalling)
- if len(PredPartList) > 1:
- return [PredPartList, '!=']
-
- PredPartList = SplitPredicateByOp(Str, '>=', IsFuncCalling)
- if len(PredPartList) > 1:
- return [PredPartList, '>=']
-
- PredPartList = SplitPredicateByOp(Str, '<=', IsFuncCalling)
- if len(PredPartList) > 1:
- return [PredPartList, '<=']
-
- PredPartList = SplitPredicateByOp(Str, '>', IsFuncCalling)
- if len(PredPartList) > 1:
- return [PredPartList, '>']
-
- PredPartList = SplitPredicateByOp(Str, '<', IsFuncCalling)
- if len(PredPartList) > 1:
- return [PredPartList, '<']
-
- return [[Str, None], None]
-
-def GetFuncContainsPE(ExpLine, ResultSet):
- 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:
- if M in EccGlobalData.gConfig.ModifierList:
- continue
- # remove array sufix
- if M.startswith('[') or M.endswith(']'):
- continue
- ReturnType += M + ' '
-
- 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
-
-def GetTypedefDict(FullFileName):
-
- Dict = ComplexTypeDict.get(FullFileName)
- if Dict != None:
- return Dict
-
- 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)
-
- Dict = {}
- for Result in ResultSet:
- if len(Result[0]) == 0:
- Dict[Result[1]] = Result[2]
-
- IncludeFileList = GetAllIncludeFiles(FullFileName)
- for F in IncludeFileList:
- FileID = GetTableID(F)
- if FileID < 0:
- continue
-
- FileTable = 'Identifier' + str(FileID)
- SqlStatement = """ select Modifier, Name, Value, ID
- from %s
- where Model = %d
- """ % (FileTable, DataClass.MODEL_IDENTIFIER_TYPEDEF)
- ResultSet = Db.TblFile.Exec(SqlStatement)
-
- for Result in ResultSet:
- if not Result[2].startswith('FP ('):
- Dict[Result[1]] = Result[2]
- else:
- if len(Result[0]) == 0:
- Dict[Result[1]] = 'VOID'
- else:
- Dict[Result[1]] = GetDataTypeFromModifier(Result[0])
-
- ComplexTypeDict[FullFileName] = Dict
- return Dict
-
-def GetSUDict(FullFileName):
-
- Dict = SUDict.get(FullFileName)
- if Dict != None:
- return Dict
-
- 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)
-
- Dict = {}
- for Result in ResultSet:
- if len(Result[1]) > 0:
- Dict[Result[0]] = Result[1]
-
- IncludeFileList = GetAllIncludeFiles(FullFileName)
- for F in IncludeFileList:
- FileID = GetTableID(F)
- if FileID < 0:
- continue
-
- FileTable = 'Identifier' + str(FileID)
- SqlStatement = """ select Name, Value, ID
- from %s
- where Model = %d or Model = %d
- """ % (FileTable, DataClass.MODEL_IDENTIFIER_STRUCTURE, DataClass.MODEL_IDENTIFIER_UNION)
- ResultSet = Db.TblFile.Exec(SqlStatement)
-
- for Result in ResultSet:
- if len(Result[1]) > 0:
- Dict[Result[0]] = Result[1]
-
- SUDict[FullFileName] = Dict
- return Dict
-
-def StripComments(Str):
- Str += ' '
- ListFromStr = list(Str)
-
- InComment = False
- DoubleSlashComment = False
- Index = 0
- 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
- elif InComment and not DoubleSlashComment and ListFromStr[Index] == '*' and ListFromStr[Index + 1] == '/':
- ListFromStr[Index] = ' '
- Index += 1
- ListFromStr[Index] = ' '
- Index += 1
- InComment = False
- # set comments to spaces
- elif InComment:
- ListFromStr[Index] = ' '
- Index += 1
- # check for // comment
- elif ListFromStr[Index] == '/' and ListFromStr[Index + 1] == '/' and ListFromStr[Index + 2] != '\n':
- InComment = True
- DoubleSlashComment = True
-
- # check for /* comment start
- elif ListFromStr[Index] == '/' and ListFromStr[Index + 1] == '*':
- ListFromStr[Index] = ' '
- Index += 1
- ListFromStr[Index] = ' '
- Index += 1
- InComment = True
- else:
- Index += 1
-
- # restore from List to String
- Str = "".join(ListFromStr)
- Str = Str.rstrip(' ')
-
- return Str
-
-def GetFinalTypeValue(Type, FieldName, TypedefDict, SUDict):
- Value = TypedefDict.get(Type)
- if Value == None:
- Value = SUDict.get(Type)
- if Value == None:
- return None
-
- LBPos = Value.find('{')
- while LBPos == -1:
- FTList = Value.split()
- for FT in FTList:
- if FT not in ('struct', 'union'):
- Value = TypedefDict.get(FT)
- if Value == None:
- Value = SUDict.get(FT)
- break
-
- if Value == None:
- return None
-
- LBPos = Value.find('{')
-
-# 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:
- # For the condition that the field in struct is an array with [] sufixes...
- if not Field[Index + len(FieldName)].isalnum():
- Type = GetDataTypeFromModifier(Field[0:Index])
- return Type.strip()
-
- return None
-
-def GetRealType(Type, TypedefDict, TargetType=None):
- if TargetType != None and Type == TargetType:
- return Type
- while TypedefDict.get(Type):
- Type = TypedefDict.get(Type)
- if TargetType != None and Type == TargetType:
- return Type
- return Type
-
-def GetTypeInfo(RefList, Modifier, FullFileName, TargetType=None):
- TypedefDict = GetTypedefDict(FullFileName)
- SUDict = GetSUDict(FullFileName)
- Type = GetDataTypeFromModifier(Modifier).replace('*', '').strip()
-
- Type = Type.split()[-1]
- Index = 0
- while Index < len(RefList):
- FieldName = RefList[Index]
- FromType = GetFinalTypeValue(Type, FieldName, TypedefDict, SUDict)
- if FromType == None:
- 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
- if Type.find('*') != -1 and Index == len(RefList) - 1:
- return Type
- Type = FromType.split()[0]
-
- Index += 1
-
- Type = GetRealType(Type, TypedefDict, TargetType)
-
- return Type
-
-def GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall=False, TargetType=None, StarList=None):
-
- PredVar = PredVarList[0]
- FileID = GetTableID(FullFileName)
-
- Db = GetDB()
- FileTable = 'Identifier' + str(FileID)
- # search variable in include files
-
- # it is a function call, search function declarations and definitions
- if IsFuncCall:
- SqlStatement = """ select Modifier, ID
- from %s
- where Model = %d and Value = \'%s\'
- """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION, PredVar)
- ResultSet = Db.TblFile.Exec(SqlStatement)
-
- for Result in ResultSet:
- Type = GetDataTypeFromModifier(Result[0]).split()[-1]
- TypedefDict = GetTypedefDict(FullFileName)
- Type = GetRealType(Type, TypedefDict, TargetType)
- return Type
-
- IncludeFileList = GetAllIncludeFiles(FullFileName)
- for F in IncludeFileList:
- FileID = GetTableID(F)
- if FileID < 0:
- continue
-
- FileTable = 'Identifier' + str(FileID)
- SqlStatement = """ select Modifier, ID
- from %s
- where Model = %d and Value = \'%s\'
- """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION, PredVar)
- ResultSet = Db.TblFile.Exec(SqlStatement)
-
- for Result in ResultSet:
- Type = GetDataTypeFromModifier(Result[0]).split()[-1]
- TypedefDict = GetTypedefDict(FullFileName)
- Type = GetRealType(Type, TypedefDict, TargetType)
- return Type
-
- FileID = GetTableID(FullFileName)
- SqlStatement = """ select Modifier, ID
- from Function
- where BelongsToFile = %d and Name = \'%s\'
- """ % (FileID, PredVar)
- ResultSet = Db.TblFile.Exec(SqlStatement)
-
- for Result in ResultSet:
- Type = GetDataTypeFromModifier(Result[0]).split()[-1]
- TypedefDict = GetTypedefDict(FullFileName)
- Type = GetRealType(Type, TypedefDict, TargetType)
- return Type
-
- for F in IncludeFileList:
- FileID = GetTableID(F)
- if FileID < 0:
- continue
-
- FileTable = 'Identifier' + str(FileID)
- SqlStatement = """ select Modifier, ID
- from Function
- where BelongsToFile = %d and Name = \'%s\'
- """ % (FileID, PredVar)
- ResultSet = Db.TblFile.Exec(SqlStatement)
-
- for Result in ResultSet:
- Type = GetDataTypeFromModifier(Result[0]).split()[-1]
- TypedefDict = GetTypedefDict(FullFileName)
- Type = GetRealType(Type, TypedefDict, TargetType)
- return Type
-
- return None
-
- # really variable, search local variable first
- SqlStatement = """ select Modifier, ID
- from %s
- 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
-
- # 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]
- if Type == '*' and len(TypeList) >= 2:
- Type = TypeList[-2]
- 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
-
- # 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
-
- IncludeFileList = GetAllIncludeFiles(FullFileName)
- for F in IncludeFileList:
- FileID = GetTableID(F)
- if FileID < 0:
- continue
-
- FileTable = 'Identifier' + str(FileID)
- SqlStatement = """ select Modifier, ID
- from %s
- where Model = %d and 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
-
-def GetTypeFromArray(Type, Var):
- Count = Var.count('[')
-
- while Count > 0:
- Type = Type.strip()
- Type = Type.rstrip('*')
- Count = Count - 1
-
- return Type
-
-def CheckFuncLayoutReturnType(FullFileName):
- ErrorMsgList = []
-
- FileID = GetTableID(FullFileName, ErrorMsgList)
- if FileID < 0:
- return ErrorMsgList
-
- Db = GetDB()
- FileTable = 'Identifier' + str(FileID)
- SqlStatement = """ select Modifier, ID, StartLine, StartColumn, EndLine, Value
- 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
- Result0 = Result[0]
- if Result0.upper().startswith('STATIC'):
- Result0 = Result0[6:].strip()
- Index = Result0.find(TypeStart)
- if Index != 0 or Result[3] != 0:
- PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '[%s] Return Type should appear at the start of line' % FuncName, FileTable, Result[1])
-
- if Result[2] == Result[4]:
- PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '[%s] Return Type should appear on its own line' % FuncName, FileTable, Result[1])
-
- SqlStatement = """ select Modifier, ID, StartLine, StartColumn, FunNameStartLine, Name
- from Function
- where BelongsToFile = %d
- """ % (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
- Result0 = Result[0]
- if Result0.upper().startswith('STATIC'):
- Result0 = Result0[6:].strip()
- Index = Result0.find(ReturnType)
- if Index != 0 or Result[3] != 0:
- PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '[%s] Return Type should appear at the start of line' % FuncName, 'Function', Result[1])
-
-def CheckFuncLayoutModifier(FullFileName):
- ErrorMsgList = []
-
- FileID = GetTableID(FullFileName, ErrorMsgList)
- if FileID < 0:
- return ErrorMsgList
-
- 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]
- Result0 = Result[0]
- if Result0.upper().startswith('STATIC'):
- Result0 = Result0[6:].strip()
- Index = Result0.find(TypeStart)
- if Index != 0:
- PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_OPTIONAL_FUNCTIONAL_MODIFIER, '', FileTable, Result[1])
-
- SqlStatement = """ select Modifier, ID
- from Function
- where BelongsToFile = %d
- """ % (FileID)
- ResultSet = Db.TblFile.Exec(SqlStatement)
- for Result in ResultSet:
- ReturnType = GetDataTypeFromModifier(Result[0])
- TypeStart = ReturnType.split()[0]
- Result0 = Result[0]
- if Result0.upper().startswith('STATIC'):
- Result0 = Result0[6:].strip()
- Index = Result0.find(TypeStart)
- if Index != 0:
- PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_OPTIONAL_FUNCTIONAL_MODIFIER, '', 'Function', Result[1])
-
-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
-
- 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:
- PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Empty line appears before Parameter %s.' % Param.Name, FileTable, Result[1])
- if not Pattern.match(Param.Name) and not Param.Name in ParamIgnoreList and not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Param.Name):
- PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Parameter [%s] NOT follow naming convention.' % Param.Name, FileTable, Result[1])
- StartLine = Param.StartLine
-
- if not Result[0].endswith('\n )') and not Result[0].endswith('\r )'):
- PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, '\')\' should be on a new line and indented two spaces', FileTable, Result[1])
-
- SqlStatement = """ select Modifier, ID, FunNameStartColumn, Name
- from Function
- where BelongsToFile = %d
- """ % (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 = []
-
- FileID = GetTableID(FullFileName, ErrorMsgList)
- if FileID < 0:
- return ErrorMsgList
-
- 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
-
- FuncDefList = []
- for Result in ResultSet:
- FuncDefList.append(Result)
-
- 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)
-
- 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])
- if len(ParamListOfDef) != len(ParamListOfDecl) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_2, FuncName):
- PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_2, 'Parameter number different in function [%s].' % FuncName, 'Function', FuncDef[3])
- break
-
- Index = 0
- while Index < len(ParamListOfDef):
- if DiffModifier(ParamListOfDef[Index].Modifier, ParamListOfDecl[Index].Modifier) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_3, FuncName):
- PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_3, 'Parameter %s has different modifier with prototype in function [%s].' % (ParamListOfDef[Index].Name, FuncName), 'Function', FuncDef[3])
- Index += 1
- break
- else:
- UndeclFuncList.append(FuncDef)
-
- IncludeFileList = GetAllIncludeFiles(FullFileName)
- FuncDeclList = []
- for F in IncludeFileList:
- FileID = GetTableID(F, ErrorMsgList)
- if FileID < 0:
- continue
-
- FileTable = 'Identifier' + str(FileID)
- SqlStatement = """ select Modifier, Name, ID
- from %s
- where Model = %d
- """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)
- ResultSet = Db.TblFile.Exec(SqlStatement)
-
- for Result in ResultSet:
- FuncDeclList.append(Result)
-
- 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])
- if len(ParamListOfDef) != len(ParamListOfDecl) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_2, FuncName):
- PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_2, 'Parameter number different in function [%s].' % FuncName, 'Function', FuncDef[3])
- break
-
- Index = 0
- while Index < len(ParamListOfDef):
- if DiffModifier(ParamListOfDef[Index].Modifier, ParamListOfDecl[Index].Modifier) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_3, FuncName):
- PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_3, 'Parameter %s has different modifier with prototype in function [%s].' % (ParamListOfDef[Index].Name, FuncName), 'Function', FuncDef[3])
- Index += 1
- break
-
-def CheckFuncLayoutBody(FullFileName):
- ErrorMsgList = []
-
- FileID = GetTableID(FullFileName, ErrorMsgList)
- if FileID < 0:
- return ErrorMsgList
-
- FileTable = 'Identifier' + str(FileID)
- Db = GetDB()
- SqlStatement = """ select BodyStartColumn, EndColumn, ID
- 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 = []
-
- FileID = GetTableID(FullFileName, ErrorMsgList)
- if FileID < 0:
- return ErrorMsgList
-
- 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)
-
- for F in FL:
- SqlStatement = """ select Name, Value, ID, Modifier
- from %s
- where Model = %d and BelongsToFunction = %d
- """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE, F[0])
- ResultSet = Db.TblFile.Exec(SqlStatement)
- if len(ResultSet) == 0:
- continue
-
- for Result in ResultSet:
- if len(Result[1]) > 0 and 'CONST' not in Result[3]:
- PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_NO_INIT_OF_VARIABLE, 'Variable Name: %s' % Result[0], FileTable, Result[2])
-
-def CheckMemberVariableFormat(Name, Value, FileTable, TdId, ModelId):
- ErrMsgList = []
- # Member variable format pattern.
- Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$')
-
- LBPos = Value.find('{')
- RBPos = Value.rfind('}')
- if LBPos == -1 or RBPos == -1:
- return ErrMsgList
-
- Fields = Value[LBPos + 1 : RBPos]
- Fields = StripComments(Fields).strip()
- NestPos = Fields.find ('struct')
- if NestPos != -1 and (NestPos + len('struct') < len(Fields)) and ModelId != DataClass.MODEL_IDENTIFIER_UNION:
- if not Fields[NestPos + len('struct') + 1].isalnum():
- if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, Name):
- PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, 'Nested struct in [%s].' % (Name), FileTable, TdId)
- 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
-
- 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]
-
- if Field.find('(') != -1:
- QuoteCount += 1
- RemoveCurrentElement = True
- Index += 1
- continue
-
- if Field.find(')') != -1 and QuoteCount > 0:
- QuoteCount -= 1
-
- if RemoveCurrentElement:
- FieldsList.remove(Field)
- if QuoteCount == 0:
- RemoveCurrentElement = False
- continue
-
- if QuoteCount == 0:
- RemoveCurrentElement = False
-
- Index += 1
- else:
- FieldsList = Fields.split(';')
-
- for Field in FieldsList:
- Field = Field.strip()
- if Field == '':
- continue
- # For the condition that the field in struct is an array with [] sufixes...
- 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]
-
- Field = Field.strip()
- if Field == '':
- continue
- if Field.startswith("#"):
- continue
- # Enum could directly assign value to variable
- Field = Field.split('=')[0].strip()
- TokenList = Field.split()
- # Remove pointers before variable
- Token = TokenList[-1]
- if Token in ['OPTIONAL']:
- Token = TokenList[-2]
- if not Pattern.match(Token.lstrip('*')):
- ErrMsgList.append(Token.lstrip('*'))
-
- return ErrMsgList
-
-def CheckDeclTypedefFormat(FullFileName, ModelId):
- ErrorMsgList = []
-
- FileID = GetTableID(FullFileName, ErrorMsgList)
- if FileID < 0:
- return ErrorMsgList
-
- Db = GetDB()
- FileTable = 'Identifier' + str(FileID)
- SqlStatement = """ select Name, StartLine, EndLine, ID, Value
- from %s
- where Model = %d
- """ % (FileTable, ModelId)
- ResultSet = Db.TblFile.Exec(SqlStatement)
- ResultList = []
- for Result in ResultSet:
- ResultList.append(Result)
-
- ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_ALL
- if ModelId == DataClass.MODEL_IDENTIFIER_STRUCTURE:
- ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_STRUCTURE_DECLARATION
- 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
-
- 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
-
- if ValueModelId != ModelId:
- continue
- # Check member variable format.
- ErrMsgList = CheckMemberVariableFormat(Name, Value, FileTable, Td[5], ModelId)
- for ErrMsg in ErrMsgList:
- if EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Name + '.' + ErrMsg):
- continue
- PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Member variable [%s] NOT follow naming convention.' % (Name + '.' + ErrMsg), FileTable, Td[5])
-
- # First check in current file to see whether struct/union/enum is typedef-ed.
- UntypedefedList = []
- for Result in ResultList:
- # 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
-
- if ValueModelId != ModelId:
- continue
- ErrMsgList = CheckMemberVariableFormat(Name, Value, FileTable, Result[3], ModelId)
- for ErrMsg in ErrMsgList:
- if EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Result[0] + '.' + ErrMsg):
- continue
- PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Member variable [%s] NOT follow naming convention.' % (Result[0] + '.' + ErrMsg), FileTable, Result[3])
- # Check whether it is typedefed.
- 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
-
- if not Found:
- UntypedefedList.append(Result)
- continue
-
- if len(UntypedefedList) == 0:
- return
-
- IncludeFileList = GetAllIncludeFiles(FullFileName)
- TdList = []
- for F in IncludeFileList:
- FileID = GetTableID(F, ErrorMsgList)
- if FileID < 0:
- continue
-
- IncludeFileTable = 'Identifier' + str(FileID)
- SqlStatement = """ select Modifier, Name, Value, StartLine, EndLine, ID
- from %s
- where Model = %d
- """ % (IncludeFileTable, DataClass.MODEL_IDENTIFIER_TYPEDEF)
- ResultSet = Db.TblFile.Exec(SqlStatement)
- TdList.extend(ResultSet)
-
- for Result in UntypedefedList:
-
- # Check whether it is typedefed.
- Found = False
- for Td in TdList:
-
- if len(Td[0]) > 0:
- continue
- if Result[1] >= Td[3] and Td[4] >= Result[2]:
- 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
-
- if not Found:
- PrintErrorMsg(ErrorType, 'No Typedef for %s' % Result[0], FileTable, Result[3])
- continue
-
-def CheckDeclStructTypedef(FullFileName):
- CheckDeclTypedefFormat(FullFileName, DataClass.MODEL_IDENTIFIER_STRUCTURE)
-
-def CheckDeclEnumTypedef(FullFileName):
- CheckDeclTypedefFormat(FullFileName, DataClass.MODEL_IDENTIFIER_ENUMERATE)
-
-def CheckDeclUnionTypedef(FullFileName):
- CheckDeclTypedefFormat(FullFileName, DataClass.MODEL_IDENTIFIER_UNION)
-
-def CheckDeclArgModifier(FullFileName):
- ErrorMsgList = []
-
- FileID = GetTableID(FullFileName, ErrorMsgList)
- if FileID < 0:
- return ErrorMsgList
-
- Db = GetDB()
- FileTable = 'Identifier' + str(FileID)
- SqlStatement = """ select Modifier, Name, ID
- 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
-
- 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
-
- 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 = []
-
- FileID = GetTableID(FullFileName, ErrorMsgList)
- if FileID < 0:
- return ErrorMsgList
-
- 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
-
- 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])
-
- for Param in ParamList:
- if PatternInModifier(Param.Modifier, Type):
- PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, 'Parameter %s' % Param.Name, FileTable, Result[2])
-
- SqlStatement = """ select Modifier, Header, ID, Name
- from Function
- where BelongsToFile = %d
- """ % (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])
-
- for Param in ParamList:
- if PatternInModifier(Param.Modifier, Type):
- PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, 'Parameter %s' % Param.Name, FileTable, Result[2])
-
-
-def CheckPointerNullComparison(FullFileName):
- ErrorMsgList = []
-
- FileID = GetTableID(FullFileName, ErrorMsgList)
- if FileID < 0:
- return ErrorMsgList
-
- # cache the found function return type to accelerate later checking in this file.
- FuncReturnTypeDict = {}
-
- Db = GetDB()
- FileTable = 'Identifier' + str(FileID)
- SqlStatement = """ select Value, StartLine, ID
- 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]])
-
- 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]])
-
- p = GetFuncDeclPattern()
- for Str in PSL:
- FuncRecord = GetFuncContainsPE(Str[1], FL)
- if FuncRecord == None:
- continue
-
- 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.
- if TmpStr.startswith(PredVarStr):
- IsFuncCall = True
-
- 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:
- if Type.find('*') != -1 and Type != 'BOOLEAN*':
- PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])
- continue
-
- if PredVarStr in FuncReturnTypeDict:
- continue
-
- Type = GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall, None, StarList)
- if SearchInCache:
- FuncReturnTypeDict[PredVarStr] = Type
- if Type == None:
- continue
- Type = GetTypeFromArray(Type, PredVarStr)
- if Type.find('*') != -1 and Type != 'BOOLEAN*':
- PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])
-
-def CheckNonBooleanValueComparison(FullFileName):
- ErrorMsgList = []
-
- FileID = GetTableID(FullFileName, ErrorMsgList)
- if FileID < 0:
- return ErrorMsgList
-
- # cache the found function return type to accelerate later checking in this file.
- FuncReturnTypeDict = {}
-
- Db = GetDB()
- FileTable = 'Identifier' + str(FileID)
- SqlStatement = """ select Value, StartLine, ID
- 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]])
-
- 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]])
-
- p = GetFuncDeclPattern()
- for Str in PSL:
- FuncRecord = GetFuncContainsPE(Str[1], FL)
- if FuncRecord == None:
- continue
-
- 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.
- if TmpStr.startswith(PredVarStr):
- IsFuncCall = True
-
- 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:
- if Type.find('BOOLEAN') == -1:
- PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR, 'Predicate Expression: %s' % Exp, FileTable, Str[2])
- continue
-
- if PredVarStr in FuncReturnTypeDict:
- continue
- Type = GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall, 'BOOLEAN', StarList)
- if SearchInCache:
- FuncReturnTypeDict[PredVarStr] = Type
- if Type == None:
- continue
- if Type.find('BOOLEAN') == -1:
- PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR, 'Predicate Expression: %s' % Exp, FileTable, Str[2])
-
-
-def CheckBooleanValueComparison(FullFileName):
- ErrorMsgList = []
-
- FileID = GetTableID(FullFileName, ErrorMsgList)
- if FileID < 0:
- return ErrorMsgList
-
- # cache the found function return type to accelerate later checking in this file.
- FuncReturnTypeDict = {}
-
- Db = GetDB()
- FileTable = 'Identifier' + str(FileID)
- SqlStatement = """ select Value, StartLine, ID
- 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]])
-
- 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]])
-
- p = GetFuncDeclPattern()
- for Str in PSL:
- FuncRecord = GetFuncContainsPE(Str[1], FL)
- if FuncRecord == None:
- continue
-
- 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.
- if TmpStr.startswith(PredVarStr):
- IsFuncCall = True
-
- 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:
- if Type.find('BOOLEAN') != -1:
- PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])
- continue
-
- if PredVarStr in FuncReturnTypeDict:
- continue
-
- Type = GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall, 'BOOLEAN', StarList)
- if SearchInCache:
- FuncReturnTypeDict[PredVarStr] = Type
- if Type == None:
- continue
- if Type.find('BOOLEAN') != -1:
- PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])
-
-
-def CheckHeaderFileData(FullFileName):
- ErrorMsgList = []
-
- FileID = GetTableID(FullFileName, ErrorMsgList)
- if FileID < 0:
- return ErrorMsgList
-
- Db = GetDB()
- FileTable = 'Identifier' + str(FileID)
- SqlStatement = """ select ID, Modifier
- 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])
-
- 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 = []
-
- FileID = GetTableID(FullFileName, ErrorMsgList)
- if FileID < 0:
- return ErrorMsgList
-
- 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
-
- 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 = []
-
- FileID = GetTableID(FullFileName, ErrorMsgList)
- if FileID < 0:
- return ErrorMsgList
-
- 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', 'endcode', 'code']
- 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 not Part.replace('@', '').strip():
- continue
- if Part.lstrip('@') in ['{', '}']:
- continue
- if Part.lstrip('@').isalpha():
- if Part.lstrip('@') not in DoxygenCommandList:
- PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Unknown doxygen command %s' % Part, FileTable, Result[1])
- 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])
-
-
-def CheckDoxygenTripleForwardSlash(FullFileName):
- ErrorMsgList = []
-
- FileID = GetTableID(FullFileName, ErrorMsgList)
- if FileID < 0:
- return ErrorMsgList
-
- Db = GetDB()
-
- SqlStatement = """ select ID, BodyStartLine, BodyStartColumn, EndLine, EndColumn
- from Function
- where BelongsToFile = %d
- """ % (FileID)
- ResultSet = Db.TblFile.Exec(SqlStatement)
- if len(ResultSet) == 0:
- return
-
- FuncDefSet = []
- for Result in ResultSet:
- FuncDefSet.append(Result)
-
-
- FileTable = 'Identifier' + str(FileID)
- SqlStatement = """ select Value, ID, StartLine, StartColumn, EndLine, EndColumn
- from %s
- where Model = %d
-
- """ % (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
-
-
- for Result in CommentSet:
- CommentStr = Result[0]
- StartLine = Result[2]
- StartColumn = Result[3]
- EndLine = Result[4]
- EndColumn = Result[5]
- if not CommentStr.startswith('///<'):
- continue
-
- Found = False
- for FuncDef in FuncDefSet:
- if StartLine == FuncDef[1] and StartColumn > FuncDef[2] and EndLine == FuncDef[3] and EndColumn < FuncDef[4]:
- 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 = []
-
- FileID = GetTableID(FullFileName, ErrorMsgList)
- if FileID < 0:
- return ErrorMsgList
-
- Db = GetDB()
- FileTable = 'Identifier' + str(FileID)
- SqlStatement = """ select Value, ID
- from %s
- where Model = %d and (StartLine = 1 or StartLine = 7 or StartLine = 8) and StartColumn = 0
- """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT)
- ResultSet = Db.TblFile.Exec(SqlStatement)
- if len(ResultSet) == 0:
- PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'No File License header appear at the very beginning of file.', 'File', FileID)
- return ErrorMsgList
-
- NoHeaderCommentStartFlag = True
- NoHeaderCommentEndFlag = True
- NoHeaderCommentPeriodFlag = True
- NoCopyrightFlag = True
- NoLicenseFlag = True
- NoRevReferFlag = True
- NextLineIndex = 0
- for Result in ResultSet:
- FileStartFlag = False
- CommentStrList = []
- CommentStr = Result[0].strip()
- CommentStrListTemp = CommentStr.split('\n')
- if (len(CommentStrListTemp) <= 1):
- # For Mac
- CommentStrListTemp = CommentStr.split('\r')
- # Skip the content before the file header
- for CommentLine in CommentStrListTemp:
- if CommentLine.strip().startswith('/** @file'):
- FileStartFlag = True
- if FileStartFlag == True:
- CommentStrList.append(CommentLine)
-
- ID = Result[1]
- Index = 0
- if CommentStrList and CommentStrList[0].strip().startswith('/** @file'):
- NoHeaderCommentStartFlag = False
- else:
- continue
- if CommentStrList and CommentStrList[-1].strip().endswith('**/'):
- NoHeaderCommentEndFlag = False
- else:
- continue
-
- for CommentLine in CommentStrList:
- Index = Index + 1
- NextLineIndex = Index
- if CommentLine.startswith('/** @file'):
- continue
- if CommentLine.startswith('**/'):
- break
- # Check whether C File header Comment content start with two spaces.
- if EccGlobalData.gConfig.HeaderCheckCFileCommentStartSpacesNum == '1' or EccGlobalData.gConfig.HeaderCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
- if CommentLine.startswith('/** @file') == False and CommentLine.startswith('**/') == False and CommentLine.strip() and CommentLine.startswith(' ') == False:
- PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment content should start with two spaces at each line', FileTable, ID)
-
- CommentLine = CommentLine.strip()
- if CommentLine.startswith('Copyright'):
- NoCopyrightFlag = False
- if CommentLine.find('All rights reserved') == -1:
- for Copyright in EccGlobalData.gConfig.Copyright:
- if CommentLine.find(Copyright) > -1:
- PrintErrorMsg(ERROR_HEADER_CHECK_FILE, '""All rights reserved"" announcement should be following the ""Copyright"" at the same line', FileTable, ID)
- break
- if CommentLine.endswith('<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:
- PrintErrorMsg(ERROR_DOXYGEN_CHECK_FILE_HEADER, 'File header comment should begin with ""/** @file""', FileTable, ID)
- return
- if NoHeaderCommentEndFlag:
- PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment should end with ""**/""', FileTable, ID)
- return
- if NoCopyrightFlag:
- PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment missing the ""Copyright""', FileTable, ID)
- #Check whether C File header Comment have the License immediately after the ""Copyright"" line.
- if EccGlobalData.gConfig.HeaderCheckCFileCommentLicenseFormat == '1' or EccGlobalData.gConfig.HeaderCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
- if NoLicenseFlag:
- PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment should have the License immediately after the ""Copyright"" line', FileTable, ID)
-
-def CheckFuncHeaderDoxygenComments(FullFileName):
- ErrorMsgList = []
-
- FileID = GetTableID(FullFileName, ErrorMsgList)
- if FileID < 0:
- return ErrorMsgList
-
- Db = GetDB()
- FileTable = 'Identifier' + str(FileID)
- SqlStatement = """ select Value, StartLine, EndLine, ID
- from %s
- where Model = %d
- """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT)
-
- ResultSet = Db.TblFile.Exec(SqlStatement)
- CommentSet = []
- try:
- for Result in ResultSet:
- CommentSet.append(Result)
- except:
- print 'Unrecognized chars in comment of file %s', FullFileName
-
- # Func Decl check
- SqlStatement = """ select Modifier, Name, StartLine, ID, Value
- from %s
- 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])
-
- # Func Def check
- SqlStatement = """ select Value, StartLine, EndLine, ID
- from %s
- where Model = %d
- """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER)
-
- ResultSet = Db.TblFile.Exec(SqlStatement)
- CommentSet = []
- try:
- for Result in ResultSet:
- CommentSet.append(Result)
- except:
- print 'Unrecognized chars in comment of file %s', FullFileName
-
- SqlStatement = """ select Modifier, Header, StartLine, ID, Name
- from Function
- where BelongsToFile = %d
- """ % (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
-
- Str = ParamTagList[0]
-
- 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
-
- 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
-
- if len(DoxygenStrList) > 0:
- DoxygenStrList[-1] = DoxygenStrList[-1].rstrip('--*/')
-
- return DoxygenStrList
-
-def CheckGeneralDoxygenCommentLayout(Str, StartLine, ErrorMsgList, CommentId= -1, TableName=''):
- #/** --*/ @retval after @param
- if not Str.startswith('/**'):
- ErrorMsgList.append('Line %d : Comment does NOT have prefix /** ' % StartLine)
- 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)
-
-def CheckFunctionHeaderConsistentWithDoxygenComment(FuncModifier, FuncHeader, FuncStartLine, CommentStr, CommentStartLine, ErrorMsgList, CommentId= -1, TableName=''):
-
- ParamList = GetParamList(FuncHeader)
- CheckGeneralDoxygenCommentLayout(CommentStr, CommentStartLine, ErrorMsgList, CommentId, TableName)
- DescriptionStr = CommentStr
- DoxygenStrList = GetDoxygenStrFromComment(DescriptionStr)
- 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')):
- ErrorMsgList.append('Line %d : in Comment, <%s> does NOT end with new line ' % (CommentStartLine, Tag.replace('\n', '').replace('\r', '')))
- PrintErrorMsg(ERROR_HEADER_CHECK_FUNCTION, 'in Comment, <%s> does NOT end with new line ' % (Tag.replace('\n', '').replace('\r', '')), TableName, CommentId)
- TagPartList = Tag.split()
- if len(TagPartList) < 2:
- ErrorMsgList.append('Line %d : in Comment, <%s> does NOT contain doxygen contents ' % (CommentStartLine, Tag.replace('\n', '').replace('\r', '')))
- PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, <%s> does NOT contain doxygen contents ' % (Tag.replace('\n', '').replace('\r', '')), TableName, CommentId)
- Index += 1
- continue
- LBPos = Tag.find('[')
- RBPos = Tag.find(']')
- ParamToLBContent = Tag[len('@param'):LBPos].strip()
- if LBPos > 0 and len(ParamToLBContent) == 0 and RBPos > LBPos:
- InOutStr = ''
- ModifierPartList = ParamModifier.split()
- for Part in ModifierPartList:
- if Part.strip() == 'IN':
- InOutStr += 'in'
- if Part.strip() == 'OUT':
- if InOutStr != '':
- InOutStr += ', out'
- else:
- InOutStr = 'out'
-
- if InOutStr != '':
- if Tag.find('[' + InOutStr + ']') == -1:
- if InOutStr != 'in, out':
- ErrorMsgList.append('Line %d : in Comment, <%s> does NOT have %s ' % (CommentStartLine, (TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), '[' + InOutStr + ']'))
- PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, <%s> does NOT have %s ' % ((TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), '[' + InOutStr + ']'), TableName, CommentId)
- else:
- if Tag.find('[in,out]') == -1:
- ErrorMsgList.append('Line %d : in Comment, <%s> does NOT have %s ' % (CommentStartLine, (TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), '[' + InOutStr + ']'))
- PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, <%s> does NOT have %s ' % ((TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), '[' + InOutStr + ']'), TableName, CommentId)
-
-
- if Tag.find(ParamName) == -1 and ParamName != 'VOID' and ParamName != 'void':
- ErrorMsgList.append('Line %d : in Comment, <%s> does NOT consistent with parameter name %s ' % (CommentStartLine, (TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), ParamName))
- PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, <%s> does NOT consistent with parameter name %s ' % ((TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), ParamName), TableName, CommentId)
- Index += 1
-
- if Index < ParamNumber:
- ErrorMsgList.append('Line %d : Number of doxygen tags in comment less than number of function parameters' % CommentStartLine)
- PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'Number of doxygen tags in comment less than number of function parameters ', TableName, CommentId)
- # VOID return type, NOT VOID*. VOID* should be matched with a doxygen tag.
- if (FuncModifier.find('VOID') != -1 or FuncModifier.find('void') != -1) and FuncModifier.find('*') == -1:
-
- # assume we allow a return description tag for void func. return. that's why 'DoxygenTagNumber - 1' is used instead of 'DoxygenTagNumber'
- if Index < DoxygenTagNumber - 1 or (Index < DoxygenTagNumber and DoxygenStrList[Index].startswith('@retval')):
- ErrorMsgList.append('Line %d : VOID return type need NO doxygen tags in comment' % CommentStartLine)
- PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'VOID return type need no doxygen tags in comment ', TableName, CommentId)
- else:
- if Index < DoxygenTagNumber and not DoxygenStrList[Index].startswith('@retval') and not DoxygenStrList[Index].startswith('@return'):
- ErrorMsgList.append('Line %d : Number of @param doxygen tags in comment does NOT match number of function parameters' % CommentStartLine)
- PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'Number of @param doxygen tags in comment does NOT match number of function parameters ', TableName, CommentId)
- else:
- if ParamNumber == 0 and DoxygenTagNumber != 0 and ((FuncModifier.find('VOID') != -1 or FuncModifier.find('void') != -1) and FuncModifier.find('*') == -1):
- ErrorMsgList.append('Line %d : VOID return type need NO doxygen tags in comment' % CommentStartLine)
- PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'VOID return type need NO doxygen tags in comment ', TableName, CommentId)
- 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)
-# CollectSourceCodeDataIntoDB(sys.argv[1])
- try:
- test_file = sys.argv[1]
- except IndexError, v:
- print "Usage: %s filename" % sys.argv[0]
- sys.exit(1)
- MsgList = CheckFuncHeaderDoxygenComments(test_file)
- for Msg in MsgList:
- print Msg
- print 'Done!'