Signed-off-by: Rebecca Cran <quic_rcran@quicinc.com> Reviewed-by: Yuwei Chen <yuwei.chen@intel.com> Reviewed-by: Bob Feng <bob.c.feng@intel.com>
		
			
				
	
	
		
			2655 lines
		
	
	
		
			111 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			2655 lines
		
	
	
		
			111 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
## @file
 | 
						|
# This file is used to be the c coding style checking of ECC tool
 | 
						|
#
 | 
						|
# Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
 | 
						|
# Copyright (c) 2020, Arm Limited. All rights reserved.<BR>
 | 
						|
# SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
#
 | 
						|
 | 
						|
from __future__ import print_function
 | 
						|
from __future__ import absolute_import
 | 
						|
import sys
 | 
						|
import Common.LongFilePathOs as os
 | 
						|
import re
 | 
						|
import string
 | 
						|
from Ecc import CodeFragmentCollector
 | 
						|
from Ecc import FileProfile
 | 
						|
from CommonDataClass import DataClass
 | 
						|
from Ecc import Database
 | 
						|
from Common import EdkLogger
 | 
						|
from Ecc.EccToolError import *
 | 
						|
from Ecc import EccGlobalData
 | 
						|
from Ecc import MetaDataParser
 | 
						|
 | 
						|
IncludeFileListDict = {}
 | 
						|
AllIncludeFileListDict = {}
 | 
						|
IncludePathListDict = {}
 | 
						|
ComplexTypeDict = {}
 | 
						|
SUDict = {}
 | 
						|
IgnoredKeywordList = ['EFI_ERROR']
 | 
						|
 | 
						|
def GetIgnoredDirListPattern():
 | 
						|
    skipList = list(EccGlobalData.gConfig.SkipDirList) + ['.svn']
 | 
						|
    DirString = '|'.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 len(List) < 2:
 | 
						|
        pass
 | 
						|
    elif List[1] == 'include':
 | 
						|
        Type = DataClass.MODEL_IDENTIFIER_INCLUDE
 | 
						|
    elif List[1] == 'define':
 | 
						|
        Type = DataClass.MODEL_IDENTIFIER_MACRO_DEFINE
 | 
						|
    elif List[1] == 'ifdef':
 | 
						|
        Type = DataClass.MODEL_IDENTIFIER_MACRO_IFDEF
 | 
						|
    elif List[1] == 'ifndef':
 | 
						|
        Type = DataClass.MODEL_IDENTIFIER_MACRO_IFNDEF
 | 
						|
    elif List[1] == 'endif':
 | 
						|
        Type = DataClass.MODEL_IDENTIFIER_MACRO_ENDIF
 | 
						|
    elif List[1] == 'pragma':
 | 
						|
        Type = DataClass.MODEL_IDENTIFIER_MACRO_PROGMA
 | 
						|
    else:
 | 
						|
        Type = DataClass.MODEL_UNKNOWN
 | 
						|
    return Type
 | 
						|
 | 
						|
def SuOccurInTypedef (Su, TdList):
 | 
						|
    for Td in TdList:
 | 
						|
        if Su.StartPos[0] == Td.StartPos[0] and Su.EndPos[0] == Td.EndPos[0]:
 | 
						|
            return True
 | 
						|
    return False
 | 
						|
 | 
						|
def GetIdentifierList():
 | 
						|
    IdList = []
 | 
						|
    for comment in FileProfile.CommentList:
 | 
						|
        IdComment = DataClass.IdentifierClass(-1, '', '', '', comment.Content, DataClass.MODEL_IDENTIFIER_COMMENT, -1, -1, comment.StartPos[0], comment.StartPos[1], comment.EndPos[0], comment.EndPos[1])
 | 
						|
        IdList.append(IdComment)
 | 
						|
 | 
						|
    for pp in FileProfile.PPDirectiveList:
 | 
						|
        Type = GetIdType(pp.Content)
 | 
						|
        IdPP = DataClass.IdentifierClass(-1, '', '', '', pp.Content, Type, -1, -1, pp.StartPos[0], pp.StartPos[1], pp.EndPos[0], pp.EndPos[1])
 | 
						|
        IdList.append(IdPP)
 | 
						|
 | 
						|
    for pe in FileProfile.PredicateExpressionList:
 | 
						|
        IdPE = DataClass.IdentifierClass(-1, '', '', '', pe.Content, DataClass.MODEL_IDENTIFIER_PREDICATE_EXPRESSION, -1, -1, pe.StartPos[0], pe.StartPos[1], pe.EndPos[0], pe.EndPos[1])
 | 
						|
        IdList.append(IdPE)
 | 
						|
 | 
						|
    FuncDeclPattern = GetFuncDeclPattern()
 | 
						|
    ArrayPattern = GetArrayPattern()
 | 
						|
    for var in FileProfile.VariableDeclarationList:
 | 
						|
        DeclText = var.Declarator.lstrip()
 | 
						|
        FuncPointerPattern = GetTypedefFuncPointerPattern()
 | 
						|
        if FuncPointerPattern.match(DeclText):
 | 
						|
            continue
 | 
						|
        VarNameStartLine = var.NameStartPos[0]
 | 
						|
        VarNameStartColumn = var.NameStartPos[1]
 | 
						|
        FirstChar = DeclText[0]
 | 
						|
        while not FirstChar.isalpha() and FirstChar != '_':
 | 
						|
            if FirstChar == '*':
 | 
						|
                var.Modifier += '*'
 | 
						|
                VarNameStartColumn += 1
 | 
						|
                DeclText = DeclText.lstrip('*')
 | 
						|
            elif FirstChar == '\r':
 | 
						|
                DeclText = DeclText.lstrip('\r\n').lstrip('\r')
 | 
						|
                VarNameStartLine += 1
 | 
						|
                VarNameStartColumn = 0
 | 
						|
            elif FirstChar == '\n':
 | 
						|
                DeclText = DeclText.lstrip('\n')
 | 
						|
                VarNameStartLine += 1
 | 
						|
                VarNameStartColumn = 0
 | 
						|
            elif FirstChar == ' ':
 | 
						|
                DeclText = DeclText.lstrip(' ')
 | 
						|
                VarNameStartColumn += 1
 | 
						|
            elif FirstChar == '\t':
 | 
						|
                DeclText = DeclText.lstrip('\t')
 | 
						|
                VarNameStartColumn += 8
 | 
						|
            else:
 | 
						|
                DeclText = DeclText[1:]
 | 
						|
                VarNameStartColumn += 1
 | 
						|
            FirstChar = DeclText[0]
 | 
						|
 | 
						|
        var.Declarator = DeclText
 | 
						|
        if FuncDeclPattern.match(var.Declarator):
 | 
						|
            DeclSplitList = var.Declarator.split('(')
 | 
						|
            FuncName = DeclSplitList[0].strip()
 | 
						|
            FuncNamePartList = FuncName.split()
 | 
						|
            if len(FuncNamePartList) > 1:
 | 
						|
                FuncName = FuncNamePartList[-1].strip()
 | 
						|
                NameStart = DeclSplitList[0].rfind(FuncName)
 | 
						|
                var.Declarator = var.Declarator[NameStart:]
 | 
						|
                if NameStart > 0:
 | 
						|
                    var.Modifier += ' ' + DeclSplitList[0][0:NameStart]
 | 
						|
                    Index = 0
 | 
						|
                    PreChar = ''
 | 
						|
                    while Index < NameStart:
 | 
						|
                        FirstChar = DeclSplitList[0][Index]
 | 
						|
                        if DeclSplitList[0][Index:].startswith('EFIAPI'):
 | 
						|
                            Index += 6
 | 
						|
                            VarNameStartColumn += 6
 | 
						|
                            PreChar = ''
 | 
						|
                            continue
 | 
						|
                        elif FirstChar == '\r':
 | 
						|
                            Index += 1
 | 
						|
                            VarNameStartLine += 1
 | 
						|
                            VarNameStartColumn = 0
 | 
						|
                        elif FirstChar == '\n':
 | 
						|
                            Index += 1
 | 
						|
                            if PreChar != '\r':
 | 
						|
                                VarNameStartLine += 1
 | 
						|
                                VarNameStartColumn = 0
 | 
						|
                        elif FirstChar == ' ':
 | 
						|
                            Index += 1
 | 
						|
                            VarNameStartColumn += 1
 | 
						|
                        elif FirstChar == '\t':
 | 
						|
                            Index += 1
 | 
						|
                            VarNameStartColumn += 8
 | 
						|
                        else:
 | 
						|
                            Index += 1
 | 
						|
                            VarNameStartColumn += 1
 | 
						|
                        PreChar = FirstChar
 | 
						|
            IdVar = DataClass.IdentifierClass(-1, var.Modifier, '', var.Declarator, FuncName, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION, -1, -1, var.StartPos[0], var.StartPos[1], VarNameStartLine, VarNameStartColumn)
 | 
						|
            IdList.append(IdVar)
 | 
						|
            continue
 | 
						|
 | 
						|
        if var.Declarator.find('{') == -1:
 | 
						|
            for decl in var.Declarator.split(','):
 | 
						|
                DeclList = decl.split('=')
 | 
						|
                Name = DeclList[0].strip()
 | 
						|
                if ArrayPattern.match(Name):
 | 
						|
                    LSBPos = var.Declarator.find('[')
 | 
						|
                    var.Modifier += ' ' + Name[LSBPos:]
 | 
						|
                    Name = Name[0:LSBPos]
 | 
						|
 | 
						|
                IdVar = DataClass.IdentifierClass(-1, var.Modifier, '', Name, (len(DeclList) > 1 and [DeclList[1]]or [''])[0], DataClass.MODEL_IDENTIFIER_VARIABLE, -1, -1, var.StartPos[0], var.StartPos[1], VarNameStartLine, VarNameStartColumn)
 | 
						|
                IdList.append(IdVar)
 | 
						|
        else:
 | 
						|
            DeclList = var.Declarator.split('=')
 | 
						|
            Name = DeclList[0].strip()
 | 
						|
            if ArrayPattern.match(Name):
 | 
						|
                LSBPos = var.Declarator.find('[')
 | 
						|
                var.Modifier += ' ' + Name[LSBPos:]
 | 
						|
                Name = Name[0:LSBPos]
 | 
						|
            IdVar = DataClass.IdentifierClass(-1, var.Modifier, '', Name, (len(DeclList) > 1 and [DeclList[1]]or [''])[0], DataClass.MODEL_IDENTIFIER_VARIABLE, -1, -1, var.StartPos[0], var.StartPos[1], VarNameStartLine, VarNameStartColumn)
 | 
						|
            IdList.append(IdVar)
 | 
						|
 | 
						|
    for enum in FileProfile.EnumerationDefinitionList:
 | 
						|
        LBPos = enum.Content.find('{')
 | 
						|
        RBPos = enum.Content.find('}')
 | 
						|
        Name = enum.Content[4:LBPos].strip()
 | 
						|
        Value = enum.Content[LBPos + 1:RBPos]
 | 
						|
        IdEnum = DataClass.IdentifierClass(-1, '', '', Name, Value, DataClass.MODEL_IDENTIFIER_ENUMERATE, -1, -1, enum.StartPos[0], enum.StartPos[1], enum.EndPos[0], enum.EndPos[1])
 | 
						|
        IdList.append(IdEnum)
 | 
						|
 | 
						|
    for su in FileProfile.StructUnionDefinitionList:
 | 
						|
        if SuOccurInTypedef(su, FileProfile.TypedefDefinitionList):
 | 
						|
            continue
 | 
						|
        Type = DataClass.MODEL_IDENTIFIER_STRUCTURE
 | 
						|
        SkipLen = 6
 | 
						|
        if su.Content.startswith('union'):
 | 
						|
            Type = DataClass.MODEL_IDENTIFIER_UNION
 | 
						|
            SkipLen = 5
 | 
						|
        LBPos = su.Content.find('{')
 | 
						|
        RBPos = su.Content.find('}')
 | 
						|
        if LBPos == -1 or RBPos == -1:
 | 
						|
            Name = su.Content[SkipLen:].strip()
 | 
						|
            Value = ''
 | 
						|
        else:
 | 
						|
            Name = su.Content[SkipLen:LBPos].strip()
 | 
						|
            Value = su.Content[LBPos:RBPos + 1]
 | 
						|
        IdPE = DataClass.IdentifierClass(-1, '', '', Name, Value, Type, -1, -1, su.StartPos[0], su.StartPos[1], su.EndPos[0], su.EndPos[1])
 | 
						|
        IdList.append(IdPE)
 | 
						|
 | 
						|
    TdFuncPointerPattern = GetTypedefFuncPointerPattern()
 | 
						|
    for td in FileProfile.TypedefDefinitionList:
 | 
						|
        Modifier = ''
 | 
						|
        Name = td.ToType
 | 
						|
        Value = td.FromType
 | 
						|
        if TdFuncPointerPattern.match(td.ToType):
 | 
						|
            Modifier = td.FromType
 | 
						|
            LBPos = td.ToType.find('(')
 | 
						|
            TmpStr = td.ToType[LBPos + 1:].strip()
 | 
						|
            StarPos = TmpStr.find('*')
 | 
						|
            if StarPos != -1:
 | 
						|
                Modifier += ' ' + TmpStr[0:StarPos]
 | 
						|
            while TmpStr[StarPos] == '*':
 | 
						|
#                Modifier += ' ' + '*'
 | 
						|
                StarPos += 1
 | 
						|
            TmpStr = TmpStr[StarPos:].strip()
 | 
						|
            RBPos = TmpStr.find(')')
 | 
						|
            Name = TmpStr[0:RBPos]
 | 
						|
            Value = 'FP' + TmpStr[RBPos + 1:]
 | 
						|
        else:
 | 
						|
            while Name.startswith('*'):
 | 
						|
                Value += ' ' + '*'
 | 
						|
                Name = Name.lstrip('*').strip()
 | 
						|
 | 
						|
        if Name.find('[') != -1:
 | 
						|
            LBPos = Name.find('[')
 | 
						|
            RBPos = Name.rfind(']')
 | 
						|
            Value += Name[LBPos : RBPos + 1]
 | 
						|
            Name = Name[0 : LBPos]
 | 
						|
 | 
						|
        IdTd = DataClass.IdentifierClass(-1, Modifier, '', Name, Value, DataClass.MODEL_IDENTIFIER_TYPEDEF, -1, -1, td.StartPos[0], td.StartPos[1], td.EndPos[0], td.EndPos[1])
 | 
						|
        IdList.append(IdTd)
 | 
						|
 | 
						|
    for funcCall in FileProfile.FunctionCallingList:
 | 
						|
        IdFC = DataClass.IdentifierClass(-1, '', '', funcCall.FuncName, funcCall.ParamList, DataClass.MODEL_IDENTIFIER_FUNCTION_CALLING, -1, -1, funcCall.StartPos[0], funcCall.StartPos[1], funcCall.EndPos[0], funcCall.EndPos[1])
 | 
						|
        IdList.append(IdFC)
 | 
						|
    return IdList
 | 
						|
 | 
						|
def StripNonAlnumChars(Str):
 | 
						|
    StrippedStr = ''
 | 
						|
    for Char in Str:
 | 
						|
        if Char.isalnum() or Char == '_':
 | 
						|
            StrippedStr += Char
 | 
						|
    return StrippedStr
 | 
						|
 | 
						|
def GetParamList(FuncDeclarator, FuncNameLine=0, FuncNameOffset=0):
 | 
						|
    FuncDeclarator = StripComments(FuncDeclarator)
 | 
						|
    ParamIdList = []
 | 
						|
    #DeclSplitList = FuncDeclarator.split('(')
 | 
						|
    LBPos = FuncDeclarator.find('(')
 | 
						|
    #if len(DeclSplitList) < 2:
 | 
						|
    if LBPos == -1:
 | 
						|
        return ParamIdList
 | 
						|
    #FuncName = DeclSplitList[0]
 | 
						|
    FuncName = FuncDeclarator[0:LBPos]
 | 
						|
    #ParamStr = DeclSplitList[1].rstrip(')')
 | 
						|
    ParamStr = FuncDeclarator[LBPos + 1:].rstrip(')')
 | 
						|
    LineSkipped = 0
 | 
						|
    OffsetSkipped = 0
 | 
						|
    TailChar = FuncName[-1]
 | 
						|
    while not TailChar.isalpha() and TailChar != '_':
 | 
						|
 | 
						|
        if TailChar == '\n':
 | 
						|
            FuncName = FuncName.rstrip('\r\n').rstrip('\n')
 | 
						|
            LineSkipped += 1
 | 
						|
            OffsetSkipped = 0
 | 
						|
        elif TailChar == '\r':
 | 
						|
            FuncName = FuncName.rstrip('\r')
 | 
						|
            LineSkipped += 1
 | 
						|
            OffsetSkipped = 0
 | 
						|
        elif TailChar == ' ':
 | 
						|
            FuncName = FuncName.rstrip(' ')
 | 
						|
            OffsetSkipped += 1
 | 
						|
        elif TailChar == '\t':
 | 
						|
            FuncName = FuncName.rstrip('\t')
 | 
						|
            OffsetSkipped += 8
 | 
						|
        else:
 | 
						|
            FuncName = FuncName[:-1]
 | 
						|
        TailChar = FuncName[-1]
 | 
						|
 | 
						|
    OffsetSkipped += 1 #skip '('
 | 
						|
 | 
						|
    for p in ParamStr.split(','):
 | 
						|
        ListP = p.split()
 | 
						|
        if len(ListP) == 0:
 | 
						|
            continue
 | 
						|
        ParamName = ListP[-1]
 | 
						|
        DeclText = ParamName.strip()
 | 
						|
        RightSpacePos = p.rfind(ParamName)
 | 
						|
        ParamModifier = p[0:RightSpacePos]
 | 
						|
        if ParamName == 'OPTIONAL':
 | 
						|
            if ParamModifier == '':
 | 
						|
                ParamModifier += ' ' + 'OPTIONAL'
 | 
						|
                DeclText = ''
 | 
						|
            else:
 | 
						|
                ParamName = ListP[-2]
 | 
						|
                DeclText = ParamName.strip()
 | 
						|
                RightSpacePos = p.rfind(ParamName)
 | 
						|
                ParamModifier = p[0:RightSpacePos]
 | 
						|
                ParamModifier += 'OPTIONAL'
 | 
						|
        while DeclText.startswith('*'):
 | 
						|
            ParamModifier += ' ' + '*'
 | 
						|
            DeclText = DeclText.lstrip('*').strip()
 | 
						|
        ParamName = DeclText
 | 
						|
        # ignore array length if exists.
 | 
						|
        LBIndex = ParamName.find('[')
 | 
						|
        if LBIndex != -1:
 | 
						|
            ParamName = ParamName[0:LBIndex]
 | 
						|
 | 
						|
        Start = RightSpacePos
 | 
						|
        Index = 0
 | 
						|
        PreChar = ''
 | 
						|
        while Index < Start:
 | 
						|
            FirstChar = p[Index]
 | 
						|
 | 
						|
            if FirstChar == '\r':
 | 
						|
                Index += 1
 | 
						|
                LineSkipped += 1
 | 
						|
                OffsetSkipped = 0
 | 
						|
            elif FirstChar == '\n':
 | 
						|
                Index += 1
 | 
						|
                if PreChar != '\r':
 | 
						|
                    LineSkipped += 1
 | 
						|
                    OffsetSkipped = 0
 | 
						|
            elif FirstChar == ' ':
 | 
						|
                Index += 1
 | 
						|
                OffsetSkipped += 1
 | 
						|
            elif FirstChar == '\t':
 | 
						|
                Index += 1
 | 
						|
                OffsetSkipped += 8
 | 
						|
            else:
 | 
						|
                Index += 1
 | 
						|
                OffsetSkipped += 1
 | 
						|
            PreChar = FirstChar
 | 
						|
 | 
						|
        ParamBeginLine = FuncNameLine + LineSkipped
 | 
						|
        ParamBeginOffset = FuncNameOffset + OffsetSkipped
 | 
						|
 | 
						|
        Index = Start + len(ParamName)
 | 
						|
        PreChar = ''
 | 
						|
        while Index < len(p):
 | 
						|
            FirstChar = p[Index]
 | 
						|
 | 
						|
            if FirstChar == '\r':
 | 
						|
                Index += 1
 | 
						|
                LineSkipped += 1
 | 
						|
                OffsetSkipped = 0
 | 
						|
            elif FirstChar == '\n':
 | 
						|
                Index += 1
 | 
						|
                if PreChar != '\r':
 | 
						|
                    LineSkipped += 1
 | 
						|
                    OffsetSkipped = 0
 | 
						|
            elif FirstChar == ' ':
 | 
						|
                Index += 1
 | 
						|
                OffsetSkipped += 1
 | 
						|
            elif FirstChar == '\t':
 | 
						|
                Index += 1
 | 
						|
                OffsetSkipped += 8
 | 
						|
            else:
 | 
						|
                Index += 1
 | 
						|
                OffsetSkipped += 1
 | 
						|
            PreChar = FirstChar
 | 
						|
 | 
						|
        ParamEndLine = FuncNameLine + LineSkipped
 | 
						|
        ParamEndOffset = FuncNameOffset + OffsetSkipped
 | 
						|
        if ParamName != '...':
 | 
						|
            ParamName = StripNonAlnumChars(ParamName)
 | 
						|
        IdParam = DataClass.IdentifierClass(-1, ParamModifier, '', ParamName, '', DataClass.MODEL_IDENTIFIER_PARAMETER, -1, -1, ParamBeginLine, ParamBeginOffset, ParamEndLine, ParamEndOffset)
 | 
						|
        ParamIdList.append(IdParam)
 | 
						|
 | 
						|
        OffsetSkipped += 1 #skip ','
 | 
						|
 | 
						|
    return ParamIdList
 | 
						|
 | 
						|
def GetFunctionList():
 | 
						|
    FuncObjList = []
 | 
						|
    for FuncDef in FileProfile.FunctionDefinitionList:
 | 
						|
        ParamIdList = []
 | 
						|
        DeclText = FuncDef.Declarator.lstrip()
 | 
						|
        FuncNameStartLine = FuncDef.NamePos[0]
 | 
						|
        FuncNameStartColumn = FuncDef.NamePos[1]
 | 
						|
        FirstChar = DeclText[0]
 | 
						|
        while not FirstChar.isalpha() and FirstChar != '_':
 | 
						|
            if FirstChar == '*':
 | 
						|
                FuncDef.Modifier += '*'
 | 
						|
                FuncNameStartColumn += 1
 | 
						|
                DeclText = DeclText.lstrip('*')
 | 
						|
            elif FirstChar == '\r':
 | 
						|
                DeclText = DeclText.lstrip('\r\n').lstrip('\r')
 | 
						|
                FuncNameStartLine += 1
 | 
						|
                FuncNameStartColumn = 0
 | 
						|
            elif FirstChar == '\n':
 | 
						|
                DeclText = DeclText.lstrip('\n')
 | 
						|
                FuncNameStartLine += 1
 | 
						|
                FuncNameStartColumn = 0
 | 
						|
            elif FirstChar == ' ':
 | 
						|
                DeclText = DeclText.lstrip(' ')
 | 
						|
                FuncNameStartColumn += 1
 | 
						|
            elif FirstChar == '\t':
 | 
						|
                DeclText = DeclText.lstrip('\t')
 | 
						|
                FuncNameStartColumn += 8
 | 
						|
            else:
 | 
						|
                DeclText = DeclText[1:]
 | 
						|
                FuncNameStartColumn += 1
 | 
						|
            FirstChar = DeclText[0]
 | 
						|
 | 
						|
        FuncDef.Declarator = DeclText
 | 
						|
        DeclSplitList = FuncDef.Declarator.split('(')
 | 
						|
        if len(DeclSplitList) < 2:
 | 
						|
            continue
 | 
						|
 | 
						|
        FuncName = DeclSplitList[0]
 | 
						|
        FuncNamePartList = FuncName.split()
 | 
						|
        if len(FuncNamePartList) > 1:
 | 
						|
            FuncName = FuncNamePartList[-1]
 | 
						|
            NameStart = DeclSplitList[0].rfind(FuncName)
 | 
						|
            if NameStart > 0:
 | 
						|
                FuncDef.Modifier += ' ' + DeclSplitList[0][0:NameStart]
 | 
						|
                Index = 0
 | 
						|
                PreChar = ''
 | 
						|
                while Index < NameStart:
 | 
						|
                    FirstChar = DeclSplitList[0][Index]
 | 
						|
                    if DeclSplitList[0][Index:].startswith('EFIAPI'):
 | 
						|
                        Index += 6
 | 
						|
                        FuncNameStartColumn += 6
 | 
						|
                        PreChar = ''
 | 
						|
                        continue
 | 
						|
                    elif FirstChar == '\r':
 | 
						|
                        Index += 1
 | 
						|
                        FuncNameStartLine += 1
 | 
						|
                        FuncNameStartColumn = 0
 | 
						|
                    elif FirstChar == '\n':
 | 
						|
                        Index += 1
 | 
						|
                        if PreChar != '\r':
 | 
						|
                            FuncNameStartLine += 1
 | 
						|
                            FuncNameStartColumn = 0
 | 
						|
                    elif FirstChar == ' ':
 | 
						|
                        Index += 1
 | 
						|
                        FuncNameStartColumn += 1
 | 
						|
                    elif FirstChar == '\t':
 | 
						|
                        Index += 1
 | 
						|
                        FuncNameStartColumn += 8
 | 
						|
                    else:
 | 
						|
                        Index += 1
 | 
						|
                        FuncNameStartColumn += 1
 | 
						|
                    PreChar = FirstChar
 | 
						|
 | 
						|
        FuncObj = DataClass.FunctionClass(-1, FuncDef.Declarator, FuncDef.Modifier, FuncName.strip(), '', FuncDef.StartPos[0], FuncDef.StartPos[1], FuncDef.EndPos[0], FuncDef.EndPos[1], FuncDef.LeftBracePos[0], FuncDef.LeftBracePos[1], -1, ParamIdList, [], FuncNameStartLine, FuncNameStartColumn)
 | 
						|
        FuncObjList.append(FuncObj)
 | 
						|
 | 
						|
    return FuncObjList
 | 
						|
 | 
						|
def GetFileModificationTimeFromDB(FullFileName):
 | 
						|
    TimeValue = 0.0
 | 
						|
    Db = GetDB()
 | 
						|
    SqlStatement = """ select TimeStamp
 | 
						|
                       from File
 | 
						|
                       where FullPath = \'%s\'
 | 
						|
                   """ % (FullFileName)
 | 
						|
    ResultSet = Db.TblFile.Exec(SqlStatement)
 | 
						|
    for Result in ResultSet:
 | 
						|
        TimeValue = Result[0]
 | 
						|
    return TimeValue
 | 
						|
 | 
						|
def CollectSourceCodeDataIntoDB(RootDir):
 | 
						|
    FileObjList = []
 | 
						|
    tuple = os.walk(RootDir)
 | 
						|
    IgnoredPattern = GetIgnoredDirListPattern()
 | 
						|
    ParseErrorFileList = []
 | 
						|
    TokenReleaceList = EccGlobalData.gConfig.TokenReleaceList
 | 
						|
    TokenReleaceList.extend(['L",\\\""'])
 | 
						|
 | 
						|
    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)
 | 
						|
                collector.TokenReleaceList = TokenReleaceList
 | 
						|
                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 is None:
 | 
						|
        ErrorMsgList = []
 | 
						|
 | 
						|
    Db = GetDB()
 | 
						|
    SqlStatement = """ select ID
 | 
						|
                       from File
 | 
						|
                       where FullPath like '%s'
 | 
						|
                   """ % FullFileName
 | 
						|
    ResultSet = Db.TblFile.Exec(SqlStatement)
 | 
						|
 | 
						|
    FileID = -1
 | 
						|
    for Result in ResultSet:
 | 
						|
        if FileID != -1:
 | 
						|
            ErrorMsgList.append('Duplicate file ID found in DB for file %s' % FullFileName)
 | 
						|
            return - 2
 | 
						|
        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 is not 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) is not None:
 | 
						|
        return AllIncludeFileListDict.get(FullFileName)
 | 
						|
 | 
						|
    FileDirName = os.path.dirname(FullFileName)
 | 
						|
    IncludePathList = IncludePathListDict.get(FileDirName)
 | 
						|
    if IncludePathList is 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 is not 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 is not 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 beginning, 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.ModifierSet:
 | 
						|
            continue
 | 
						|
        # remove array suffix
 | 
						|
        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 is not 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 is not 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] == '/':
 | 
						|
            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 is None:
 | 
						|
        Value = SUDict.get(Type)
 | 
						|
    if Value is None:
 | 
						|
        return None
 | 
						|
 | 
						|
    LBPos = Value.find('{')
 | 
						|
    while LBPos == -1:
 | 
						|
        FTList = Value.split()
 | 
						|
        for FT in FTList:
 | 
						|
            if FT not in ('struct', 'union'):
 | 
						|
                Value = TypedefDict.get(FT)
 | 
						|
                if Value is None:
 | 
						|
                    Value = SUDict.get(FT)
 | 
						|
                break
 | 
						|
 | 
						|
        if Value is 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 [] suffixes...
 | 
						|
                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 is not None and Type == TargetType:
 | 
						|
            return Type
 | 
						|
    while TypedefDict.get(Type):
 | 
						|
        Type = TypedefDict.get(Type)
 | 
						|
        if TargetType is not 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 is None:
 | 
						|
            return None
 | 
						|
        # we want to determine the exact type.
 | 
						|
        if TargetType is not None:
 | 
						|
            Type = FromType.split()[0]
 | 
						|
        # we only want to check if it is a pointer
 | 
						|
        else:
 | 
						|
            Type = FromType
 | 
						|
            if Type.find('*') != -1 and Index == len(RefList) - 1:
 | 
						|
                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 is not 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 is not 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 is not 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 is not 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(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, '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, Name
 | 
						|
                       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:
 | 
						|
            if not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY, Result[3]):
 | 
						|
                PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY,
 | 
						|
                              'The open brace should be at the very beginning of a line for the function [%s].' % Result[3],
 | 
						|
                              'Function', Result[2])
 | 
						|
        if Result[1] != 0:
 | 
						|
            if not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY, Result[3]):
 | 
						|
                PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY,
 | 
						|
                              'The close brace should be at the very beginning of a line for the function [%s].' % Result[3],
 | 
						|
                              '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] and 'STATIC' not in Result[3]:
 | 
						|
                PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_NO_INIT_OF_VARIABLE, 'Variable Name: %s' % Result[0], FileTable, Result[2])
 | 
						|
 | 
						|
def CheckMemberVariableFormat(Name, Value, FileTable, TdId, ModelId):
 | 
						|
    ErrMsgList = []
 | 
						|
    # Member variable format pattern.
 | 
						|
    Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$')
 | 
						|
 | 
						|
    LBPos = Value.find('{')
 | 
						|
    RBPos = Value.rfind('}')
 | 
						|
    if LBPos == -1 or RBPos == -1:
 | 
						|
        return ErrMsgList
 | 
						|
 | 
						|
    Fields = Value[LBPos + 1 : RBPos]
 | 
						|
    Fields = StripComments(Fields).strip()
 | 
						|
    NestPos = Fields.find ('struct')
 | 
						|
    if NestPos != -1 and (NestPos + len('struct') < len(Fields)) and ModelId != DataClass.MODEL_IDENTIFIER_UNION:
 | 
						|
        if not Fields[NestPos + len('struct') + 1].isalnum():
 | 
						|
            if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, Name):
 | 
						|
                PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, 'Nested struct in [%s].' % (Name), FileTable, TdId)
 | 
						|
            return ErrMsgList
 | 
						|
    NestPos = Fields.find ('union')
 | 
						|
    if NestPos != -1 and (NestPos + len('union') < len(Fields)):
 | 
						|
        if not Fields[NestPos + len('union') + 1].isalnum():
 | 
						|
            if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, Name):
 | 
						|
                PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, 'Nested union in [%s].' % (Name), FileTable, TdId)
 | 
						|
            return ErrMsgList
 | 
						|
    NestPos = Fields.find ('enum')
 | 
						|
    if NestPos != -1 and (NestPos + len('enum') < len(Fields)):
 | 
						|
        if not Fields[NestPos + len('enum') + 1].isalnum():
 | 
						|
            if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, Name):
 | 
						|
                PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, 'Nested enum in [%s].' % (Name), FileTable, TdId)
 | 
						|
            return ErrMsgList
 | 
						|
 | 
						|
    if ModelId == DataClass.MODEL_IDENTIFIER_ENUMERATE:
 | 
						|
        FieldsList = Fields.split(',')
 | 
						|
        # deal with enum is pre-assigned a value by function call ( , , , ...)
 | 
						|
        QuoteCount = 0
 | 
						|
        Index = 0
 | 
						|
        RemoveCurrentElement = False
 | 
						|
        while Index < len(FieldsList):
 | 
						|
            Field = FieldsList[Index]
 | 
						|
 | 
						|
            if Field.find('(') != -1:
 | 
						|
                QuoteCount += 1
 | 
						|
                RemoveCurrentElement = True
 | 
						|
                Index += 1
 | 
						|
                continue
 | 
						|
 | 
						|
            if Field.find(')') != -1 and QuoteCount > 0:
 | 
						|
                QuoteCount -= 1
 | 
						|
 | 
						|
            if RemoveCurrentElement:
 | 
						|
                FieldsList.remove(Field)
 | 
						|
                if QuoteCount == 0:
 | 
						|
                    RemoveCurrentElement = False
 | 
						|
                continue
 | 
						|
 | 
						|
            if QuoteCount == 0:
 | 
						|
                RemoveCurrentElement = False
 | 
						|
 | 
						|
            Index += 1
 | 
						|
    else:
 | 
						|
        FieldsList = Fields.split(';')
 | 
						|
 | 
						|
    for Field in FieldsList:
 | 
						|
        Field = Field.strip()
 | 
						|
        if Field == '':
 | 
						|
            continue
 | 
						|
        # For the condition that the field in struct is an array with [] suffixes...
 | 
						|
        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', 'long')
 | 
						|
    for Result in ResultSet:
 | 
						|
        for Type in CTypeTuple:
 | 
						|
            if PatternInModifier(Result[0], Type):
 | 
						|
                if EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE,
 | 
						|
                                                        Result[0] + ' ' + Result[1]):
 | 
						|
                    continue
 | 
						|
                PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE,
 | 
						|
                              'Invalid variable type (%s) in definition [%s]' % (Type, Result[0] + ' ' + Result[1]),
 | 
						|
                              FileTable,
 | 
						|
                              Result[2])
 | 
						|
                break
 | 
						|
 | 
						|
    SqlStatement = """ select Modifier, Name, ID, Value
 | 
						|
                       from %s
 | 
						|
                       where Model = %d
 | 
						|
                   """ % (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 is None:
 | 
						|
            continue
 | 
						|
 | 
						|
        for Exp in GetPredicateListFromPredicateExpStr(Str[0]):
 | 
						|
            PredInfo = SplitPredicateStr(Exp)
 | 
						|
            if PredInfo[1] is 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 is not None:
 | 
						|
                        if Type.find('*') != -1 and Type != 'BOOLEAN*':
 | 
						|
                            PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])
 | 
						|
                        continue
 | 
						|
 | 
						|
                    if PredVarStr in FuncReturnTypeDict:
 | 
						|
                        continue
 | 
						|
 | 
						|
                Type = GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall, None, StarList)
 | 
						|
                if SearchInCache:
 | 
						|
                    FuncReturnTypeDict[PredVarStr] = Type
 | 
						|
                if Type is 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 is None:
 | 
						|
            continue
 | 
						|
 | 
						|
        for Exp in GetPredicateListFromPredicateExpStr(Str[0]):
 | 
						|
            PredInfo = SplitPredicateStr(Exp)
 | 
						|
            if PredInfo[1] is 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 is not None:
 | 
						|
                        if Type.find('BOOLEAN') == -1:
 | 
						|
                            PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR, 'Predicate Expression: %s' % Exp, FileTable, Str[2])
 | 
						|
                        continue
 | 
						|
 | 
						|
                    if PredVarStr in FuncReturnTypeDict:
 | 
						|
                        continue
 | 
						|
                Type = GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall, 'BOOLEAN', StarList)
 | 
						|
                if SearchInCache:
 | 
						|
                    FuncReturnTypeDict[PredVarStr] = Type
 | 
						|
                if Type is None:
 | 
						|
                    continue
 | 
						|
                if Type.find('BOOLEAN') == -1:
 | 
						|
                    PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR, 'Predicate Expression: %s' % Exp, FileTable, Str[2])
 | 
						|
 | 
						|
 | 
						|
def CheckBooleanValueComparison(FullFileName):
 | 
						|
    ErrorMsgList = []
 | 
						|
 | 
						|
    FileID = GetTableID(FullFileName, ErrorMsgList)
 | 
						|
    if FileID < 0:
 | 
						|
        return ErrorMsgList
 | 
						|
 | 
						|
    # cache the found function return type to accelerate later checking in this file.
 | 
						|
    FuncReturnTypeDict = {}
 | 
						|
 | 
						|
    Db = GetDB()
 | 
						|
    FileTable = 'Identifier' + str(FileID)
 | 
						|
    SqlStatement = """ select Value, StartLine, ID
 | 
						|
                       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 is 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 is not None:
 | 
						|
                        if Type.find('BOOLEAN') != -1:
 | 
						|
                            PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])
 | 
						|
                        continue
 | 
						|
 | 
						|
                    if PredVarStr in FuncReturnTypeDict:
 | 
						|
                        continue
 | 
						|
 | 
						|
                Type = GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall, 'BOOLEAN', StarList)
 | 
						|
                if SearchInCache:
 | 
						|
                    FuncReturnTypeDict[PredVarStr] = Type
 | 
						|
                if Type is None:
 | 
						|
                    continue
 | 
						|
                if Type.find('BOOLEAN') != -1:
 | 
						|
                    PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])
 | 
						|
 | 
						|
 | 
						|
def CheckHeaderFileData(FullFileName, AllTypedefFun=[]):
 | 
						|
    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'):
 | 
						|
            for Item in AllTypedefFun:
 | 
						|
                if '(%s)' % Result[1] in Item:
 | 
						|
                    break
 | 
						|
            else:
 | 
						|
                PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_DATA, 'Variable definition appears in header file', FileTable, Result[0])
 | 
						|
 | 
						|
    SqlStatement = """ select ID
 | 
						|
                       from Function
 | 
						|
                       where BelongsToFile = %d
 | 
						|
                   """ % FileID
 | 
						|
    ResultSet = Db.TblFile.Exec(SqlStatement)
 | 
						|
    for Result in ResultSet:
 | 
						|
        PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_DATA, 'Function definition appears in header file', 'Function', Result[0])
 | 
						|
 | 
						|
    return ErrorMsgList
 | 
						|
 | 
						|
def CheckHeaderFileIfndef(FullFileName):
 | 
						|
    ErrorMsgList = []
 | 
						|
 | 
						|
    FileID = GetTableID(FullFileName, ErrorMsgList)
 | 
						|
    if FileID < 0:
 | 
						|
        return ErrorMsgList
 | 
						|
 | 
						|
    Db = GetDB()
 | 
						|
    FileTable = 'Identifier' + str(FileID)
 | 
						|
    SqlStatement = """ select Value, StartLine
 | 
						|
                       from %s
 | 
						|
                       where Model = %d order by StartLine
 | 
						|
                   """ % (FileTable, DataClass.MODEL_IDENTIFIER_MACRO_IFNDEF)
 | 
						|
    ResultSet = Db.TblFile.Exec(SqlStatement)
 | 
						|
    if len(ResultSet) == 0:
 | 
						|
        PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_1, '', 'File', FileID)
 | 
						|
        return ErrorMsgList
 | 
						|
    for Result in ResultSet:
 | 
						|
        SqlStatement = """ select Value, EndLine
 | 
						|
                       from %s
 | 
						|
                       where EndLine < %d
 | 
						|
                   """ % (FileTable, Result[1])
 | 
						|
        ResultSet = Db.TblFile.Exec(SqlStatement)
 | 
						|
        for Result in ResultSet:
 | 
						|
            if not Result[0].startswith('/*') and not Result[0].startswith('//'):
 | 
						|
                PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_2, '', 'File', FileID)
 | 
						|
        break
 | 
						|
 | 
						|
    SqlStatement = """ select Value
 | 
						|
                       from %s
 | 
						|
                       where StartLine > (select max(EndLine) from %s where Model = %d)
 | 
						|
                   """ % (FileTable, FileTable, DataClass.MODEL_IDENTIFIER_MACRO_ENDIF)
 | 
						|
    ResultSet = Db.TblFile.Exec(SqlStatement)
 | 
						|
    for Result in ResultSet:
 | 
						|
        if not Result[0].startswith('/*') and not Result[0].startswith('//'):
 | 
						|
            PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_3, '', 'File', FileID)
 | 
						|
    return ErrorMsgList
 | 
						|
 | 
						|
def CheckDoxygenCommand(FullFileName):
 | 
						|
    ErrorMsgList = []
 | 
						|
 | 
						|
    FileID = GetTableID(FullFileName, ErrorMsgList)
 | 
						|
    if FileID < 0:
 | 
						|
        return ErrorMsgList
 | 
						|
 | 
						|
    Db = GetDB()
 | 
						|
    FileTable = 'Identifier' + str(FileID)
 | 
						|
    SqlStatement = """ select Value, ID
 | 
						|
                       from %s
 | 
						|
                       where Model = %d or Model = %d
 | 
						|
                   """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT, DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER)
 | 
						|
    ResultSet = Db.TblFile.Exec(SqlStatement)
 | 
						|
    DoxygenCommandList = ['bug', 'todo', 'example', 'file', 'attention', 'param', 'post', 'pre', 'retval',
 | 
						|
                          'return', 'sa', 'since', 'test', 'note', 'par', 'endcode', 'code']
 | 
						|
    for Result in ResultSet:
 | 
						|
        CommentStr = Result[0]
 | 
						|
        CommentPartList = CommentStr.split()
 | 
						|
        for Part in CommentPartList:
 | 
						|
            if Part.upper() == 'BUGBUG':
 | 
						|
                PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Bug should be marked with doxygen tag @bug', FileTable, Result[1])
 | 
						|
            if Part.upper() == 'TODO':
 | 
						|
                PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'ToDo should be marked with doxygen tag @todo', FileTable, Result[1])
 | 
						|
            if Part.startswith('@'):
 | 
						|
                if EccGlobalData.gException.IsException(ERROR_DOXYGEN_CHECK_COMMAND, Part):
 | 
						|
                    continue
 | 
						|
                if not Part.replace('@', '').strip():
 | 
						|
                    continue
 | 
						|
                if Part.lstrip('@') in ['{', '}']:
 | 
						|
                    continue
 | 
						|
                if Part.lstrip('@').isalpha():
 | 
						|
                    if Part.lstrip('@') not in DoxygenCommandList:
 | 
						|
                        PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Unknown doxygen command %s' % Part, FileTable, Result[1])
 | 
						|
                else:
 | 
						|
                    Index = Part.find('[')
 | 
						|
                    if Index == -1:
 | 
						|
                        PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Unknown doxygen command %s' % Part, FileTable, Result[1])
 | 
						|
                    RealCmd = Part[1:Index]
 | 
						|
                    if RealCmd not in DoxygenCommandList:
 | 
						|
                        PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Unknown doxygen command %s' % Part, FileTable, Result[1])
 | 
						|
 | 
						|
 | 
						|
def CheckDoxygenTripleForwardSlash(FullFileName):
 | 
						|
    ErrorMsgList = []
 | 
						|
 | 
						|
    FileID = GetTableID(FullFileName, ErrorMsgList)
 | 
						|
    if FileID < 0:
 | 
						|
        return ErrorMsgList
 | 
						|
 | 
						|
    Db = GetDB()
 | 
						|
 | 
						|
    SqlStatement = """ select ID, BodyStartLine, BodyStartColumn, EndLine, EndColumn
 | 
						|
                       from Function
 | 
						|
                       where BelongsToFile = %d
 | 
						|
                   """ % (FileID)
 | 
						|
    ResultSet = Db.TblFile.Exec(SqlStatement)
 | 
						|
    if len(ResultSet) == 0:
 | 
						|
        return
 | 
						|
 | 
						|
    FuncDefSet = []
 | 
						|
    for Result in ResultSet:
 | 
						|
        FuncDefSet.append(Result)
 | 
						|
 | 
						|
 | 
						|
    FileTable = 'Identifier' + str(FileID)
 | 
						|
    SqlStatement = """ select Value, ID, StartLine, StartColumn, EndLine, EndColumn
 | 
						|
                       from %s
 | 
						|
                       where Model = %d
 | 
						|
 | 
						|
                   """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT)
 | 
						|
    ResultSet = Db.TblFile.Exec(SqlStatement)
 | 
						|
    CommentSet = []
 | 
						|
    try:
 | 
						|
        for Result in ResultSet:
 | 
						|
            CommentSet.append(Result)
 | 
						|
    except:
 | 
						|
        print('Unrecognized chars in comment of file %s', FullFileName)
 | 
						|
 | 
						|
 | 
						|
    for Result in CommentSet:
 | 
						|
        CommentStr = Result[0]
 | 
						|
        StartLine = Result[2]
 | 
						|
        StartColumn = Result[3]
 | 
						|
        EndLine = Result[4]
 | 
						|
        EndColumn = Result[5]
 | 
						|
        if not CommentStr.startswith('///<'):
 | 
						|
            continue
 | 
						|
 | 
						|
        Found = False
 | 
						|
        for FuncDef in FuncDefSet:
 | 
						|
            if StartLine == FuncDef[1] and StartColumn > FuncDef[2] and EndLine == FuncDef[3] and EndColumn < FuncDef[4]:
 | 
						|
                Found = True
 | 
						|
                break
 | 
						|
            if StartLine > FuncDef[1] and EndLine < FuncDef[3]:
 | 
						|
                Found = True
 | 
						|
                break
 | 
						|
            if StartLine == FuncDef[1] and StartColumn > FuncDef[2] and EndLine < FuncDef[3]:
 | 
						|
                Found = True
 | 
						|
                break
 | 
						|
            if StartLine > FuncDef[1] and EndLine == FuncDef[3] and EndColumn < FuncDef[4]:
 | 
						|
                Found = True
 | 
						|
                break
 | 
						|
        if Found:
 | 
						|
            PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMENT_FORMAT, '', FileTable, Result[1])
 | 
						|
 | 
						|
 | 
						|
def CheckFileHeaderDoxygenComments(FullFileName):
 | 
						|
    ErrorMsgList = []
 | 
						|
 | 
						|
    FileID = GetTableID(FullFileName, ErrorMsgList)
 | 
						|
    if FileID < 0:
 | 
						|
        return ErrorMsgList
 | 
						|
 | 
						|
    Db = GetDB()
 | 
						|
    FileTable = 'Identifier' + str(FileID)
 | 
						|
    SqlStatement = """ select Value, ID
 | 
						|
                       from %s
 | 
						|
                       where Model = %d and (StartLine = 1 or StartLine = 7 or StartLine = 8) and StartColumn = 0
 | 
						|
                   """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT)
 | 
						|
    ResultSet = Db.TblFile.Exec(SqlStatement)
 | 
						|
    if len(ResultSet) == 0:
 | 
						|
        PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'No File License header appear at the very beginning of file.', 'File', FileID)
 | 
						|
        return ErrorMsgList
 | 
						|
 | 
						|
    NoHeaderCommentStartFlag = True
 | 
						|
    NoHeaderCommentEndFlag = True
 | 
						|
    NoHeaderCommentPeriodFlag = True
 | 
						|
    NoCopyrightFlag = True
 | 
						|
    NoLicenseFlag = True
 | 
						|
    NoRevReferFlag = True
 | 
						|
    NextLineIndex = 0
 | 
						|
    for Result in ResultSet:
 | 
						|
        FileStartFlag = False
 | 
						|
        CommentStrList = []
 | 
						|
        CommentStr = Result[0].strip()
 | 
						|
        CommentStrListTemp = CommentStr.split('\n')
 | 
						|
        if (len(CommentStrListTemp) <= 1):
 | 
						|
            # For Mac
 | 
						|
            CommentStrListTemp = CommentStr.split('\r')
 | 
						|
        # Skip the content before the file  header
 | 
						|
        for CommentLine in CommentStrListTemp:
 | 
						|
            if CommentLine.strip().startswith('/** @file'):
 | 
						|
                FileStartFlag = True
 | 
						|
            if FileStartFlag ==  True:
 | 
						|
                CommentStrList.append(CommentLine)
 | 
						|
 | 
						|
        ID = Result[1]
 | 
						|
        Index = 0
 | 
						|
        if CommentStrList and CommentStrList[0].strip().startswith('/** @file'):
 | 
						|
            NoHeaderCommentStartFlag = False
 | 
						|
        else:
 | 
						|
            continue
 | 
						|
        if CommentStrList and CommentStrList[-1].strip().endswith('**/'):
 | 
						|
            NoHeaderCommentEndFlag = False
 | 
						|
        else:
 | 
						|
            continue
 | 
						|
 | 
						|
        for CommentLine in CommentStrList:
 | 
						|
            Index = Index + 1
 | 
						|
            NextLineIndex = Index
 | 
						|
            if CommentLine.startswith('/** @file'):
 | 
						|
                continue
 | 
						|
            if CommentLine.startswith('**/'):
 | 
						|
                break
 | 
						|
            # Check whether C File header Comment content start with two spaces.
 | 
						|
            if EccGlobalData.gConfig.HeaderCheckCFileCommentStartSpacesNum == '1' or EccGlobalData.gConfig.HeaderCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
 | 
						|
                if CommentLine.startswith('/** @file') == False and CommentLine.startswith('**/') == False and CommentLine.strip() and CommentLine.startswith('  ') == False:
 | 
						|
                    PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment content should start with two spaces at each line', FileTable, ID)
 | 
						|
 | 
						|
            CommentLine = CommentLine.strip()
 | 
						|
            if CommentLine.startswith('Copyright') or ('Copyright' in CommentLine and CommentLine.lower().startswith('(c)')):
 | 
						|
                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> is 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> is 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 as v:
 | 
						|
        print("Usage: %s filename" % sys.argv[0])
 | 
						|
        sys.exit(1)
 | 
						|
    MsgList = CheckFuncHeaderDoxygenComments(test_file)
 | 
						|
    for Msg in MsgList:
 | 
						|
        print(Msg)
 | 
						|
    print('Done!')
 |