ECC: predicate expression and data declaration checking initial check-in.
authorjlin16 <jlin16@7335b38e-4728-0410-8992-fb3ffe349368>
Mon, 24 Mar 2008 09:36:16 +0000 (09:36 +0000)
committerjlin16 <jlin16@7335b38e-4728-0410-8992-fb3ffe349368>
Mon, 24 Mar 2008 09:36:16 +0000 (09:36 +0000)
git-svn-id: https://buildtools.tianocore.org/svn/buildtools/trunk/BaseTools@1086 7335b38e-4728-0410-8992-fb3ffe349368

Source/Python/Ecc/Check.py
Source/Python/Ecc/c.py

index d55b90e..09f47e8 100644 (file)
@@ -34,9 +34,122 @@ class Check(object):
         self.MetaDataFileCheck()\r
         self.DoxygenCheck()\r
         self.IncludeFileCheck()\r
-        self.NamingConventionCheck()\r
+        self.PredicateExpressionCheck()\r
+        self.DeclAndDataTypeCheck()\r
     \r
     #\r
+    # Declarations and Data Types Checking\r
+    #\r
+    def DeclAndDataTypeCheck(self):\r
+        self.DeclCheckNoUseCType()\r
+        self.DeclCheckInOutModifier()\r
+        self.DeclCheckEFIAPIModifier()\r
+        self.DeclCheckEnumeratedType()\r
+        self.DeclCheckStructureDeclaration()\r
+        self.DeclCheckUnionType()\r
+    \r
+    \r
+    # Check whether no use of int, unsigned, char, void, static, long in any .c, .h or .asl files.\r
+    def DeclCheckNoUseCType(self):\r
+        if EccGlobalData.gConfig.DeclarationDataTypeCheckNoUseCType == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1':\r
+            EdkLogger.quiet("Checking Declaration No use C type ...")\r
+            Tuple = os.walk(EccGlobalData.gTarget)\r
+            IgnoredPattern = re.compile(r'.*[\\/](?:BUILD|CVS|\.SVN|INTELRESTRICTEDTOOLS|INTELRESTRICTEDPKG)[\\/].*')\r
+        \r
+            for Dirpath, Dirnames, Filenames in Tuple:\r
+                if IgnoredPattern.match(Dirpath.upper()) or Dirpath.find('.svn') != -1:\r
+                    continue\r
+                for F in Filenames:\r
+                    if os.path.splitext(F)[1] in ('.h', '.c'):\r
+                        FullName = os.path.join(Dirpath, F)\r
+                        c.CheckDeclNoUseCType(FullName)\r
+    \r
+    # Check whether the modifiers IN, OUT, OPTIONAL, and UNALIGNED are used only to qualify arguments to a function and should not appear in a data type declaration\r
+    def DeclCheckInOutModifier(self):\r
+        if EccGlobalData.gConfig.DeclarationDataTypeCheckInOutModifier == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1':\r
+            EdkLogger.quiet("Checking Declaration argument modifier ...")\r
+            Tuple = os.walk(EccGlobalData.gTarget)\r
+            IgnoredPattern = re.compile(r'.*[\\/](?:BUILD|CVS|\.SVN|INTELRESTRICTEDTOOLS|INTELRESTRICTEDPKG)[\\/].*')\r
+        \r
+            for Dirpath, Dirnames, Filenames in Tuple:\r
+                if IgnoredPattern.match(Dirpath.upper()) or Dirpath.find('.svn') != -1:\r
+                    continue\r
+                for F in Filenames:\r
+                    if os.path.splitext(F)[1] in ('.h', '.c'):\r
+                        FullName = os.path.join(Dirpath, F)\r
+                        c.CheckDeclArgModifier(FullName)\r
+    \r
+    # Check whether the EFIAPI modifier should be used at the entry of drivers, events, and member functions of protocols\r
+    def DeclCheckEFIAPIModifier(self):\r
+        if EccGlobalData.gConfig.DeclarationDataTypeCheckEFIAPIModifier == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1':\r
+            pass\r
+    \r
+    # Check whether Enumerated Type has a 'typedef' and the name is capital\r
+    def DeclCheckEnumeratedType(self):\r
+        if EccGlobalData.gConfig.DeclarationDataTypeCheckEnumeratedType == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1':\r
+            pass\r
+    \r
+    # Check whether Structure Type has a 'typedef' and the name is capital\r
+    def DeclCheckStructureDeclaration(self):\r
+        if EccGlobalData.gConfig.DeclarationDataTypeCheckStructureDeclaration == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1':\r
+            pass\r
+    \r
+    # Check whether Union Type has a 'typedef' and the name is capital\r
+    def DeclCheckUnionType(self):\r
+        if EccGlobalData.gConfig.DeclarationDataTypeCheckUnionType == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1':\r
+            pass\r
+    \r
+    #\r
+    # Predicate Expression Checking\r
+    #\r
+    def PredicateExpressionCheck(self):\r
+        self.PredicateExpressionCheckBooleanValue()\r
+        self.PredicateExpressionCheckNonBooleanOperator()\r
+        self.PredicateExpressionCheckComparisonNullType()\r
+    \r
+    # Check whether Boolean values, variable type BOOLEAN not use explicit comparisons to TRUE or FALSE\r
+    def PredicateExpressionCheckBooleanValue(self):\r
+        if EccGlobalData.gConfig.PredicateExpressionCheckBooleanValue == '1' or EccGlobalData.gConfig.PredicateExpressionCheckAll == '1':\r
+            EdkLogger.quiet("Checking predicate expression Boolean value ...")\r
+            Tuple = os.walk(EccGlobalData.gTarget)\r
+            IgnoredPattern = re.compile(r'.*[\\/](?:BUILD|CVS|\.SVN|INTELRESTRICTEDTOOLS|INTELRESTRICTEDPKG)[\\/].*')\r
+        \r
+            for Dirpath, Dirnames, Filenames in Tuple:\r
+                if IgnoredPattern.match(Dirpath.upper()) or Dirpath.find('.svn') != -1:\r
+                    continue\r
+                for F in Filenames:\r
+                    if os.path.splitext(F)[1] in ('.c'):\r
+                        FullName = os.path.join(Dirpath, F)\r
+                        c.CheckBooleanValueComparison(FullName)\r
+    # Check whether Non-Boolean comparisons use a compare operator (==, !=, >, < >=, <=). \r
+    def PredicateExpressionCheckNonBooleanOperator(self):\r
+        if EccGlobalData.gConfig.PredicateExpressionCheckNonBooleanOperator == '1' or EccGlobalData.gConfig.PredicateExpressionCheckAll == '1':\r
+            EdkLogger.quiet("Checking predicate expression Non-Boolean variable...")\r
+            Tuple = os.walk(EccGlobalData.gTarget)\r
+            IgnoredPattern = re.compile(r'.*[\\/](?:BUILD|CVS|\.SVN|INTELRESTRICTEDTOOLS|INTELRESTRICTEDPKG)[\\/].*')\r
+        \r
+            for Dirpath, Dirnames, Filenames in Tuple:\r
+                if IgnoredPattern.match(Dirpath.upper()) or Dirpath.find('.svn') != -1:\r
+                    continue\r
+                for F in Filenames:\r
+                    if os.path.splitext(F)[1] in ('.c'):\r
+                        FullName = os.path.join(Dirpath, F)\r
+                        c.CheckNonBooleanValueComparison(FullName)\r
+    # Check whether a comparison of any pointer to zero must be done via the NULL type\r
+    def PredicateExpressionCheckComparisonNullType(self):\r
+        if EccGlobalData.gConfig.PredicateExpressionCheckComparisonNullType == '1' or EccGlobalData.gConfig.PredicateExpressionCheckAll == '1':\r
+            EdkLogger.quiet("Checking predicate expression NULL pointer ...")\r
+            Tuple = os.walk(EccGlobalData.gTarget)\r
+            IgnoredPattern = re.compile(r'.*[\\/](?:BUILD|CVS|\.SVN|INTELRESTRICTEDTOOLS|INTELRESTRICTEDPKG)[\\/].*')\r
+        \r
+            for Dirpath, Dirnames, Filenames in Tuple:\r
+                if IgnoredPattern.match(Dirpath.upper()) or Dirpath.find('.svn') != -1:\r
+                    continue\r
+                for F in Filenames:\r
+                    if os.path.splitext(F)[1] in ('.c'):\r
+                        FullName = os.path.join(Dirpath, F)\r
+                        c.CheckPointerNullComparison(FullName)\r
+    #\r
     # Include file checking\r
     #\r
     def IncludeFileCheck(self):\r
index 2a4c2d3..87a8014 100644 (file)
@@ -15,7 +15,7 @@ def GetIgnoredDirListPattern():
     return p\r
 \r
 def GetFuncDeclPattern():\r
-    p = re.compile(r'[^=]*\(.*\).*', re.DOTALL)\r
+    p = re.compile(r'[_\w]*\s*\(.*\).*', re.DOTALL)\r
     return p\r
 \r
 def GetDB():\r
@@ -258,6 +258,483 @@ def GetTableID(FullFileName, ErrorMsgList):
         return -1\r
     return FileID\r
 \r
+def GetIncludeFileList(FullFileName):\r
+    ErrorMsgList = []\r
+    \r
+    FileID = GetTableID(FullFileName, ErrorMsgList)\r
+    if FileID < 0:\r
+        return []\r
+    \r
+    Db = GetDB()\r
+    FileTable = 'Identifier' + str(FileID)\r
+    SqlStatement = """ select Value\r
+                       from %s\r
+                       where Model = %d\r
+                   """ % (FileTable, DataClass.MODEL_IDENTIFIER_INCLUDE)\r
+    ResultSet = Db.TblFile.Exec(SqlStatement)\r
+    return ResultSet\r
+\r
+def GetFullPathOfIncludeFile(Str):\r
+    pass\r
+\r
+def GetAllIncludeFiles(FullFileName):\r
+\r
+    IncludeFileQueue = []\r
+    for IncludeFile in GetIncludeFileList(FullFileName):\r
+        FullPath = GetFullPathOfIncludeFile(IncludeFile[0])\r
+        IncludeFileQueue.append(FullPath)\r
+        \r
+    i = 0\r
+    while i < len(IncludeFileQueue):\r
+        for IncludeFile in GetIncludeFileList(IncludeFileQueue[i]):\r
+            FullPath = GetFullPathOfIncludeFile(IncludeFile[0])\r
+            if FullPath not in IncludeFileQueue:\r
+                IncludeFileQueue.insert(i + 1, FullPath)\r
+        i += 1\r
+    return IncludeFileQueue\r
+\r
+def GetPredicateListFromPredicateExpStr(PES):\r
+\r
+    PredicateList = []\r
+    i = 0\r
+    PredicateBegin = 0\r
+    #PredicateEnd = 0\r
+    LogicOpPos = 0\r
+    while i < len(PES) - 1:\r
+        if (PES[i].isalpha() or PES[i] == '_') and LogicOpPos >= PredicateBegin:\r
+            PredicateBegin = i\r
+        if (PES[i] == '&' and PES[i+1] == '&') or (PES[i] == '|' and PES[i+1] == '|'):\r
+            LogicOpPos = i\r
+            PredicateList.append(PES[PredicateBegin:i].strip())\r
+        i += 1\r
+    \r
+    if PredicateBegin > LogicOpPos:\r
+        PredicateList.append(PES[PredicateBegin:len(PES)].strip())\r
+    return PredicateList\r
+    \r
+def GetPredicateVariable(Lvalue):\r
+    i = 0\r
+    VarStart = -1\r
+    VarEnd = -1\r
+    while i < len(Lvalue):\r
+        if Lvalue[i].isalnum() or Lvalue[i] == '_':\r
+            if VarStart == -1:\r
+                VarStart = i\r
+            VarEnd = i\r
+            i += 1\r
+        elif VarEnd != -1:\r
+            break\r
+        else:\r
+            i += 1\r
+    \r
+    if VarStart != -1:\r
+        return Lvalue[VarStart:VarEnd+1]\r
+    \r
+    return None    \r
+\r
+def SplitPredicateByOp(Str, Op):\r
+\r
+    Name = Str.strip()\r
+    Value = None\r
+    \r
+    PredPartList = Str.split(Op)\r
+    if len(PredPartList) > 1:\r
+        Name = PredPartList[0].strip()\r
+        Value = PredPartList[1].strip()\r
+        return [Name, Value]\r
+    return [Name]\r
+\r
+def SplitPredicateStr(Str):\r
+    PredPartList = SplitPredicateByOp(Str, '==')\r
+    if len(PredPartList) > 1:\r
+        return [PredPartList, '==']\r
+    \r
+    PredPartList = SplitPredicateByOp(Str, '!=')\r
+    if len(PredPartList) > 1:\r
+        return [PredPartList, '!=']\r
+        \r
+    PredPartList = SplitPredicateByOp(Str, '>')\r
+    if len(PredPartList) > 1:\r
+        return [PredPartList, '>']\r
+        \r
+    PredPartList = SplitPredicateByOp(Str, '<')\r
+    if len(PredPartList) > 1:\r
+        return [PredPartList, '<']\r
+        \r
+    PredPartList = SplitPredicateByOp(Str, '>=')\r
+    if len(PredPartList) > 1:\r
+        return [PredPartList, '>=']\r
+        \r
+    PredPartList = SplitPredicateByOp(Str, '<=')\r
+    if len(PredPartList) > 1:\r
+        return [PredPartList, '<=']\r
+        \r
+    return [[Str, None], None]\r
+\r
+def GetFuncContainsPE(ExpLine, ResultSet):\r
+    for Result in ResultSet:\r
+        if Result[0] < ExpLine and Result[1] > ExpLine:\r
+            return Result\r
+    return None\r
+\r
+def PatternInModifier(Modifier, SubStr):\r
+    PartList = Modifier.split()\r
+    for Part in PartList:\r
+        if Part == SubStr:\r
+            return True\r
+    return False\r
+\r
+def CheckDeclArgModifier(FullFileName):\r
+    ErrorMsgList = []\r
+    \r
+    FileID = GetTableID(FullFileName, ErrorMsgList)\r
+    if FileID < 0:\r
+        return ErrorMsgList\r
+    \r
+    Db = GetDB()\r
+    FileTable = 'Identifier' + str(FileID)\r
+    SqlStatement = """ select Modifier, Name, ID\r
+                       from %s\r
+                       where Model = %d\r
+                   """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE)\r
+    ResultSet = Db.TblFile.Exec(SqlStatement)\r
+    ModifierTuple = ('IN', 'OUT', 'OPTIONAL', 'UNALIGNED')\r
+    MAX_MODIFIER_LENGTH = 100\r
+    for Result in ResultSet:\r
+        for Modifier in ModifierTuple:\r
+            if PatternInModifier(Result[0], Modifier) and len(Result[0]) < MAX_MODIFIER_LENGTH:\r
+                PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER, 'Variable Modifier %s' % Result[0], FileTable, Result[2])\r
+                break\r
+    \r
+    SqlStatement = """ select Modifier, Name, ID\r
+                       from %s\r
+                       where Model = %d\r
+                   """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
+    ResultSet = Db.TblFile.Exec(SqlStatement)\r
+    for Result in ResultSet:\r
+        for Modifier in ModifierTuple:\r
+            if PatternInModifier(Result[0], Modifier):\r
+                PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER, 'Return Type Modifier %s' % Result[0], FileTable, Result[2])\r
+                break\r
+                    \r
+    SqlStatement = """ select Modifier, Header, ID\r
+                       from Function\r
+                       where BelongsToFile = %d\r
+                   """ % (FileID)\r
+    ResultSet = Db.TblFile.Exec(SqlStatement)\r
+    for Result in ResultSet:\r
+        for Modifier in ModifierTuple:\r
+            if PatternInModifier(Result[0], Modifier):\r
+                PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER, 'Return Type Modifier %s' % Result[0], FileTable, Result[2])\r
+                break\r
+\r
+def CheckDeclNoUseCType(FullFileName):\r
+    ErrorMsgList = []\r
+    \r
+    FileID = GetTableID(FullFileName, ErrorMsgList)\r
+    if FileID < 0:\r
+        return ErrorMsgList\r
+    \r
+    Db = GetDB()\r
+    FileTable = 'Identifier' + str(FileID)\r
+    SqlStatement = """ select Modifier, Name, ID\r
+                       from %s\r
+                       where Model = %d\r
+                   """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE)\r
+    ResultSet = Db.TblFile.Exec(SqlStatement)\r
+    CTypeTuple = ('int', 'unsigned', 'char', 'void', 'static', 'long')\r
+    for Result in ResultSet:\r
+        for Type in CTypeTuple:\r
+            if PatternInModifier(Result[0], Type):\r
+                PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, 'Variable type %s' % Type, FileTable, Result[2])\r
+                break\r
+    \r
+    SqlStatement = """ select Modifier, Name, ID\r
+                       from %s\r
+                       where Model = %d\r
+                   """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
+    ResultSet = Db.TblFile.Exec(SqlStatement)\r
+    for Result in ResultSet:\r
+        ParamList = GetParamList(Result[1])\r
+        for Type in CTypeTuple:\r
+            if PatternInModifier(Result[0], Type):\r
+                PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, 'Return type %s' % Result[0], FileTable, Result[2])\r
+            \r
+            for Param in ParamList:\r
+                if PatternInModifier(Param.Modifier, Type):\r
+                    PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, 'Parameter %s' % Param.Name, FileTable, Result[2])\r
+                    \r
+    SqlStatement = """ select Modifier, Header, ID\r
+                       from Function\r
+                       where BelongsToFile = %d\r
+                   """ % (FileID)\r
+    ResultSet = Db.TblFile.Exec(SqlStatement)\r
+    for Result in ResultSet:\r
+        ParamList = GetParamList(Result[1])\r
+        for Type in CTypeTuple:\r
+            if PatternInModifier(Result[0], Type):\r
+                PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, 'Return type %s' % Result[0], FileTable, Result[2])\r
+            \r
+            for Param in ParamList:\r
+                if PatternInModifier(Param.Modifier, Type):\r
+                    PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, 'Parameter %s' % Param.Name, FileTable, Result[2])\r
+            \r
+\r
+def CheckPointerNullComparison(FullFileName):\r
+    ErrorMsgList = []\r
+    \r
+    FileID = GetTableID(FullFileName, ErrorMsgList)\r
+    if FileID < 0:\r
+        return ErrorMsgList\r
+    \r
+    Db = GetDB()\r
+    FileTable = 'Identifier' + str(FileID)\r
+    SqlStatement = """ select Value, StartLine, ID\r
+                       from %s\r
+                       where Model = %d\r
+                   """ % (FileTable, DataClass.MODEL_IDENTIFIER_PREDICATE_EXPRESSION)\r
+    ResultSet = Db.TblFile.Exec(SqlStatement)\r
+    if len(ResultSet) == 0:\r
+        return\r
+    PSL = []\r
+    for Result in ResultSet:\r
+        PSL.append([Result[0], Result[1], Result[2]])\r
+    \r
+    SqlStatement = """ select BodyStartLine, EndLine, Header, Modifier, ID\r
+                       from Function\r
+                       where BelongsToFile = %d\r
+                   """ % (FileID)\r
+    ResultSet = Db.TblFile.Exec(SqlStatement)\r
+    FL = []\r
+    for Result in ResultSet:\r
+        FL.append([Result[0], Result[1], Result[2], Result[3], Result[4]])\r
+    \r
+    for Str in PSL:\r
+        FuncRecord = GetFuncContainsPE(Str[1], FL)\r
+        if FuncRecord == None:\r
+            continue\r
+        \r
+        for Exp in GetPredicateListFromPredicateExpStr(Str[0]):\r
+            PredInfo = SplitPredicateStr(Exp)\r
+            if PredInfo[1] == None:\r
+                PredVar = GetPredicateVariable(PredInfo[0][0])\r
+                # No variable found, maybe value first? like (0 == VarName)\r
+                if PredVar == None:\r
+                    continue\r
+                # in the form of function call\r
+                if len(PredInfo[0][0]) - PredInfo[0][0].find(PredVar) > len(PredVar):\r
+                    RemainingPos = PredInfo[0][0].find(PredVar) + len(PredVar)\r
+                    if PredInfo[0][0][RemainingPos:].strip().startswith('('):\r
+                        continue\r
+                # really variable, search local variable first\r
+                SqlStatement = """ select Modifier, ID\r
+                       from %s\r
+                       where Model = %d and Name = \'%s\' and BelongsToFunction = %d\r
+                   """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE, PredVar, FuncRecord[4])\r
+                ResultSet = Db.TblFile.Exec(SqlStatement)\r
+                VarFound = False\r
+                for Result in ResultSet:\r
+                    if Result[0].find('*') != -1:\r
+                        PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE, 'Variable Name: %s' % PredVar, FileTable, Str[2])\r
+                    VarFound = True\r
+                if VarFound:\r
+                    continue\r
+                \r
+                # search function parameters second\r
+                ParamList = GetParamList(FuncRecord[2])\r
+                for Param in ParamList:\r
+                    if Param.Name.strip() == PredVar:\r
+                        if Param.Modifier.find('*') != -1:\r
+                            PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE, 'Variable Name: %s' % PredVar, FileTable, Str[2])\r
+                        VarFound = True\r
+                if VarFound:\r
+                    continue            \r
+                # search global variable next\r
+                SqlStatement = """ select Modifier, ID\r
+                       from %s\r
+                       where Model = %d and Name = \'%s\' and BelongsToFunction = -1\r
+                   """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE, PredVar)\r
+                ResultSet = Db.TblFile.Exec(SqlStatement)\r
+\r
+                for Result in ResultSet:\r
+                    if Result[0].find('*') != -1:\r
+                        PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE, 'Variable Name: %s' % PredVar, FileTable, Str[2])\r
+                    VarFound = True\r
+                if VarFound:\r
+                    continue\r
+                # search variable in include files\r
+\r
+\r
+def CheckNonBooleanValueComparison(FullFileName):\r
+    ErrorMsgList = []\r
+    \r
+    FileID = GetTableID(FullFileName, ErrorMsgList)\r
+    if FileID < 0:\r
+        return ErrorMsgList\r
+    \r
+    Db = GetDB()\r
+    FileTable = 'Identifier' + str(FileID)\r
+    SqlStatement = """ select Value, StartLine, ID\r
+                       from %s\r
+                       where Model = %d\r
+                   """ % (FileTable, DataClass.MODEL_IDENTIFIER_PREDICATE_EXPRESSION)\r
+    ResultSet = Db.TblFile.Exec(SqlStatement)\r
+    if len(ResultSet) == 0:\r
+        return\r
+    PSL = []\r
+    for Result in ResultSet:\r
+        PSL.append([Result[0], Result[1], Result[2]])\r
+    \r
+    SqlStatement = """ select BodyStartLine, EndLine, Header, Modifier, ID\r
+                       from Function\r
+                       where BelongsToFile = %d\r
+                   """ % (FileID)\r
+    ResultSet = Db.TblFile.Exec(SqlStatement)\r
+    FL = []\r
+    for Result in ResultSet:\r
+        FL.append([Result[0], Result[1], Result[2], Result[3], Result[4]])\r
+    \r
+    for Str in PSL:\r
+        FuncRecord = GetFuncContainsPE(Str[1], FL)\r
+        if FuncRecord == None:\r
+            continue\r
+        \r
+        for Exp in GetPredicateListFromPredicateExpStr(Str[0]):\r
+            PredInfo = SplitPredicateStr(Exp)\r
+            if PredInfo[1] == None:\r
+                PredVar = GetPredicateVariable(PredInfo[0][0])\r
+                # No variable found, maybe value first? like (0 == VarName)\r
+                if PredVar == None:\r
+                    continue\r
+                # in the form of function call\r
+                if len(PredInfo[0][0]) - PredInfo[0][0].find(PredVar) > len(PredVar):\r
+                    RemainingPos = PredInfo[0][0].find(PredVar) + len(PredVar)\r
+                    if PredInfo[0][0][RemainingPos:].strip().startswith('('):\r
+                        continue\r
+                # really variable, search local variable first\r
+                SqlStatement = """ select Modifier, ID\r
+                       from %s\r
+                       where Model = %d and Name = \'%s\' and BelongsToFunction = %d\r
+                   """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE, PredVar, FuncRecord[4])\r
+                ResultSet = Db.TblFile.Exec(SqlStatement)\r
+                VarFound = False\r
+                for Result in ResultSet:\r
+                    if not PatternInModifier(Result[0], 'BOOLEAN'):\r
+                        PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR, 'Variable Name: %s' % PredVar, FileTable, Str[2])\r
+                    VarFound = True\r
+                if VarFound:\r
+                    continue\r
+                \r
+                # search function parameters second\r
+                ParamList = GetParamList(FuncRecord[2])\r
+                for Param in ParamList:\r
+                    if Param.Name.strip() == PredVar:\r
+                        if not PatternInModifier(Param.Modifier, 'BOOLEAN'):\r
+                            PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR, 'Variable Name: %s' % PredVar, FileTable, Str[2])\r
+                        VarFound = True\r
+                if VarFound:\r
+                    continue            \r
+                # search global variable next\r
+                SqlStatement = """ select Modifier, ID\r
+                       from %s\r
+                       where Model = %d and Name = \'%s\' and BelongsToFunction = -1\r
+                   """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE, PredVar)\r
+                ResultSet = Db.TblFile.Exec(SqlStatement)\r
+\r
+                for Result in ResultSet:\r
+                    if not PatternInModifier(Result[0], 'BOOLEAN'):\r
+                        PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR, 'Variable Name: %s' % PredVar, FileTable, Str[2])\r
+                    VarFound = True\r
+                if VarFound:\r
+                    continue\r
+                # search variable in include files\r
+\r
+\r
+def CheckBooleanValueComparison(FullFileName):\r
+    ErrorMsgList = []\r
+    \r
+    FileID = GetTableID(FullFileName, ErrorMsgList)\r
+    if FileID < 0:\r
+        return ErrorMsgList\r
+    \r
+    Db = GetDB()\r
+    FileTable = 'Identifier' + str(FileID)\r
+    SqlStatement = """ select Value, StartLine, ID\r
+                       from %s\r
+                       where Model = %d\r
+                   """ % (FileTable, DataClass.MODEL_IDENTIFIER_PREDICATE_EXPRESSION)\r
+    ResultSet = Db.TblFile.Exec(SqlStatement)\r
+    if len(ResultSet) == 0:\r
+        return\r
+    PSL = []\r
+    for Result in ResultSet:\r
+        PSL.append([Result[0], Result[1], Result[2]])\r
+    \r
+    SqlStatement = """ select BodyStartLine, EndLine, Header, Modifier, ID\r
+                       from Function\r
+                       where BelongsToFile = %d\r
+                   """ % (FileID)\r
+    ResultSet = Db.TblFile.Exec(SqlStatement)\r
+    FL = []\r
+    for Result in ResultSet:\r
+        FL.append([Result[0], Result[1], Result[2], Result[3], Result[4]])\r
+    \r
+    for Str in PSL:\r
+        FuncRecord = GetFuncContainsPE(Str[1], FL)\r
+        if FuncRecord == None:\r
+            continue\r
+        \r
+        for Exp in GetPredicateListFromPredicateExpStr(Str[0]):\r
+            PredInfo = SplitPredicateStr(Exp)\r
+            if PredInfo[1] in ('==', '!=') and PredInfo[0][1] in ('TRUE', 'FALSE'):\r
+                PredVar = GetPredicateVariable(PredInfo[0][0])\r
+                # No variable found, maybe value first? like (0 == VarName)\r
+                if PredVar == None:\r
+                    continue\r
+                # in the form of function call\r
+                if len(PredInfo[0][0]) - PredInfo[0][0].find(PredVar) > len(PredVar):\r
+                    RemainingPos = PredInfo[0][0].find(PredVar) + len(PredVar)\r
+                    if PredInfo[0][0][RemainingPos:].strip().startswith('('):\r
+                        continue\r
+                # really variable, search local variable first\r
+                SqlStatement = """ select Modifier, ID\r
+                       from %s\r
+                       where Model = %d and Name = \'%s\' and BelongsToFunction = %d\r
+                   """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE, PredVar, FuncRecord[4])\r
+                ResultSet = Db.TblFile.Exec(SqlStatement)\r
+                VarFound = False\r
+                for Result in ResultSet:\r
+                    if PatternInModifier(Result[0], 'BOOLEAN'):\r
+                        PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE, 'Variable Name: %s' % PredVar, FileTable, Str[2])\r
+                    VarFound = True\r
+                if VarFound:\r
+                    continue\r
+                \r
+                # search function parameters second\r
+                ParamList = GetParamList(FuncRecord[2])\r
+                for Param in ParamList:\r
+                    if Param.Name.strip() == PredVar:\r
+                        if PatternInModifier(Param.Modifier, 'BOOLEAN'):\r
+                            PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE, 'Variable Name: %s' % PredVar, FileTable, Str[2])\r
+                        VarFound = True\r
+                if VarFound:\r
+                    continue            \r
+                # search global variable next\r
+                SqlStatement = """ select Modifier, ID\r
+                       from %s\r
+                       where Model = %d and Name = \'%s\' and BelongsToFunction = -1\r
+                   """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE, PredVar)\r
+                ResultSet = Db.TblFile.Exec(SqlStatement)\r
+\r
+                for Result in ResultSet:\r
+                    if PatternInModifier(Result[0], 'BOOLEAN'):\r
+                        PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE, 'Variable Name: %s' % PredVar, FileTable, Str[2])\r
+                    VarFound = True\r
+                if VarFound:\r
+                    continue\r
+                # search variable in include files\r
+                \r
+\r
 def CheckHeaderFileData(FullFileName):\r
     ErrorMsgList = []\r
     \r