1. Fix a bug of removing the checkpoint for STATIC modifier 2. Fix a bug of parsing CONST variable Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Hess Chen <hesheng.chen@intel.com> Reviewed-by: YangX Li <yangx.li@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18446 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			2632 lines
		
	
	
		
			110 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			2632 lines
		
	
	
		
			110 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| ## @file
 | |
| # This file is used to be the c coding style checking of ECC tool
 | |
| #
 | |
| # Copyright (c) 2009 - 2015, 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():
 | |
|             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)):
 | |
|         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']
 | |
|     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])
 | |
| 
 | |
| 
 | |
| 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!'
 |