git-svn-id: https://buildtools.tianocore.org/svn/buildtools/trunk/BaseTools@1094...
authorjlin16 <jlin16@7335b38e-4728-0410-8992-fb3ffe349368>
Fri, 28 Mar 2008 10:24:38 +0000 (10:24 +0000)
committerjlin16 <jlin16@7335b38e-4728-0410-8992-fb3ffe349368>
Fri, 28 Mar 2008 10:24:38 +0000 (10:24 +0000)
Source/Python/Ecc/Check.py
Source/Python/Ecc/c.py

index 09dca16..ad02339 100644 (file)
@@ -36,8 +36,115 @@ class Check(object):
         self.IncludeFileCheck()\r
         self.PredicateExpressionCheck()\r
         self.DeclAndDataTypeCheck()\r
+        self.FunctionLayoutCheck()\r
         self.NamingConventionCheck()\r
     \r
+    #\r
+    # C Function Layout Checking\r
+    #\r
+    def FunctionLayoutCheck(self):\r
+        self.FunctionLayoutCheckReturnType()\r
+        self.FunctionLayoutCheckModifier()\r
+        self.FunctionLayoutCheckName()\r
+        self.FunctionLayoutCheckPrototype()\r
+        self.FunctionLayoutCheckBody()\r
+        self.FunctionLayoutCheckLocalVariable()\r
+    \r
+    # Check whether return type exists and in the first line\r
+    def FunctionLayoutCheckReturnType(self):\r
+        if EccGlobalData.gConfig.CFunctionLayoutCheckReturnType == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1':\r
+            EdkLogger.quiet("Checking function layout return 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 ('.c'):\r
+                        FullName = os.path.join(Dirpath, F)\r
+                        c.CheckFuncLayoutReturnType(FullName)\r
+    \r
+    # Check whether any optional functional modifiers exist and next to the return type\r
+    def FunctionLayoutCheckModifier(self):\r
+        if EccGlobalData.gConfig.CFunctionLayoutCheckOptionalFunctionalModifier == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1':\r
+            EdkLogger.quiet("Checking function layout 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 ('.c'):\r
+                        FullName = os.path.join(Dirpath, F)\r
+                        c.CheckFuncLayoutModifier(FullName)\r
+                        \r
+    # Check whether the next line contains the function name, left justified, followed by the beginning of the parameter list\r
+    # Check whether the closing parenthesis is on its own line and also indented two spaces\r
+    def FunctionLayoutCheckName(self):\r
+        if EccGlobalData.gConfig.CFunctionLayoutCheckFunctionName == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1':\r
+            EdkLogger.quiet("Checking function layout function name ...")\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.CheckFuncLayoutName(FullName)\r
+    # Check whether the function prototypes in include files have the same form as function definitions\r
+    def FunctionLayoutCheckPrototype(self):\r
+        if EccGlobalData.gConfig.CFunctionLayoutCheckFunctionPrototype == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1':\r
+            EdkLogger.quiet("Checking function layout function prototype ...")\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.CheckFuncLayoutPrototype(FullName)\r
+\r
+    # Check whether the body of a function is contained by open and close braces that must be in the first column\r
+    def FunctionLayoutCheckBody(self):\r
+        if EccGlobalData.gConfig.CFunctionLayoutCheckFunctionBody == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1':\r
+            EdkLogger.quiet("Checking function layout function body ...")\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.CheckFuncLayoutBody(FullName)\r
+\r
+    # Check whether the data declarations is the first code in a module.\r
+    #self.CFunctionLayoutCheckDataDeclaration = 1\r
+    # Check whether no initialization of a variable as part of its declaration\r
+    def FunctionLayoutCheckLocalVariable(self):\r
+        if EccGlobalData.gConfig.CFunctionLayoutCheckNoInitOfVariable == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1':\r
+            EdkLogger.quiet("Checking function layout local variables ...")\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.CheckFuncLayoutLocalVariable(FullName)\r
+\r
+    # Check whether no use of STATIC for functions\r
+    #self.CFunctionLayoutCheckNoStatic = 1\r
+    \r
     #\r
     # Declarations and Data Types Checking\r
     #\r
@@ -88,17 +195,47 @@ class Check(object):
     # 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
+            EdkLogger.quiet("Checking Declaration enum typedef ...")\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.CheckDeclEnumTypedef(FullName)\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
+            EdkLogger.quiet("Checking Declaration struct typedef ...")\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.CheckDeclStructTypedef(FullName)\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
+            EdkLogger.quiet("Checking Declaration union typedef ...")\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.CheckDeclUnionTypedef(FullName)\r
     \r
     #\r
     # Predicate Expression Checking\r
index 87a8014..ec02a2a 100644 (file)
@@ -8,7 +8,11 @@ import Database
 from Common import EdkLogger\r
 from EccToolError import *\r
 import EccGlobalData\r
+import MetaDataParser\r
 \r
+IncludeFileListDict = {}\r
+IncludePathListDict = {}\r
+ComplexTypeDict = {}\r
 \r
 def GetIgnoredDirListPattern():\r
     p = re.compile(r'.*[\\/](?:BUILD|INTELRESTRICTEDTOOLS|INTELRESTRICTEDPKG|PCCTS)[\\/].*')\r
@@ -18,6 +22,14 @@ def GetFuncDeclPattern():
     p = re.compile(r'[_\w]*\s*\(.*\).*', re.DOTALL)\r
     return p\r
 \r
+def GetArrayPattern():\r
+    p = re.compile(r'[_\w]*\s*[\[.*\]]+')\r
+    return p\r
+\r
+def GetTypedefFuncPointerPattern():\r
+    p = re.compile('[_\w\s]*\([\w\s]*\*+\s*[_\w]+\s*\)\s*\(.*\)', re.DOTALL)\r
+    return p\r
+\r
 def GetDB():\r
     return EccGlobalData.gDb\r
 \r
@@ -69,6 +81,7 @@ def GetIdentifierList():
         IdList.append(IdPE)\r
         \r
     FuncDeclPattern = GetFuncDeclPattern()\r
+    ArrayPattern = GetArrayPattern()\r
     for var in FileProfile.VariableDeclarationList:\r
         DeclText = var.Declarator.strip()\r
         while DeclText.startswith('*'):\r
@@ -83,11 +96,22 @@ def GetIdentifierList():
         if var.Declarator.find('{') == -1:      \r
             for decl in var.Declarator.split(','):\r
                 DeclList = decl.split('=')\r
-                IdVar = DataClass.IdentifierClass(-1, var.Modifier, '', DeclList[0].strip(), (len(DeclList) > 1 and [DeclList[1]]or [''])[0], DataClass.MODEL_IDENTIFIER_VARIABLE, -1, -1, var.StartPos[0],var.StartPos[1],var.EndPos[0],var.EndPos[1])\r
+                Name = DeclList[0].strip()\r
+                if ArrayPattern.match(Name):\r
+                    LSBPos = var.Declarator.find('[')\r
+                    var.Modifier += ' ' + Name[LSBPos:]\r
+                    Name = Name[0:LSBPos]\r
+            \r
+                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],var.EndPos[0],var.EndPos[1])\r
                 IdList.append(IdVar)\r
         else:\r
             DeclList = var.Declarator.split('=')\r
-            IdVar = DataClass.IdentifierClass(-1, var.Modifier, '', DeclList[0].strip(), (len(DeclList) > 1 and [DeclList[1]]or [''])[0], DataClass.MODEL_IDENTIFIER_VARIABLE, -1, -1, var.StartPos[0],var.StartPos[1],var.EndPos[0],var.EndPos[1])\r
+            Name = DeclList[0].strip()\r
+            if ArrayPattern.match(Name):\r
+                LSBPos = var.Declarator.find('[')\r
+                var.Modifier += ' ' + Name[LSBPos:]\r
+                Name = Name[0:LSBPos]\r
+            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],var.EndPos[0],var.EndPos[1])\r
             IdList.append(IdVar)\r
             \r
     for enum in FileProfile.EnumerationDefinitionList:\r
@@ -106,13 +130,36 @@ def GetIdentifierList():
             SkipLen = 5\r
         LBPos = su.Content.find('{')\r
         RBPos = su.Content.find('}')\r
-        Name = su.Content[SkipLen:LBPos].strip()\r
-        Value = su.Content[LBPos+1:RBPos]\r
+        if LBPos == -1 or RBPos == -1:\r
+            Name = su.Content[SkipLen:].strip()\r
+            Value = ''\r
+        else:\r
+            Name = su.Content[SkipLen:LBPos].strip()\r
+            Value = su.Content[LBPos+1:RBPos]\r
         IdPE = DataClass.IdentifierClass(-1, '', '', Name, Value, Type, -1, -1, su.StartPos[0],su.StartPos[1],su.EndPos[0],su.EndPos[1])\r
         IdList.append(IdPE)\r
-        \r
+    \r
+    TdFuncPointerPattern = GetTypedefFuncPointerPattern()    \r
     for td in FileProfile.TypedefDefinitionList:\r
-        IdTd = DataClass.IdentifierClass(-1, '', '', td.ToType, td.FromType, DataClass.MODEL_IDENTIFIER_TYPEDEF, -1, -1, td.StartPos[0],td.StartPos[1],td.EndPos[0],td.EndPos[1])\r
+        Modifier = ''\r
+        Name = td.ToType\r
+        Value = td.FromType\r
+        if TdFuncPointerPattern.match(td.ToType):\r
+            Modifier = td.FromType\r
+            LBPos = td.ToType.find('(')\r
+            TmpStr = td.ToType[LBPos+1:].strip()\r
+            StarPos = TmpStr.find('*')\r
+            if StarPos != -1:\r
+                Modifier += ' ' + TmpStr[0:StarPos]\r
+            while TmpStr[StarPos] == '*':\r
+                Modifier += ' ' + '*'\r
+                StarPos += 1\r
+            TmpStr = TmpStr[StarPos:].strip()\r
+            RBPos = TmpStr.find(')')\r
+            Name = TmpStr[0:RBPos]\r
+            Value = 'FP' + TmpStr[RBPos + 1:]\r
+            \r
+        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])\r
         IdList.append(IdTd)\r
         \r
     for funcCall in FileProfile.FunctionCallingList:\r
@@ -124,7 +171,7 @@ def GetParamList(FuncDeclarator, FuncNameLine = 0, FuncNameOffset = 0):
     ParamIdList = []\r
     DeclSplitList = FuncDeclarator.split('(')\r
     if len(DeclSplitList) < 2:\r
-        return None\r
+        return ParamIdList\r
     FuncName = DeclSplitList[0]\r
     ParamStr = DeclSplitList[1].rstrip(')')\r
     LineSkipped = 0\r
@@ -149,7 +196,7 @@ def GetParamList(FuncDeclarator, FuncNameLine = 0, FuncNameOffset = 0):
         ParamModifier = p[0:RightSpacePos]\r
         if ParamName == 'OPTIONAL':\r
             if ParamModifier == '':\r
-                ParamModifier += 'OPTIONAL'\r
+                ParamModifier += ' ' + 'OPTIONAL'\r
                 DeclText = ''\r
             else:\r
                 ParamName = ListP[-2]\r
@@ -158,7 +205,7 @@ def GetParamList(FuncDeclarator, FuncNameLine = 0, FuncNameOffset = 0):
                 ParamModifier = p[0:RightSpacePos]\r
                 ParamModifier += 'OPTIONAL'\r
         while DeclText.startswith('*'):\r
-            ParamModifier += '*'\r
+            ParamModifier += ' ' + '*'\r
             DeclText = DeclText.lstrip('*').strip()\r
         ParamName = DeclText\r
         \r
@@ -187,12 +234,21 @@ def GetFunctionList():
         while DeclText.startswith('*'):\r
             FuncDef.Modifier += '*'\r
             DeclText = DeclText.lstrip('*').strip()\r
-        FuncDef.Declarator = DeclText\r
+        \r
+        FuncDef.Declarator = FuncDef.Declarator.replace('*', '')\r
         DeclSplitList = FuncDef.Declarator.split('(')\r
         if len(DeclSplitList) < 2:\r
             continue\r
         \r
         FuncName = DeclSplitList[0]\r
+        FuncNamePartList = FuncName.split()\r
+        if len(FuncNamePartList) > 1:\r
+            FuncName = FuncNamePartList[-1]\r
+            Index = 0\r
+            while Index < len(FuncNamePartList) - 1:\r
+                FuncDef.Modifier += ' ' + FuncNamePartList[Index]\r
+                Index += 1\r
+                \r
         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, [])\r
         FuncObjList.append(FuncObj)\r
         \r
@@ -259,6 +315,10 @@ def GetTableID(FullFileName, ErrorMsgList):
     return FileID\r
 \r
 def GetIncludeFileList(FullFileName):\r
+    IFList = IncludeFileListDict.get(FullFileName)\r
+    if IFList != None:\r
+        return IFList\r
+    \r
     ErrorMsgList = []\r
     \r
     FileID = GetTableID(FullFileName, ErrorMsgList)\r
@@ -272,23 +332,41 @@ def GetIncludeFileList(FullFileName):
                        where Model = %d\r
                    """ % (FileTable, DataClass.MODEL_IDENTIFIER_INCLUDE)\r
     ResultSet = Db.TblFile.Exec(SqlStatement)\r
+    IncludeFileListDict[FullFileName] = ResultSet\r
     return ResultSet\r
 \r
-def GetFullPathOfIncludeFile(Str):\r
-    pass\r
+def GetFullPathOfIncludeFile(Str, IncludePathList):\r
+    for IncludePath in IncludePathList:\r
+        FullPath = os.path.join(IncludePath, Str)\r
+        if os.path.exists(FullPath):\r
+            return FullPath\r
+    return None\r
 \r
 def GetAllIncludeFiles(FullFileName):\r
-\r
+    IncludePathList = IncludePathListDict.get(os.path.dirname(FullFileName))\r
+    if IncludePathList == None:\r
+        IncludePathList = MetaDataParser.GetIncludeListOfFile(EccGlobalData.gWorkspace, FullFileName, GetDB())\r
+        IncludePathList.insert(0, os.path.dirname(FullFileName))\r
+        IncludePathListDict[os.path.dirname(FullFileName)] = IncludePathList\r
     IncludeFileQueue = []\r
     for IncludeFile in GetIncludeFileList(FullFileName):\r
-        FullPath = GetFullPathOfIncludeFile(IncludeFile[0])\r
-        IncludeFileQueue.append(FullPath)\r
+        FileName = IncludeFile[0].lstrip('#').strip()\r
+        FileName = FileName.lstrip('include').strip()\r
+        FileName = FileName.strip('\"')\r
+        FileName = FileName.lstrip('<').rstrip('>').strip()\r
+        FullPath = GetFullPathOfIncludeFile(FileName, IncludePathList)\r
+        if FullPath != None:\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
+            FileName = IncludeFile[0].lstrip('#').strip()\r
+            FileName = FileName.lstrip('include').strip()\r
+            FileName = FileName.strip('\"')\r
+            FileName = FileName.lstrip('<').rstrip('>').strip()\r
+            FullPath = GetFullPathOfIncludeFile(FileName, IncludePathList)\r
+            if FullPath != None and FullPath not in IncludeFileQueue:\r
                 IncludeFileQueue.insert(i + 1, FullPath)\r
         i += 1\r
     return IncludeFileQueue\r
@@ -314,23 +392,40 @@ def GetPredicateListFromPredicateExpStr(PES):
     \r
 def GetPredicateVariable(Lvalue):\r
     i = 0\r
+    SearchBegin = 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
+    VarList = []\r
+    while SearchBegin < len(Lvalue):\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
+                VarList.append(Lvalue[VarStart:VarEnd+1])\r
+                i += 1\r
+                break\r
+            else:\r
+                i += 1\r
+        if VarEnd == -1:\r
             break\r
+        \r
+        Index = Lvalue[VarEnd:].find('.')\r
+        if Index > 0:\r
+            SearchBegin += VarEnd + Index\r
         else:\r
-            i += 1\r
-    \r
-    if VarStart != -1:\r
-        return Lvalue[VarStart:VarEnd+1]\r
+            Index = Lvalue[VarEnd:].find('->')\r
+            if Index > 0:\r
+                SearchBegin += VarEnd + Index\r
+            else:\r
+                break\r
+        i = SearchBegin\r
+        VarStart = -1\r
+        VarEnd = -1\r
     \r
-    return None    \r
+    return VarList    \r
 \r
 def SplitPredicateByOp(Str, Op):\r
 \r
@@ -384,6 +479,438 @@ def PatternInModifier(Modifier, SubStr):
             return True\r
     return False\r
 \r
+def GetReturnTypeFromModifier(ModifierStr):\r
+    MList = ModifierStr.split()\r
+    for M in MList:\r
+        if M in EccGlobalData.gConfig.ModifierList:\r
+            MList.remove(M)\r
+            \r
+    ReturnType = ''\r
+    for M in MList:\r
+        ReturnType += M + ' '\r
+    return ReturnType.strip()    \r
+\r
+def DiffModifier(Str1, Str2):\r
+    PartList1 = Str1.split()\r
+    PartList2 = Str2.split()\r
+    if PartList1 == PartList2:\r
+        return False\r
+    else:\r
+        return True\r
+    \r
+def GetTypedefDict(FullFileName):\r
+    \r
+    Dict = ComplexTypeDict.get(FullFileName)\r
+    if Dict != None:\r
+        return Dict\r
+    \r
+    FileID = GetTableID(FullFileName, ErrorMsgList)\r
+    FileTable = 'Identifier' + str(FileID)\r
+    Db = GetDB()\r
+    SqlStatement = """ select Modifier, Name, Value, ID\r
+                       from %s\r
+                       where Model = %d\r
+                   """ % (FileTable, DataClass.MODEL_IDENTIFIER_TYPEDEF)\r
+    ResultSet = Db.TblFile.Exec(SqlStatement)\r
+    \r
+    Dict = {}\r
+    for Result in ResultSet:\r
+        if len(Result[0]) == 0:\r
+            Dict[Result[1]] = Result[2]\r
+        \r
+    IncludeFileList = GetAllIncludeFiles(FullFileName)\r
+    for F in IncludeFileList:\r
+        FileID = GetTableID(F, ErrorMsgList)\r
+        if FileID < 0:\r
+            continue\r
+    \r
+        FileTable = 'Identifier' + str(FileID)\r
+        SqlStatement = """ select Modifier, Name, Value, ID\r
+                       from %s\r
+                       where Model = %d\r
+                   """ % (FileTable, DataClass.MODEL_IDENTIFIER_TYPEDEF)\r
+        ResultSet = Db.TblFile.Exec(SqlStatement)\r
+    \r
+        Dict = {}\r
+        for Result in ResultSet:\r
+            if len(Result[0]) == 0:\r
+                Dict[Result[1]] = Result[2]\r
+                \r
+    ComplexTypeDict[FullFileName] = Dict\r
+    return Dict\r
+\r
+def GetTypeInfo(RefList, Modifier, FullFileName):\r
+    TypedefDict = GetTypedefDict(FullFileName)\r
+    Type = GetReturnTypeFromModifier(Modifier)\r
+    Index = 0\r
+    while Index < len(RefList):\r
+        FieldName = RefList[Index]\r
+        FromType = GetFinalTypeValue(Type, FieldName, TypedefDict, SUDict)\r
+        if FromType == None:\r
+            return None\r
+        Type = FromType\r
+        Index += 1\r
+\r
+def GetVarInfo(PredVarList, FuncRecord, FullFileName):\r
+    \r
+    PredVar = PredVarList[0]\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 len(PredVarList) > 1:\r
+            Type = GetTypeInfo(PredVarList[1:], Result[0])\r
+            return Type\r
+                \r
+    # search function parameters second\r
+    ParamList = GetParamList(FuncRecord[2])\r
+    for Param in ParamList:\r
+        if Param.Name.strip() == PredVar:\r
+            if len(PredVarList) > 1:\r
+                Type = GetTypeInfo(PredVarList[1:], Result[0])\r
+                return Type\r
+          \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 len(PredVarList) > 1:\r
+            Type = GetTypeInfo(PredVarList[1:], Result[0])\r
+            return Type\r
+    \r
+    # search variable in include files\r
+    IncludeFileList = GetAllIncludeFiles(FullFileName)\r
+    for F in IncludeFileList:\r
+        FileID = GetTableID(F, ErrorMsgList)\r
+        if FileID < 0:\r
+            continue\r
+    \r
+        FileTable = 'Identifier' + str(FileID)\r
+        SqlStatement = """ select Modifier, ID\r
+                       from %s\r
+                       where Model = %d and BelongsToFunction = -1 and Name = %s\r
+                   """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE, PredVar)\r
+        ResultSet = Db.TblFile.Exec(SqlStatement)\r
+\r
+        for Result in ResultSet:\r
+            if len(PredVarList) > 1:\r
+                Type = GetTypeInfo(PredVarList[1:], Result[0])\r
+                return Type\r
+\r
+def CheckFuncLayoutReturnType(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, 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
+        ReturnType = GetReturnTypeFromModifier(Result[0])\r
+        if len(ReturnType) == 0:\r
+            PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '', FileTable, Result[1])\r
+            continue\r
+        Index = Result[0].find(ReturnType)\r
+        if Index != 0:\r
+            PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '', FileTable, Result[1])\r
+            \r
+        if Result[0].find('\n') == -1 or Result[0].find('\r') == -1:\r
+            PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '', FileTable, Result[1])\r
+            \r
+    SqlStatement = """ select Modifier, ID\r
+                       from Function\r
+                       where BelongsToFile = %d\r
+                   """ % (FileID)\r
+    ResultSet = Db.TblFile.Exec(SqlStatement)\r
+    for Result in ResultSet:\r
+        ReturnType = GetReturnTypeFromModifier(Result[0])\r
+        if len(ReturnType) == 0:\r
+            PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '', 'Function', Result[1])\r
+            continue\r
+        Index = Result[0].find(ReturnType)\r
+        if Index != 0:\r
+            PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '', 'Function', Result[1])\r
+            \r
+#        if Result[0].find('\n') == -1 or Result[0].find('\r') == -1:\r
+#            PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '', 'Function', Result[1])\r
+    \r
+def CheckFuncLayoutModifier(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, 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
+        ReturnType = GetReturnTypeFromModifier(Result[0])\r
+        if len(ReturnType) == 0:\r
+            continue\r
+        Index = Result[0].find(ReturnType)\r
+        if Index != 0:\r
+            PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_OPTIONAL_FUNCTIONAL_MODIFIER, '', FileTable, Result[1])\r
+            \r
+    SqlStatement = """ select Modifier, ID\r
+                       from Function\r
+                       where BelongsToFile = %d\r
+                   """ % (FileID)\r
+    ResultSet = Db.TblFile.Exec(SqlStatement)\r
+    for Result in ResultSet:\r
+        ReturnType = GetReturnTypeFromModifier(Result[0])\r
+        if len(ReturnType) == 0:\r
+            continue\r
+        Index = Result[0].find(ReturnType)\r
+        if Index != 0:\r
+            PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_OPTIONAL_FUNCTIONAL_MODIFIER, '', FileTable, Result[1])\r
+\r
+def CheckFuncLayoutName(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 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[0])\r
+        if len(ParamList) == 0:\r
+            continue\r
+        StartLine = 0\r
+        for Param in ParamList:\r
+            if Param.StartLine <= StartLine:\r
+                PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Parameter %s should be in its own line.' % Param.Name, FileTable, Result[1])\r
+            StartLine = Param.StartLine\r
+            if not Result[0].endswith('\n  )') and not Result[0].endswith('\r  )'):\r
+                PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, '\')\' should be on a new line and indented two spaces', FileTable, Result[1])\r
+            \r
+    SqlStatement = """ select Modifier, 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[0])\r
+        if len(ParamList) == 0:\r
+            continue\r
+        StartLine = 0\r
+        for Param in ParamList:\r
+            if Param.StartLine <= StartLine:\r
+                PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Parameter %s should be in its own line.' % Param.Name, 'Function', Result[1])\r
+            StartLine = Param.StartLine\r
+            if not Result[0].endswith('\n  )') and not Result[0].endswith('\r  )'):\r
+                PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, '\')\' should be on a new line and indented two spaces', 'Function', Result[1])\r
+\r
+def CheckFuncLayoutPrototype(FullFileName):\r
+    ErrorMsgList = []\r
+    \r
+    FileID = GetTableID(FullFileName, ErrorMsgList)\r
+    if FileID < 0:\r
+        return ErrorMsgList\r
+    \r
+    FileTable = 'Identifier' + str(FileID)\r
+    Db = GetDB()\r
+    SqlStatement = """ select Modifier, Header, Name, ID\r
+                       from Function\r
+                       where BelongsToFile = %d\r
+                   """ % (FileID)\r
+    ResultSet = Db.TblFile.Exec(SqlStatement)\r
+    if len(ResultSet) == 0:\r
+        return ErrorMsgList\r
+    \r
+    FuncDefList = []\r
+    for Result in ResultSet:\r
+        FuncDefList.append(Result)\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
+    FuncDeclList = []\r
+    for Result in ResultSet:\r
+        FuncDeclList.append(Result)\r
+    \r
+    IncludeFileList = GetAllIncludeFiles(FullFileName)\r
+    for F in IncludeFileList:\r
+        FileID = GetTableID(F, ErrorMsgList)\r
+        if FileID < 0:\r
+            continue\r
+    \r
+        FileTable = 'Identifier' + str(FileID)\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
+\r
+        for Result in ResultSet:\r
+            FuncDeclList.append(Result)\r
+    \r
+    for FuncDef in FuncDefList:\r
+        FuncName = FuncDef[2].strip()\r
+        FuncModifier = FuncDef[0]\r
+        FuncDefHeader = FuncDef[1]\r
+        for FuncDecl in FuncDeclList:\r
+            LBPos = FuncDecl[1].find('(')\r
+            DeclName = FuncDecl[1][0:LBPos].strip()\r
+            DeclModifier = FuncDecl[0]\r
+            if DeclName == FuncName:\r
+                if DiffModifier(FuncModifier, DeclModifier):\r
+                    PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, 'Function modifier different with prototype.', 'Function', FuncDef[3])\r
+                ParamListOfDef = GetParamList(FuncDefHeader)\r
+                ParamListOfDecl = GetParamList(FuncDecl[1])\r
+                if len(ParamListOfDef) != len(ParamListOfDecl):\r
+                    PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, 'Parameter number different.', 'Function', FuncDef[3])\r
+                    break\r
+\r
+                Index = 0\r
+                while Index < len(ParamListOfDef):\r
+                    if DiffModifier(ParamListOfDef[Index].Modifier, ParamListOfDecl[Index].Modifier):\r
+                        PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, 'Parameter %s has different modifier with prototype.' % ParamListOfDef[Index].Name, 'Function', FuncDef[3])\r
+                    Index += 1\r
+                break\r
+    \r
+def CheckFuncLayoutBody(FullFileName):\r
+    ErrorMsgList = []\r
+    \r
+    FileID = GetTableID(FullFileName, ErrorMsgList)\r
+    if FileID < 0:\r
+        return ErrorMsgList\r
+    \r
+    FileTable = 'Identifier' + str(FileID)\r
+    Db = GetDB()\r
+    SqlStatement = """ select BodyStartColumn, EndColumn, ID\r
+                       from Function\r
+                       where BelongsToFile = %d\r
+                   """ % (FileID)\r
+    ResultSet = Db.TblFile.Exec(SqlStatement)\r
+    if len(ResultSet) == 0:\r
+        return ErrorMsgList\r
+    for Result in ResultSet:\r
+        if Result[0] != 0:\r
+            PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY, 'open brace should be at the very beginning of a line.', 'Function', Result[2])\r
+        if Result[1] != 0:\r
+            PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY, 'close brace should be at the very beginning of a line.', 'Function', Result[2])\r
+\r
+def CheckFuncLayoutLocalVariable(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 ID\r
+                       from Function\r
+                       where BelongsToFile = %d\r
+                   """ % (FileID)\r
+    ResultSet = Db.TblFile.Exec(SqlStatement)\r
+    if len(ResultSet) == 0:\r
+        return ErrorMsgList\r
+    FL = []\r
+    for Result in ResultSet:\r
+        FL.append(Result)\r
+        \r
+    for F in FL:\r
+        SqlStatement = """ select Name, Value, ID\r
+                       from %s\r
+                       where Model = %d and BelongsToFunction = %d\r
+                   """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE, F[0])\r
+        ResultSet = Db.TblFile.Exec(SqlStatement)\r
+        if len(ResultSet) == 0:\r
+            continue\r
+        \r
+        for Result in ResultSet:\r
+            if len(Result[1]) > 0:\r
+                PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_NO_INIT_OF_VARIABLE, 'Variable Name: %s' % Result[0], FileTable, Result[2])\r
+        \r
+\r
+def CheckDeclTypedefFormat(FullFileName, ModelId):\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 Name, StartLine, EndLine, ID\r
+                       from %s\r
+                       where Model = %d\r
+                   """ % (FileTable, ModelId)\r
+    ResultSet = Db.TblFile.Exec(SqlStatement)\r
+    ResultList = []\r
+    for Result in ResultSet:\r
+        ResultList.append(Result)\r
+    \r
+    ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_ALL\r
+    if ModelId == DataClass.MODEL_IDENTIFIER_STRUCTURE:\r
+        ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_STRUCTURE_DECLARATION\r
+    if ModelId == DataClass.MODEL_IDENTIFIER_ENUMERATE:\r
+        ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_ENUMERATED_TYPE\r
+    if ModelId == DataClass.MODEL_IDENTIFIER_UNION:\r
+        ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_UNION_TYPE\r
+    \r
+    SqlStatement = """ select Modifier, Name, Value, StartLine, EndLine, ID\r
+                       from %s\r
+                       where Model = %d\r
+                   """ % (FileTable, DataClass.MODEL_IDENTIFIER_TYPEDEF)\r
+    TdSet = Db.TblFile.Exec(SqlStatement)\r
+    \r
+    for Result in ResultList:\r
+        Found = False\r
+        for Td in TdSet:\r
+            if len(Td[0]) > 0:\r
+                continue\r
+            if Result[1] >= Td[3] and Td[4] >= Result[2]:\r
+                Found = True\r
+                if not Td[1].isupper():\r
+                    PrintErrorMsg(ErrorType, 'Typedef should be UPPER case', FileTable, Td[5])\r
+            if Result[0] in Td[2].split():\r
+                Found = True\r
+                if not Td[1].isupper():\r
+                    PrintErrorMsg(ErrorType, 'Typedef should be UPPER case', FileTable, Td[5])\r
+        \r
+        if not Found:\r
+            PrintErrorMsg(ErrorType, 'No Typedef for %s' % Result[0], FileTable, Result[3])\r
+            continue\r
+                \r
+def CheckDeclStructTypedef(FullFileName):\r
+    CheckDeclTypedefFormat(FullFileName, DataClass.MODEL_IDENTIFIER_STRUCTURE)\r
+\r
+def CheckDeclEnumTypedef(FullFileName):\r
+    CheckDeclTypedefFormat(FullFileName, DataClass.MODEL_IDENTIFIER_ENUMERATE)\r
+    \r
+def CheckDeclUnionTypedef(FullFileName):\r
+    CheckDeclTypedefFormat(FullFileName, DataClass.MODEL_IDENTIFIER_UNION)\r
+\r
 def CheckDeclArgModifier(FullFileName):\r
     ErrorMsgList = []\r
     \r
@@ -509,6 +1036,7 @@ def CheckPointerNullComparison(FullFileName):
     for Result in ResultSet:\r
         FL.append([Result[0], Result[1], Result[2], Result[3], Result[4]])\r
     \r
+    p = GetFuncDeclPattern()\r
     for Str in PSL:\r
         FuncRecord = GetFuncContainsPE(Str[1], FL)\r
         if FuncRecord == None:\r
@@ -517,53 +1045,19 @@ def CheckPointerNullComparison(FullFileName):
         for Exp in GetPredicateListFromPredicateExpStr(Str[0]):\r
             PredInfo = SplitPredicateStr(Exp)\r
             if PredInfo[1] == None:\r
-                PredVar = GetPredicateVariable(PredInfo[0][0])\r
+                PredVarList = GetPredicateVariable(PredInfo[0][0])\r
                 # No variable found, maybe value first? like (0 == VarName)\r
-                if PredVar == None:\r
+                if len(PredVarList) == 0:\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
+                if p.match(PredInfo[0][0]):\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
+                Type = GetVarInfo(PredVarList, FuncRecord, FullFileName)\r
+                if Type == None:\r
                     continue\r
-                # search variable in include files\r
-\r
+                if Type.find('*') != -1:\r
+                    PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
 \r
 def CheckNonBooleanValueComparison(FullFileName):\r
     ErrorMsgList = []\r
@@ -594,6 +1088,7 @@ def CheckNonBooleanValueComparison(FullFileName):
     for Result in ResultSet:\r
         FL.append([Result[0], Result[1], Result[2], Result[3], Result[4]])\r
     \r
+    p = GetFuncDeclPattern()\r
     for Str in PSL:\r
         FuncRecord = GetFuncContainsPE(Str[1], FL)\r
         if FuncRecord == None:\r
@@ -602,53 +1097,19 @@ def CheckNonBooleanValueComparison(FullFileName):
         for Exp in GetPredicateListFromPredicateExpStr(Str[0]):\r
             PredInfo = SplitPredicateStr(Exp)\r
             if PredInfo[1] == None:\r
-                PredVar = GetPredicateVariable(PredInfo[0][0])\r
+                PredVarList = GetPredicateVariable(PredInfo[0][0])\r
                 # No variable found, maybe value first? like (0 == VarName)\r
-                if PredVar == None:\r
+                if len(PredVarList) == 0:\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
+                if p.match(PredInfo[0][0]):\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
+                Type = GetVarInfo(PredVarList, FuncRecord, FullFileName)\r
+                if Type == None:\r
                     continue\r
-                # search variable in include files\r
-\r
+                if Type.find('BOOLEAN') == -1:\r
+                    PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
 \r
 def CheckBooleanValueComparison(FullFileName):\r
     ErrorMsgList = []\r
@@ -679,6 +1140,7 @@ def CheckBooleanValueComparison(FullFileName):
     for Result in ResultSet:\r
         FL.append([Result[0], Result[1], Result[2], Result[3], Result[4]])\r
     \r
+    p = GetFuncDeclPattern()\r
     for Str in PSL:\r
         FuncRecord = GetFuncContainsPE(Str[1], FL)\r
         if FuncRecord == None:\r
@@ -687,52 +1149,19 @@ def CheckBooleanValueComparison(FullFileName):
         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
+                PredVarList = GetPredicateVariable(PredInfo[0][0])\r
                 # No variable found, maybe value first? like (0 == VarName)\r
-                if PredVar == None:\r
+                if len(PredVarList) == 0:\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
+                if p.match(PredInfo[0][0]):\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
+                Type = GetVarInfo(PredVarList, FuncRecord, FullFileName)\r
+                if Type == None:\r
                     continue\r
-                # search variable in include files\r
+                if Type.find('BOOLEAN') != -1:\r
+                    PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
                 \r
 \r
 def CheckHeaderFileData(FullFileName):\r