Home | History | Annotate | Download | only in Ecc
      1 ## @file

      2 # This file is used to define checkpoints used by ECC tool

      3 #

      4 # Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>

      5 # This program and the accompanying materials

      6 # are licensed and made available under the terms and conditions of the BSD License

      7 # which accompanies this distribution.  The full text of the license may be found at

      8 # http://opensource.org/licenses/bsd-license.php

      9 #

     10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

     11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

     12 #

     13 import Common.LongFilePathOs as os
     14 import re
     15 from CommonDataClass.DataClass import *
     16 import Common.DataType as DT
     17 from EccToolError import *
     18 from MetaDataParser import ParseHeaderCommentSection
     19 import EccGlobalData
     20 import c
     21 from Common.LongFilePathSupport import OpenLongFilePath as open
     22 from Common.MultipleWorkspace import MultipleWorkspace as mws
     23 
     24 ## Check

     25 #

     26 # This class is to define checkpoints used by ECC tool

     27 #

     28 # @param object:          Inherited from object class

     29 #

     30 class Check(object):
     31     def __init__(self):
     32         pass
     33 
     34     # Check all required checkpoints

     35     def Check(self):
     36         self.GeneralCheck()
     37         self.MetaDataFileCheck()
     38         self.DoxygenCheck()
     39         self.IncludeFileCheck()
     40         self.PredicateExpressionCheck()
     41         self.DeclAndDataTypeCheck()
     42         self.FunctionLayoutCheck()
     43         self.NamingConventionCheck()
     44 
     45     # Check UNI files

     46     def UniCheck(self):
     47         if EccGlobalData.gConfig.GeneralCheckUni == '1' or EccGlobalData.gConfig.GeneralCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
     48             EdkLogger.quiet("Checking whether UNI file is UTF-16 ...")
     49             SqlCommand = """select ID, FullPath, ExtName from File where ExtName like 'uni'"""
     50             RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
     51             for Record in RecordSet:
     52                 File = Record[1]
     53                 FileIn = open(File, 'rb').read(2)
     54                 if FileIn != '\xff\xfe':
     55                     OtherMsg = "File %s is not a valid UTF-16 UNI file" % Record[1]
     56                     EccGlobalData.gDb.TblReport.Insert(ERROR_GENERAL_CHECK_UNI, OtherMsg=OtherMsg, BelongsToTable='File', BelongsToItem=Record[0])
     57 
     58     # General Checking

     59     def GeneralCheck(self):
     60         self.GeneralCheckNonAcsii()
     61         self.UniCheck()
     62 
     63     # Check whether file has non ACSII char

     64     def GeneralCheckNonAcsii(self):
     65         if EccGlobalData.gConfig.GeneralCheckNonAcsii == '1' or EccGlobalData.gConfig.GeneralCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
     66             EdkLogger.quiet("Checking Non-ACSII char in file ...")
     67             SqlCommand = """select ID, FullPath, ExtName from File where ExtName in ('.dec', '.inf', '.dsc', 'c', 'h')"""
     68             RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
     69             for Record in RecordSet:
     70                 if Record[2].upper() not in EccGlobalData.gConfig.BinaryExtList:
     71                     op = open(Record[1]).readlines()
     72                     IndexOfLine = 0
     73                     for Line in op:
     74                         IndexOfLine += 1
     75                         IndexOfChar = 0
     76                         for Char in Line:
     77                             IndexOfChar += 1
     78                             if ord(Char) > 126:
     79                                 OtherMsg = "File %s has Non-ASCII char at line %s column %s" % (Record[1], IndexOfLine, IndexOfChar)
     80                                 EccGlobalData.gDb.TblReport.Insert(ERROR_GENERAL_CHECK_NON_ACSII, OtherMsg=OtherMsg, BelongsToTable='File', BelongsToItem=Record[0])
     81 
     82     # C Function Layout Checking

     83     def FunctionLayoutCheck(self):
     84         self.FunctionLayoutCheckReturnType()
     85         self.FunctionLayoutCheckModifier()
     86         self.FunctionLayoutCheckName()
     87         self.FunctionLayoutCheckPrototype()
     88         self.FunctionLayoutCheckBody()
     89         self.FunctionLayoutCheckLocalVariable()
     90 
     91     def WalkTree(self):
     92         IgnoredPattern = c.GetIgnoredDirListPattern()
     93         for Dirpath, Dirnames, Filenames in os.walk(EccGlobalData.gTarget):
     94             for Dir in Dirnames:
     95                 Dirname = os.path.join(Dirpath, Dir)
     96                 if os.path.islink(Dirname):
     97                     Dirname = os.path.realpath(Dirname)
     98                     if os.path.isdir(Dirname):
     99                         # symlinks to directories are treated as directories

    100                         Dirnames.remove(Dir)
    101                         Dirnames.append(Dirname)
    102             if IgnoredPattern.match(Dirpath.upper()):
    103                 continue
    104             for f in Filenames[:]:
    105                 if f.lower() in EccGlobalData.gConfig.SkipFileList:
    106                     Filenames.remove(f)
    107             yield (Dirpath, Dirnames, Filenames)
    108 
    109     # Check whether return type exists and in the first line

    110     def FunctionLayoutCheckReturnType(self):
    111         if EccGlobalData.gConfig.CFunctionLayoutCheckReturnType == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    112             EdkLogger.quiet("Checking function layout return type ...")
    113 
    114 #            for Dirpath, Dirnames, Filenames in self.WalkTree():

    115 #                for F in Filenames:

    116 #                    if os.path.splitext(F)[1] in ('.c', '.h'):

    117 #                        FullName = os.path.join(Dirpath, F)

    118 #                        c.CheckFuncLayoutReturnType(FullName)

    119             for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:
    120                 c.CheckFuncLayoutReturnType(FullName)
    121 
    122     # Check whether any optional functional modifiers exist and next to the return type

    123     def FunctionLayoutCheckModifier(self):
    124         if EccGlobalData.gConfig.CFunctionLayoutCheckOptionalFunctionalModifier == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    125             EdkLogger.quiet("Checking function layout modifier ...")
    126 
    127 #            for Dirpath, Dirnames, Filenames in self.WalkTree():

    128 #                for F in Filenames:

    129 #                    if os.path.splitext(F)[1] in ('.c', '.h'):

    130 #                        FullName = os.path.join(Dirpath, F)

    131 #                        c.CheckFuncLayoutModifier(FullName)

    132             for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:
    133                 c.CheckFuncLayoutModifier(FullName)
    134 
    135     # Check whether the next line contains the function name, left justified, followed by the beginning of the parameter list

    136     # Check whether the closing parenthesis is on its own line and also indented two spaces

    137     def FunctionLayoutCheckName(self):
    138         if EccGlobalData.gConfig.CFunctionLayoutCheckFunctionName == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    139             EdkLogger.quiet("Checking function layout function name ...")
    140 
    141 #            for Dirpath, Dirnames, Filenames in self.WalkTree():

    142 #                for F in Filenames:

    143 #                    if os.path.splitext(F)[1] in ('.c', '.h'):

    144 #                        FullName = os.path.join(Dirpath, F)

    145 #                        c.CheckFuncLayoutName(FullName)

    146             for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:
    147                 c.CheckFuncLayoutName(FullName)
    148 
    149     # Check whether the function prototypes in include files have the same form as function definitions

    150     def FunctionLayoutCheckPrototype(self):
    151         if EccGlobalData.gConfig.CFunctionLayoutCheckFunctionPrototype == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    152             EdkLogger.quiet("Checking function layout function prototype ...")
    153 
    154 #            for Dirpath, Dirnames, Filenames in self.WalkTree():

    155 #                for F in Filenames:

    156 #                    if os.path.splitext(F)[1] in ('.c'):

    157 #                        FullName = os.path.join(Dirpath, F)

    158 #                        EdkLogger.quiet("[PROTOTYPE]" + FullName)

    159 #                        c.CheckFuncLayoutPrototype(FullName)

    160             for FullName in EccGlobalData.gCFileList:
    161                 EdkLogger.quiet("[PROTOTYPE]" + FullName)
    162                 c.CheckFuncLayoutPrototype(FullName)
    163 
    164     # Check whether the body of a function is contained by open and close braces that must be in the first column

    165     def FunctionLayoutCheckBody(self):
    166         if EccGlobalData.gConfig.CFunctionLayoutCheckFunctionBody == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    167             EdkLogger.quiet("Checking function layout function body ...")
    168 
    169 #            for Dirpath, Dirnames, Filenames in self.WalkTree():

    170 #                for F in Filenames:

    171 #                    if os.path.splitext(F)[1] in ('.c'):

    172 #                        FullName = os.path.join(Dirpath, F)

    173 #                        c.CheckFuncLayoutBody(FullName)

    174             for FullName in EccGlobalData.gCFileList:
    175                 c.CheckFuncLayoutBody(FullName)
    176 
    177     # Check whether the data declarations is the first code in a module.

    178     # self.CFunctionLayoutCheckDataDeclaration = 1

    179     # Check whether no initialization of a variable as part of its declaration

    180     def FunctionLayoutCheckLocalVariable(self):
    181         if EccGlobalData.gConfig.CFunctionLayoutCheckNoInitOfVariable == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    182             EdkLogger.quiet("Checking function layout local variables ...")
    183 
    184 #            for Dirpath, Dirnames, Filenames in self.WalkTree():

    185 #                for F in Filenames:

    186 #                    if os.path.splitext(F)[1] in ('.c'):

    187 #                        FullName = os.path.join(Dirpath, F)

    188 #                        c.CheckFuncLayoutLocalVariable(FullName)

    189 
    190             for FullName in EccGlobalData.gCFileList:
    191                 c.CheckFuncLayoutLocalVariable(FullName)
    192 
    193     # Check whether no use of STATIC for functions

    194     # self.CFunctionLayoutCheckNoStatic = 1

    195 
    196     # Declarations and Data Types Checking

    197     def DeclAndDataTypeCheck(self):
    198         self.DeclCheckNoUseCType()
    199         self.DeclCheckInOutModifier()
    200         self.DeclCheckEFIAPIModifier()
    201         self.DeclCheckEnumeratedType()
    202         self.DeclCheckStructureDeclaration()
    203         self.DeclCheckSameStructure()
    204         self.DeclCheckUnionType()
    205 
    206 
    207     # Check whether no use of int, unsigned, char, void, static, long in any .c, .h or .asl files.

    208     def DeclCheckNoUseCType(self):
    209         if EccGlobalData.gConfig.DeclarationDataTypeCheckNoUseCType == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    210             EdkLogger.quiet("Checking Declaration No use C type ...")
    211 
    212 #            for Dirpath, Dirnames, Filenames in self.WalkTree():

    213 #                for F in Filenames:

    214 #                    if os.path.splitext(F)[1] in ('.h', '.c'):

    215 #                        FullName = os.path.join(Dirpath, F)

    216 #                        c.CheckDeclNoUseCType(FullName)

    217             for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:
    218                 c.CheckDeclNoUseCType(FullName)
    219 
    220     # 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

    221     def DeclCheckInOutModifier(self):
    222         if EccGlobalData.gConfig.DeclarationDataTypeCheckInOutModifier == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    223             EdkLogger.quiet("Checking Declaration argument modifier ...")
    224 
    225 #            for Dirpath, Dirnames, Filenames in self.WalkTree():

    226 #                for F in Filenames:

    227 #                    if os.path.splitext(F)[1] in ('.h', '.c'):

    228 #                        FullName = os.path.join(Dirpath, F)

    229 #                        c.CheckDeclArgModifier(FullName)

    230             for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:
    231                 c.CheckDeclArgModifier(FullName)
    232 
    233     # Check whether the EFIAPI modifier should be used at the entry of drivers, events, and member functions of protocols

    234     def DeclCheckEFIAPIModifier(self):
    235         if EccGlobalData.gConfig.DeclarationDataTypeCheckEFIAPIModifier == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    236             pass
    237 
    238     # Check whether Enumerated Type has a 'typedef' and the name is capital

    239     def DeclCheckEnumeratedType(self):
    240         if EccGlobalData.gConfig.DeclarationDataTypeCheckEnumeratedType == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    241             EdkLogger.quiet("Checking Declaration enum typedef ...")
    242 
    243 #            for Dirpath, Dirnames, Filenames in self.WalkTree():

    244 #                for F in Filenames:

    245 #                    if os.path.splitext(F)[1] in ('.h', '.c'):

    246 #                        FullName = os.path.join(Dirpath, F)

    247 #                        EdkLogger.quiet("[ENUM]" + FullName)

    248 #                        c.CheckDeclEnumTypedef(FullName)

    249             for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:
    250                 EdkLogger.quiet("[ENUM]" + FullName)
    251                 c.CheckDeclEnumTypedef(FullName)
    252 
    253     # Check whether Structure Type has a 'typedef' and the name is capital

    254     def DeclCheckStructureDeclaration(self):
    255         if EccGlobalData.gConfig.DeclarationDataTypeCheckStructureDeclaration == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    256             EdkLogger.quiet("Checking Declaration struct typedef ...")
    257 
    258 #            for Dirpath, Dirnames, Filenames in self.WalkTree():

    259 #                for F in Filenames:

    260 #                    if os.path.splitext(F)[1] in ('.h', '.c'):

    261 #                        FullName = os.path.join(Dirpath, F)

    262 #                        EdkLogger.quiet("[STRUCT]" + FullName)

    263 #                        c.CheckDeclStructTypedef(FullName)

    264             for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:
    265                 EdkLogger.quiet("[STRUCT]" + FullName)
    266                 c.CheckDeclStructTypedef(FullName)
    267 
    268     # Check whether having same Structure

    269     def DeclCheckSameStructure(self):
    270         if EccGlobalData.gConfig.DeclarationDataTypeCheckSameStructure == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    271             EdkLogger.quiet("Checking same struct ...")
    272             AllStructure = {}
    273             for IdentifierTable in EccGlobalData.gIdentifierTableList:
    274                 SqlCommand = """select ID, Name, BelongsToFile from %s where Model = %s""" % (IdentifierTable, MODEL_IDENTIFIER_STRUCTURE)
    275                 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
    276                 for Record in RecordSet:
    277                     if Record[1] != '':
    278                         if Record[1] not in AllStructure.keys():
    279                             AllStructure[Record[1]] = Record[2]
    280                         else:
    281                             ID = AllStructure[Record[1]]
    282                             SqlCommand = """select FullPath from File where ID = %s """ % ID
    283                             NewRecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
    284                             OtherMsg = "The structure name '%s' is duplicate" % Record[1]
    285                             if NewRecordSet != []:
    286                                 OtherMsg = "The structure name [%s] is duplicate with the one defined in %s, maybe struct NOT typedefed or the typedef new type NOT used to qualify variables" % (Record[1], NewRecordSet[0][0])
    287                             if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE, Record[1]):
    288                                 EccGlobalData.gDb.TblReport.Insert(ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE, OtherMsg=OtherMsg, BelongsToTable=IdentifierTable, BelongsToItem=Record[0])
    289 
    290     # Check whether Union Type has a 'typedef' and the name is capital

    291     def DeclCheckUnionType(self):
    292         if EccGlobalData.gConfig.DeclarationDataTypeCheckUnionType == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    293             EdkLogger.quiet("Checking Declaration union typedef ...")
    294 
    295 #            for Dirpath, Dirnames, Filenames in self.WalkTree():

    296 #                for F in Filenames:

    297 #                    if os.path.splitext(F)[1] in ('.h', '.c'):

    298 #                        FullName = os.path.join(Dirpath, F)

    299 #                        EdkLogger.quiet("[UNION]" + FullName)

    300 #                        c.CheckDeclUnionTypedef(FullName)

    301             for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:
    302                 EdkLogger.quiet("[UNION]" + FullName)
    303                 c.CheckDeclUnionTypedef(FullName)
    304 
    305     # Predicate Expression Checking

    306     def PredicateExpressionCheck(self):
    307         self.PredicateExpressionCheckBooleanValue()
    308         self.PredicateExpressionCheckNonBooleanOperator()
    309         self.PredicateExpressionCheckComparisonNullType()
    310 
    311     # Check whether Boolean values, variable type BOOLEAN not use explicit comparisons to TRUE or FALSE

    312     def PredicateExpressionCheckBooleanValue(self):
    313         if EccGlobalData.gConfig.PredicateExpressionCheckBooleanValue == '1' or EccGlobalData.gConfig.PredicateExpressionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    314             EdkLogger.quiet("Checking predicate expression Boolean value ...")
    315 
    316 #            for Dirpath, Dirnames, Filenames in self.WalkTree():

    317 #                for F in Filenames:

    318 #                    if os.path.splitext(F)[1] in ('.c'):

    319 #                        FullName = os.path.join(Dirpath, F)

    320 #                        EdkLogger.quiet("[BOOLEAN]" + FullName)

    321 #                        c.CheckBooleanValueComparison(FullName)

    322             for FullName in EccGlobalData.gCFileList:
    323                 EdkLogger.quiet("[BOOLEAN]" + FullName)
    324                 c.CheckBooleanValueComparison(FullName)
    325 
    326     # Check whether Non-Boolean comparisons use a compare operator (==, !=, >, < >=, <=).

    327     def PredicateExpressionCheckNonBooleanOperator(self):
    328         if EccGlobalData.gConfig.PredicateExpressionCheckNonBooleanOperator == '1' or EccGlobalData.gConfig.PredicateExpressionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    329             EdkLogger.quiet("Checking predicate expression Non-Boolean variable...")
    330 
    331 #            for Dirpath, Dirnames, Filenames in self.WalkTree():

    332 #                for F in Filenames:

    333 #                    if os.path.splitext(F)[1] in ('.c'):

    334 #                        FullName = os.path.join(Dirpath, F)

    335 #                        EdkLogger.quiet("[NON-BOOLEAN]" + FullName)

    336 #                        c.CheckNonBooleanValueComparison(FullName)

    337             for FullName in EccGlobalData.gCFileList:
    338                 EdkLogger.quiet("[NON-BOOLEAN]" + FullName)
    339                 c.CheckNonBooleanValueComparison(FullName)
    340 
    341     # Check whether a comparison of any pointer to zero must be done via the NULL type

    342     def PredicateExpressionCheckComparisonNullType(self):
    343         if EccGlobalData.gConfig.PredicateExpressionCheckComparisonNullType == '1' or EccGlobalData.gConfig.PredicateExpressionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    344             EdkLogger.quiet("Checking predicate expression NULL pointer ...")
    345 
    346 #            for Dirpath, Dirnames, Filenames in self.WalkTree():

    347 #                for F in Filenames:

    348 #                    if os.path.splitext(F)[1] in ('.c'):

    349 #                        FullName = os.path.join(Dirpath, F)

    350 #                        EdkLogger.quiet("[POINTER]" + FullName)

    351 #                        c.CheckPointerNullComparison(FullName)

    352             for FullName in EccGlobalData.gCFileList:
    353                 EdkLogger.quiet("[POINTER]" + FullName)
    354                 c.CheckPointerNullComparison(FullName)
    355 
    356     # Include file checking

    357     def IncludeFileCheck(self):
    358         self.IncludeFileCheckIfndef()
    359         self.IncludeFileCheckData()
    360         self.IncludeFileCheckSameName()
    361 
    362     # Check whether having include files with same name

    363     def IncludeFileCheckSameName(self):
    364         if EccGlobalData.gConfig.IncludeFileCheckSameName == '1' or EccGlobalData.gConfig.IncludeFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    365             EdkLogger.quiet("Checking same header file name ...")
    366             SqlCommand = """select ID, FullPath from File
    367                             where Model = 1002 order by Name """
    368             RecordDict = {}
    369             RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
    370             for Record in RecordSet:
    371                 List = Record[1].replace('/', '\\').split('\\')
    372                 if len(List) >= 2:
    373                     Key = List[-2] + '\\' + List[-1]
    374                 else:
    375                     Key = List[0]
    376                 if Key not in RecordDict:
    377                     RecordDict[Key] = [Record]
    378                 else:
    379                     RecordDict[Key].append(Record)
    380 
    381             for Key in RecordDict:
    382                 if len(RecordDict[Key]) > 1:
    383                     for Item in RecordDict[Key]:
    384                         Path = mws.relpath(Item[1], EccGlobalData.gWorkspace)
    385                         if not EccGlobalData.gException.IsException(ERROR_INCLUDE_FILE_CHECK_NAME, Path):
    386                             EccGlobalData.gDb.TblReport.Insert(ERROR_INCLUDE_FILE_CHECK_NAME, OtherMsg="The file name for [%s] is duplicate" % Path, BelongsToTable='File', BelongsToItem=Item[0])
    387 
    388     # Check whether all include file contents is guarded by a #ifndef statement.
    389     def IncludeFileCheckIfndef(self):
    390         if EccGlobalData.gConfig.IncludeFileCheckIfndefStatement == '1' or EccGlobalData.gConfig.IncludeFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    391             EdkLogger.quiet("Checking header file ifndef ...")
    392 
    393 #            for Dirpath, Dirnames, Filenames in self.WalkTree():
    394 #                for F in Filenames:
    395 #                    if os.path.splitext(F)[1] in ('.h'):
    396 #                        FullName = os.path.join(Dirpath, F)
    397 #                        MsgList = c.CheckHeaderFileIfndef(FullName)
    398             for FullName in EccGlobalData.gHFileList:
    399                 MsgList = c.CheckHeaderFileIfndef(FullName)
    400 
    401     # Check whether include files NOT contain code or define data variables
    402     def IncludeFileCheckData(self):
    403         if EccGlobalData.gConfig.IncludeFileCheckData == '1' or EccGlobalData.gConfig.IncludeFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    404             EdkLogger.quiet("Checking header file data ...")
    405 
    406 #            for Dirpath, Dirnames, Filenames in self.WalkTree():
    407 #                for F in Filenames:
    408 #                    if os.path.splitext(F)[1] in ('.h'):
    409 #                        FullName = os.path.join(Dirpath, F)
    410 #                        MsgList = c.CheckHeaderFileData(FullName)
    411             for FullName in EccGlobalData.gHFileList:
    412                 MsgList = c.CheckHeaderFileData(FullName)
    413 
    414     # Doxygen document checking
    415     def DoxygenCheck(self):
    416         self.DoxygenCheckFileHeader()
    417         self.DoxygenCheckFunctionHeader()
    418         self.DoxygenCheckCommentDescription()
    419         self.DoxygenCheckCommentFormat()
    420         self.DoxygenCheckCommand()
    421 
    422     # Check whether the file headers are followed Doxygen special documentation blocks in section 2.3.5
    423     def DoxygenCheckFileHeader(self):
    424         if EccGlobalData.gConfig.DoxygenCheckFileHeader == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    425             EdkLogger.quiet("Checking Doxygen file header ...")
    426 
    427             for Dirpath, Dirnames, Filenames in self.WalkTree():
    428                 for F in Filenames:
    429                     Ext = os.path.splitext(F)[1]
    430                     if Ext in ('.h', '.c'):
    431                         FullName = os.path.join(Dirpath, F)
    432                         MsgList = c.CheckFileHeaderDoxygenComments(FullName)
    433                     elif Ext in ('.inf', '.dec', '.dsc', '.fdf'):
    434                         FullName = os.path.join(Dirpath, F)
    435                         op = open(FullName).readlines()
    436                         FileLinesList = op
    437                         LineNo             = 0
    438                         CurrentSection     = MODEL_UNKNOWN 
    439                         HeaderSectionLines       = []
    440                         HeaderCommentStart = False 
    441                         HeaderCommentEnd   = False
    442                         
    443                         for Line in FileLinesList:
    444                             LineNo   = LineNo + 1
    445                             Line     = Line.strip()
    446                             if (LineNo < len(FileLinesList) - 1):
    447                                 NextLine = FileLinesList[LineNo].strip()
    448             
    449                             #
    450                             # blank line
    451                             #
    452                             if (Line == '' or not Line) and LineNo == len(FileLinesList):
    453                                 LastSectionFalg = True
    454 
    455                             #
    456                             # check whether file header comment section started
    457                             #
    458                             if Line.startswith('#') and \

    459                                 (Line.find('@file') > -1) and \
    460                                 not HeaderCommentStart:
    461                                 if CurrentSection != MODEL_UNKNOWN:
    462                                     SqlStatement = """ select ID from File where FullPath like '%s'""" % FullName
    463                                     ResultSet = EccGlobalData.gDb.TblFile.Exec(SqlStatement)
    464                                     for Result in ResultSet:
    465                                         Msg = 'INF/DEC/DSC/FDF file header comment should begin with ""## @file"" or ""# @file""at the very top file'
    466                                         EccGlobalData.gDb.TblReport.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER, Msg, "File", Result[0])
    467 
    468                                 else:
    469                                     CurrentSection = MODEL_IDENTIFIER_FILE_HEADER
    470                                     #

    471                                     # Append the first line to section lines.

    472                                     #

    473                                     HeaderSectionLines.append((Line, LineNo))
    474                                     HeaderCommentStart = True
    475                                     continue        
    476             
    477                             #

    478                             # Collect Header content.

    479                             #

    480                             if (Line.startswith('#') and CurrentSection == MODEL_IDENTIFIER_FILE_HEADER) and\
    481                                 HeaderCommentStart and not Line.startswith('##') and not\
    482                                 HeaderCommentEnd and NextLine != '':
    483                                 HeaderSectionLines.append((Line, LineNo))
    484                                 continue
    485                             #

    486                             # Header content end

    487                             #

    488                             if (Line.startswith('##') or not Line.strip().startswith("#")) and HeaderCommentStart \
    489                                 and not HeaderCommentEnd:
    490                                 if Line.startswith('##'):
    491                                     HeaderCommentEnd = True
    492                                 HeaderSectionLines.append((Line, LineNo))
    493                                 ParseHeaderCommentSection(HeaderSectionLines, FullName)
    494                                 break
    495                         if HeaderCommentStart == False:
    496                             SqlStatement = """ select ID from File where FullPath like '%s'""" % FullName
    497                             ResultSet = EccGlobalData.gDb.TblFile.Exec(SqlStatement)
    498                             for Result in ResultSet:
    499                                 Msg = 'INF/DEC/DSC/FDF file header comment should begin with ""## @file"" or ""# @file"" at the very top file'
    500                                 EccGlobalData.gDb.TblReport.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER, Msg, "File", Result[0])
    501                         if HeaderCommentEnd == False:
    502                             SqlStatement = """ select ID from File where FullPath like '%s'""" % FullName
    503                             ResultSet = EccGlobalData.gDb.TblFile.Exec(SqlStatement)
    504                             for Result in ResultSet:
    505                                 Msg = 'INF/DEC/DSC/FDF file header comment should end with ""##"" at the end of file header comment block'
    506                                 # Check whether File header Comment End with '##'

    507                                 if EccGlobalData.gConfig.HeaderCheckFileCommentEnd == '1' or EccGlobalData.gConfig.HeaderCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    508                                     EccGlobalData.gDb.TblReport.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER, Msg, "File", Result[0])
    509 
    510                                      
    511 
    512     # Check whether the function headers are followed Doxygen special documentation blocks in section 2.3.5

    513     def DoxygenCheckFunctionHeader(self):
    514         if EccGlobalData.gConfig.DoxygenCheckFunctionHeader == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    515             EdkLogger.quiet("Checking Doxygen function header ...")
    516 
    517 #            for Dirpath, Dirnames, Filenames in self.WalkTree():

    518 #                for F in Filenames:

    519 #                    if os.path.splitext(F)[1] in ('.h', '.c'):

    520 #                        FullName = os.path.join(Dirpath, F)

    521 #                        MsgList = c.CheckFuncHeaderDoxygenComments(FullName)

    522             for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:
    523                 MsgList = c.CheckFuncHeaderDoxygenComments(FullName)
    524 
    525 
    526     # Check whether the first line of text in a comment block is a brief description of the element being documented.

    527     # The brief description must end with a period.

    528     def DoxygenCheckCommentDescription(self):
    529         if EccGlobalData.gConfig.DoxygenCheckCommentDescription == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    530             pass
    531 
    532     # Check whether comment lines with '///< ... text ...' format, if it is used, it should be after the code section.

    533     def DoxygenCheckCommentFormat(self):
    534         if EccGlobalData.gConfig.DoxygenCheckCommentFormat == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    535             EdkLogger.quiet("Checking Doxygen comment ///< ...")
    536 
    537 #            for Dirpath, Dirnames, Filenames in self.WalkTree():

    538 #                for F in Filenames:

    539 #                    if os.path.splitext(F)[1] in ('.h', '.c'):

    540 #                        FullName = os.path.join(Dirpath, F)

    541 #                        MsgList = c.CheckDoxygenTripleForwardSlash(FullName)

    542             for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:
    543                 MsgList = c.CheckDoxygenTripleForwardSlash(FullName)
    544 
    545     # Check whether only Doxygen commands allowed to mark the code are @bug and @todo.

    546     def DoxygenCheckCommand(self):
    547         if EccGlobalData.gConfig.DoxygenCheckCommand == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    548             EdkLogger.quiet("Checking Doxygen command ...")
    549 
    550 #            for Dirpath, Dirnames, Filenames in self.WalkTree():

    551 #                for F in Filenames:

    552 #                    if os.path.splitext(F)[1] in ('.h', '.c'):

    553 #                        FullName = os.path.join(Dirpath, F)

    554 #                        MsgList = c.CheckDoxygenCommand(FullName)

    555             for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:
    556                 MsgList = c.CheckDoxygenCommand(FullName)
    557 
    558     # Meta-Data File Processing Checking

    559     def MetaDataFileCheck(self):
    560         self.MetaDataFileCheckPathName()
    561         self.MetaDataFileCheckGenerateFileList()
    562         self.MetaDataFileCheckLibraryInstance()
    563         self.MetaDataFileCheckLibraryInstanceDependent()
    564         self.MetaDataFileCheckLibraryInstanceOrder()
    565         self.MetaDataFileCheckLibraryNoUse()
    566         self.MetaDataFileCheckLibraryDefinedInDec()
    567         self.MetaDataFileCheckBinaryInfInFdf()
    568         self.MetaDataFileCheckPcdDuplicate()
    569         self.MetaDataFileCheckPcdFlash()
    570         self.MetaDataFileCheckPcdNoUse()
    571         self.MetaDataFileCheckGuidDuplicate()
    572         self.MetaDataFileCheckModuleFileNoUse()
    573         self.MetaDataFileCheckPcdType()
    574         self.MetaDataFileCheckModuleFileGuidDuplication()
    575         self.MetaDataFileCheckModuleFileGuidFormat()
    576         self.MetaDataFileCheckModuleFileProtocolFormat()
    577         self.MetaDataFileCheckModuleFilePpiFormat()
    578         self.MetaDataFileCheckModuleFilePcdFormat()
    579 
    580     # Check whether each file defined in meta-data exists

    581     def MetaDataFileCheckPathName(self):
    582         if EccGlobalData.gConfig.MetaDataFileCheckPathName == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    583             # This item is covered when parsing Inf/Dec/Dsc files

    584             pass
    585 
    586     # Generate a list for all files defined in meta-data files

    587     def MetaDataFileCheckGenerateFileList(self):
    588         if EccGlobalData.gConfig.MetaDataFileCheckGenerateFileList == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    589             # This item is covered when parsing Inf/Dec/Dsc files

    590             pass
    591 
    592     # Check whether all Library Instances defined for a given module (or dependent library instance) match the module's type.

    593     # Each Library Instance must specify the Supported Module Types in its Inf file,

    594     # and any module specifying the library instance must be one of the supported types.

    595     def MetaDataFileCheckLibraryInstance(self):
    596         if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstance == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    597             EdkLogger.quiet("Checking for library instance type issue ...")
    598             SqlCommand = """select A.ID, A.Value3, B.Value3 from Inf as A left join Inf as B
    599                             where A.Value2 = 'LIBRARY_CLASS' and A.Model = %s
    600                             and B.Value2 = 'MODULE_TYPE' and B.Model = %s and A.BelongsToFile = B.BelongsToFile
    601                             group by A.BelongsToFile""" % (MODEL_META_DATA_HEADER, MODEL_META_DATA_HEADER)
    602             RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
    603             LibraryClasses = {}
    604             for Record in RecordSet:
    605                 List = Record[1].split('|', 1)
    606                 SupModType = []
    607                 if len(List) == 1:
    608                     SupModType = DT.SUP_MODULE_LIST_STRING.split(DT.TAB_VALUE_SPLIT)
    609                 elif len(List) == 2:
    610                     SupModType = List[1].split()
    611 
    612                 if List[0] not in LibraryClasses:
    613                     LibraryClasses[List[0]] = SupModType
    614                 else:
    615                     for Item in SupModType:
    616                         if Item not in LibraryClasses[List[0]]:
    617                             LibraryClasses[List[0]].append(Item)
    618 
    619                 if Record[2] != 'BASE' and Record[2] not in SupModType:
    620                     EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_2, OtherMsg="The Library Class '%s' does not specify its supported module types" % (List[0]), BelongsToTable='Inf', BelongsToItem=Record[0])
    621 
    622             SqlCommand = """select A.ID, A.Value1, B.Value3 from Inf as A left join Inf as B
    623                             where A.Model = %s and B.Value2 = '%s' and B.Model = %s
    624                             and B.BelongsToFile = A.BelongsToFile""" \
    625                             % (MODEL_EFI_LIBRARY_CLASS, 'MODULE_TYPE', MODEL_META_DATA_HEADER)
    626             RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
    627             # Merge all LibraryClasses' supmodlist

    628             RecordDict = {}
    629             for Record in RecordSet:
    630                 if Record[1] not in RecordDict:
    631                     RecordDict[Record[1]] = [str(Record[2])]
    632                 else:
    633                     if Record[2] not in RecordDict[Record[1]]:
    634                         RecordDict[Record[1]].append(Record[2])
    635 
    636             for Record in RecordSet:
    637                 if Record[1] in LibraryClasses:
    638                     if Record[2] not in LibraryClasses[Record[1]] and 'BASE' not in RecordDict[Record[1]]:
    639                         if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1, Record[1]):
    640                             EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1, OtherMsg="The type of Library Class [%s] defined in Inf file does not match the type of the module" % (Record[1]), BelongsToTable='Inf', BelongsToItem=Record[0])
    641                 else:
    642                     if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1, Record[1]):
    643                         EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1, OtherMsg="The type of Library Class [%s] defined in Inf file does not match the type of the module" % (Record[1]), BelongsToTable='Inf', BelongsToItem=Record[0])
    644 
    645     # Check whether a Library Instance has been defined for all dependent library classes

    646     def MetaDataFileCheckLibraryInstanceDependent(self):
    647         if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstanceDependent == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    648             EdkLogger.quiet("Checking for library instance dependent issue ...")
    649             SqlCommand = """select ID, Value1, Value2 from Dsc where Model = %s""" % MODEL_EFI_LIBRARY_CLASS
    650             LibraryClasses = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)
    651             for LibraryClass in LibraryClasses:
    652                 if LibraryClass[1].upper() == 'NULL' or LibraryClass[1].startswith('!ifdef') or LibraryClass[1].startswith('!ifndef') or LibraryClass[1].endswith('!endif'):
    653                     continue
    654                 else:
    655                     LibraryIns = os.path.normpath(mws.join(EccGlobalData.gWorkspace, LibraryClass[2]))
    656                     SkipDirString = '|'.join(EccGlobalData.gConfig.SkipDirList)
    657                     p = re.compile(r'.*[\\/](?:%s^\S)[\\/]?.*' % SkipDirString)
    658                     if p.match(os.path.split(LibraryIns)[0].upper()):
    659                         continue
    660                     SqlCommand = """select Value3 from Inf where BelongsToFile =
    661                                     (select ID from File where lower(FullPath) = lower('%s'))
    662                                     and Value2 = '%s'""" % (LibraryIns, 'LIBRARY_CLASS')
    663                     RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
    664                     IsFound = False
    665                     for Record in RecordSet:
    666                         LibName = Record[0].split('|', 1)[0]
    667                         if LibraryClass[1] == LibName:
    668                             IsFound = True
    669                     if not IsFound:
    670                         if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_DEPENDENT, LibraryClass[1]):
    671                             EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_DEPENDENT, OtherMsg="The Library Class [%s] is not specified in '%s'" % (LibraryClass[1], LibraryClass[2]), BelongsToTable='Dsc', BelongsToItem=LibraryClass[0])
    672 
    673     # Check whether the Library Instances specified by the LibraryClasses sections are listed in order of dependencies

    674     def MetaDataFileCheckLibraryInstanceOrder(self):
    675         if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstanceOrder == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    676             # This checkpoint is not necessary for Ecc check

    677             pass
    678 
    679     # Check whether the unnecessary inclusion of library classes in the Inf file

    680     # Check whether the unnecessary duplication of library classe names in the DSC file

    681     def MetaDataFileCheckLibraryNoUse(self):
    682         if EccGlobalData.gConfig.MetaDataFileCheckLibraryNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    683             EdkLogger.quiet("Checking for library instance not used ...")
    684             SqlCommand = """select ID, Value1 from Inf as A where A.Model = %s and A.Value1 not in (select B.Value1 from Dsc as B where Model = %s)""" % (MODEL_EFI_LIBRARY_CLASS, MODEL_EFI_LIBRARY_CLASS)
    685             RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
    686             for Record in RecordSet:
    687                 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_NO_USE, Record[1]):
    688                     EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_NO_USE, OtherMsg="The Library Class [%s] is not used in any platform" % (Record[1]), BelongsToTable='Inf', BelongsToItem=Record[0])
    689             SqlCommand = """
    690                          select A.ID, A.Value1, A.BelongsToFile, A.StartLine, B.StartLine from Dsc as A left join Dsc as B
    691                          where A.Model = %s and B.Model = %s and A.Scope1 = B.Scope1 and A.Scope2 = B.Scope2 and A.ID <> B.ID
    692                          and A.Value1 = B.Value1 and A.Value2 <> B.Value2 and A.BelongsToItem = -1 and B.BelongsToItem = -1 and A.StartLine <> B.StartLine and B.BelongsToFile = A.BelongsToFile""" \
    693                             % (MODEL_EFI_LIBRARY_CLASS, MODEL_EFI_LIBRARY_CLASS)
    694             RecordSet = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)
    695             for Record in RecordSet:
    696                 if Record[3] and Record[4] and Record[3] != Record[4] and Record[1] != 'NULL':
    697                     SqlCommand = """select FullPath from File where ID = %s""" % (Record[2])
    698                     FilePathList = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
    699                     for FilePath in FilePathList:
    700                         if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_NAME_DUPLICATE, Record[1]):
    701                             EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_NAME_DUPLICATE, OtherMsg="The Library Class [%s] is duplicated in '%s' line %s and line %s." % (Record[1], FilePath, Record[3], Record[4]), BelongsToTable='Dsc', BelongsToItem=Record[0])
    702     
    703     # Check the header file in Include\Library directory whether be defined in the package DEC file.

    704     def MetaDataFileCheckLibraryDefinedInDec(self):
    705         if EccGlobalData.gConfig.MetaDataFileCheckLibraryDefinedInDec == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    706             EdkLogger.quiet("Checking for library instance whether be defined in the package dec file ...")
    707             SqlCommand = """
    708                     select A.Value1, A.StartLine, A.ID, B.Value1 from Inf as A left join Dec as B
    709                     on A.Model = B.Model and A.Value1 = B.Value1 where A.Model=%s
    710                     """ % MODEL_EFI_LIBRARY_CLASS
    711             RecordSet = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)
    712             for Record in RecordSet:
    713                 LibraryInInf, Line, ID, LibraryDec = Record
    714                 if not LibraryDec:
    715                     if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_NOT_DEFINED, LibraryInInf):
    716                         EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_NOT_DEFINED, \
    717                                             OtherMsg="The Library Class [%s] in %s line is not defined in the associated package file." % (LibraryInInf, Line), 
    718                                             BelongsToTable='Inf', BelongsToItem=ID)
    719     
    720     # Check whether an Inf file is specified in the FDF file, but not in the Dsc file, then the Inf file must be for a Binary module only

    721     def MetaDataFileCheckBinaryInfInFdf(self):
    722         if EccGlobalData.gConfig.MetaDataFileCheckBinaryInfInFdf == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    723             EdkLogger.quiet("Checking for non-binary modules defined in FDF files ...")
    724             SqlCommand = """select A.ID, A.Value1 from Fdf as A
    725                          where A.Model = %s
    726                          and A.Enabled > -1
    727                          and A.Value1 not in
    728                          (select B.Value1 from Dsc as B
    729                          where B.Model = %s
    730                          and B.Enabled > -1)""" % (MODEL_META_DATA_COMPONENT, MODEL_META_DATA_COMPONENT)
    731             RecordSet = EccGlobalData.gDb.TblFdf.Exec(SqlCommand)
    732             for Record in RecordSet:
    733                 FdfID = Record[0]
    734                 FilePath = Record[1]
    735                 FilePath = os.path.normpath(mws.join(EccGlobalData.gWorkspace, FilePath))
    736                 SqlCommand = """select ID from Inf where Model = %s and BelongsToFile = (select ID from File where FullPath like '%s')
    737                                 """ % (MODEL_EFI_SOURCE_FILE, FilePath)
    738                 NewRecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
    739                 if NewRecordSet != []:
    740                     if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_BINARY_INF_IN_FDF, FilePath):
    741                         EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_BINARY_INF_IN_FDF, OtherMsg="File [%s] defined in FDF file and not in DSC file must be a binary module" % (FilePath), BelongsToTable='Fdf', BelongsToItem=FdfID)
    742 
    743     # Check whether a PCD is set in a Dsc file or the FDF file, but not in both.

    744     def MetaDataFileCheckPcdDuplicate(self):
    745         if EccGlobalData.gConfig.MetaDataFileCheckPcdDuplicate == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    746             EdkLogger.quiet("Checking for duplicate PCDs defined in both DSC and FDF files ...")
    747             SqlCommand = """
    748                          select A.ID, A.Value1, A.Value2, A.BelongsToFile, B.ID, B.Value1, B.Value2, B.BelongsToFile from Dsc as A, Fdf as B
    749                          where A.Model >= %s and A.Model < %s
    750                          and B.Model >= %s and B.Model < %s
    751                          and A.Value1 = B.Value1
    752                          and A.Value2 = B.Value2
    753                          and A.Enabled > -1
    754                          and B.Enabled > -1
    755                          group by A.ID
    756                          """ % (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER)
    757             RecordSet = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)
    758             for Record in RecordSet:
    759                 SqlCommand1 = """select Name from File where ID = %s""" % Record[3]
    760                 SqlCommand2 = """select Name from File where ID = %s""" % Record[7]
    761                 DscFileName = os.path.splitext(EccGlobalData.gDb.TblDsc.Exec(SqlCommand1)[0][0])[0]
    762                 FdfFileName = os.path.splitext(EccGlobalData.gDb.TblDsc.Exec(SqlCommand2)[0][0])[0]
    763                 if DscFileName != FdfFileName:
    764                     continue
    765                 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, Record[1] + '.' + Record[2]):
    766                     EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, OtherMsg="The PCD [%s] is defined in both FDF file and DSC file" % (Record[1] + '.' + Record[2]), BelongsToTable='Dsc', BelongsToItem=Record[0])
    767                 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, Record[5] + '.' + Record[6]):
    768                     EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, OtherMsg="The PCD [%s] is defined in both FDF file and DSC file" % (Record[5] + '.' + Record[6]), BelongsToTable='Fdf', BelongsToItem=Record[4])
    769 
    770             EdkLogger.quiet("Checking for duplicate PCDs defined in DEC files ...")
    771             SqlCommand = """
    772                          select A.ID, A.Value1, A.Value2, A.Model, B.Model from Dec as A left join Dec as B
    773                          where A.Model >= %s and A.Model < %s
    774                          and B.Model >= %s and B.Model < %s
    775                          and A.Value1 = B.Value1
    776                          and A.Value2 = B.Value2
    777                          and A.Scope1 = B.Scope1
    778                          and A.ID <> B.ID
    779                          and A.Model = B.Model
    780                          and A.Enabled > -1
    781                          and B.Enabled > -1
    782                          and A.BelongsToFile = B.BelongsToFile
    783                          group by A.ID
    784                          """ % (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER)
    785             RecordSet = EccGlobalData.gDb.TblDec.Exec(SqlCommand)
    786             for Record in RecordSet:
    787                 RecordCat = Record[1] + '.' + Record[2]
    788                 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, RecordCat):
    789                     EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, OtherMsg="The PCD [%s] is defined duplicated in DEC file" % RecordCat, BelongsToTable='Dec', BelongsToItem=Record[0])
    790 
    791     # Check whether PCD settings in the FDF file can only be related to flash.

    792     def MetaDataFileCheckPcdFlash(self):
    793         if EccGlobalData.gConfig.MetaDataFileCheckPcdFlash == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    794             EdkLogger.quiet("Checking only Flash related PCDs are used in FDF ...")
    795             SqlCommand = """
    796                          select ID, Value1, Value2, BelongsToFile from Fdf as A
    797                          where A.Model >= %s and Model < %s
    798                          and A.Enabled > -1
    799                          and A.Value2 not like '%%Flash%%'
    800                          """ % (MODEL_PCD, MODEL_META_DATA_HEADER)
    801             RecordSet = EccGlobalData.gDb.TblFdf.Exec(SqlCommand)
    802             for Record in RecordSet:
    803                 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_FLASH, Record[1] + '.' + Record[2]):
    804                     EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_FLASH, OtherMsg="The PCD [%s] defined in FDF file is not related to Flash" % (Record[1] + '.' + Record[2]), BelongsToTable='Fdf', BelongsToItem=Record[0])
    805 
    806     # Check whether PCDs used in Inf files but not specified in Dsc or FDF files

    807     def MetaDataFileCheckPcdNoUse(self):
    808         if EccGlobalData.gConfig.MetaDataFileCheckPcdNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    809             EdkLogger.quiet("Checking for non-specified PCDs ...")
    810             SqlCommand = """
    811                          select ID, Value1, Value2, BelongsToFile from Inf as A
    812                          where A.Model >= %s and Model < %s
    813                          and A.Enabled > -1
    814                          and (A.Value1, A.Value2) not in
    815                              (select Value1, Value2 from Dsc as B
    816                               where B.Model >= %s and B.Model < %s
    817                               and B.Enabled > -1)
    818                          and (A.Value1, A.Value2) not in
    819                              (select Value1, Value2 from Fdf as C
    820                               where C.Model >= %s and C.Model < %s
    821                               and C.Enabled > -1)
    822                          """ % (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER)
    823             RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
    824             for Record in RecordSet:
    825                 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_NO_USE, Record[1] + '.' + Record[2]):
    826                     EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_NO_USE, OtherMsg="The PCD [%s] defined in INF file is not specified in either DSC or FDF files" % (Record[1] + '.' + Record[2]), BelongsToTable='Inf', BelongsToItem=Record[0])
    827 
    828     # Check whether having duplicate guids defined for Guid/Protocol/Ppi

    829     def MetaDataFileCheckGuidDuplicate(self):
    830         if EccGlobalData.gConfig.MetaDataFileCheckGuidDuplicate == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    831             EdkLogger.quiet("Checking for duplicate GUID/PPI/PROTOCOL ...")
    832             # Check Guid

    833             self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID, EccGlobalData.gDb.TblDec)
    834             self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID, EccGlobalData.gDb.TblDsc)
    835             self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID)
    836             # Check protocol

    837             self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL, EccGlobalData.gDb.TblDec)
    838             self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL, EccGlobalData.gDb.TblDsc)
    839             self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL)
    840             # Check ppi

    841             self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI, EccGlobalData.gDb.TblDec)
    842             self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI, EccGlobalData.gDb.TblDsc)
    843             self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI)
    844 
    845     # Check whether all files under module directory are described in INF files

    846     def MetaDataFileCheckModuleFileNoUse(self):
    847         if EccGlobalData.gConfig.MetaDataFileCheckModuleFileNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    848             EdkLogger.quiet("Checking for no used module files ...")
    849             SqlCommand = """
    850                          select upper(Path) from File where ID in (select BelongsToFile from Inf where BelongsToFile != -1)
    851                          """
    852             InfPathSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
    853             InfPathList = []
    854             for Item in InfPathSet:
    855                 if Item[0] not in InfPathList:
    856                     InfPathList.append(Item[0])
    857             SqlCommand = """
    858                          select ID, Path, FullPath from File where upper(FullPath) not in
    859                             (select upper(A.Path) || '\\' || upper(B.Value1) from File as A, INF as B
    860                             where A.ID in (select BelongsToFile from INF where Model = %s group by BelongsToFile) and
    861                             B.BelongsToFile = A.ID and B.Model = %s)
    862                             and (Model = %s or Model = %s)
    863                         """ % (MODEL_EFI_SOURCE_FILE, MODEL_EFI_SOURCE_FILE, MODEL_FILE_C, MODEL_FILE_H)
    864             RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
    865             for Record in RecordSet:
    866                 Path = Record[1]
    867                 Path = Path.upper().replace('\X64', '').replace('\IA32', '').replace('\EBC', '').replace('\IPF', '').replace('\ARM', '')
    868                 if Path in InfPathList:
    869                     if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_NO_USE, Record[2]):
    870                         EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_NO_USE, OtherMsg="The source file [%s] is existing in module directory but it is not described in INF file." % (Record[2]), BelongsToTable='File', BelongsToItem=Record[0])
    871 
    872     # Check whether the PCD is correctly used in C function via its type

    873     def MetaDataFileCheckPcdType(self):
    874         if EccGlobalData.gConfig.MetaDataFileCheckPcdType == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    875             EdkLogger.quiet("Checking for pcd type in c code function usage ...")
    876             SqlCommand = """
    877                          select ID, Model, Value1, Value2, BelongsToFile from INF where Model > %s and Model < %s
    878                          """ % (MODEL_PCD, MODEL_META_DATA_HEADER)
    879             PcdSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
    880             for Pcd in PcdSet:
    881                 Model = Pcd[1]
    882                 PcdName = Pcd[2]
    883                 if Pcd[3]:
    884                     PcdName = Pcd[3]
    885                 BelongsToFile = Pcd[4]
    886                 SqlCommand = """
    887                              select ID from File where FullPath in
    888                             (select B.Path || '\\' || A.Value1 from INF as A, File as B where A.Model = %s and A.BelongsToFile = %s
    889                              and B.ID = %s and (B.Model = %s or B.Model = %s))
    890                              """ % (MODEL_EFI_SOURCE_FILE, BelongsToFile, BelongsToFile, MODEL_FILE_C, MODEL_FILE_H)
    891                 TableSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
    892                 for Tbl in TableSet:
    893                     TblName = 'Identifier' + str(Tbl[0])
    894                     SqlCommand = """
    895                                  select Name, ID from %s where value like '%s' and Model = %s
    896                                  """ % (TblName, PcdName, MODEL_IDENTIFIER_FUNCTION_CALLING)
    897                     RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
    898                     TblNumber = TblName.replace('Identifier', '')
    899                     for Record in RecordSet:
    900                         FunName = Record[0]
    901                         if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_TYPE, FunName):
    902                             if Model in [MODEL_PCD_FIXED_AT_BUILD] and not FunName.startswith('FixedPcdGet'):
    903                                 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_TYPE, OtherMsg="The pcd '%s' is defined as a FixPcd but now it is called by c function [%s]" % (PcdName, FunName), BelongsToTable=TblName, BelongsToItem=Record[1])
    904                             if Model in [MODEL_PCD_FEATURE_FLAG] and (not FunName.startswith('FeaturePcdGet') and not FunName.startswith('FeaturePcdSet')):
    905                                 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_TYPE, OtherMsg="The pcd '%s' is defined as a FeaturePcd but now it is called by c function [%s]" % (PcdName, FunName), BelongsToTable=TblName, BelongsToItem=Record[1])
    906                             if Model in [MODEL_PCD_PATCHABLE_IN_MODULE] and (not FunName.startswith('PatchablePcdGet') and not FunName.startswith('PatchablePcdSet')):
    907                                 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_TYPE, OtherMsg="The pcd '%s' is defined as a PatchablePcd but now it is called by c function [%s]" % (PcdName, FunName), BelongsToTable=TblName, BelongsToItem=Record[1])
    908 
    909             #ERROR_META_DATA_FILE_CHECK_PCD_TYPE

    910         pass
    911 
    912     # Internal worker function to get the INF workspace relative path from FileID

    913     def GetInfFilePathFromID(self, FileID):
    914         Table = EccGlobalData.gDb.TblFile
    915         SqlCommand = """select A.FullPath from %s as A where A.ID = %s""" % (Table.Table, FileID)
    916         RecordSet = Table.Exec(SqlCommand)
    917         Path = ""
    918         for Record in RecordSet:
    919             Path = mws.relpath(Record[0], EccGlobalData.gWorkspace)
    920         return Path
    921 
    922     # Check whether two module INFs under one workspace has the same FILE_GUID value

    923     def MetaDataFileCheckModuleFileGuidDuplication(self):
    924         if EccGlobalData.gConfig.MetaDataFileCheckModuleFileGuidDuplication == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    925             EdkLogger.quiet("Checking for pcd type in c code function usage ...")
    926             Table = EccGlobalData.gDb.TblInf
    927             SqlCommand = """
    928                          select A.ID, A.Value3, A.BelongsToFile, B.BelongsToFile from %s as A, %s as B
    929                          where A.Value2 = 'FILE_GUID' and B.Value2 = 'FILE_GUID' and
    930                          A.Value3 = B.Value3 and A.ID <> B.ID group by A.ID
    931                          """ % (Table.Table, Table.Table)
    932             RecordSet = Table.Exec(SqlCommand)
    933             for Record in RecordSet:
    934                 InfPath1 = self.GetInfFilePathFromID(Record[2])
    935                 InfPath2 = self.GetInfFilePathFromID(Record[3])
    936                 if InfPath1 and InfPath2:
    937                     if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_GUID_DUPLICATION, InfPath1):
    938                         Msg = "The FILE_GUID of INF file [%s] is duplicated with that of %s" % (InfPath1, InfPath2)
    939                         EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_GUID_DUPLICATION, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])
    940 
    941 
    942     # Check Guid Format in module INF

    943     def MetaDataFileCheckModuleFileGuidFormat(self):
    944         if EccGlobalData.gConfig.MetaDataFileCheckModuleFileGuidFormat or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    945             EdkLogger.quiet("Check Guid Format in module INF ...")
    946             Table = EccGlobalData.gDb.TblInf
    947             SqlCommand = """
    948                          select ID, Value1, Usage, BelongsToFile from %s where Model = %s group by ID
    949                          """ % (Table.Table, MODEL_EFI_GUID)
    950             RecordSet = Table.Exec(SqlCommand)
    951             for Record in RecordSet:
    952                 Value1 = Record[1]
    953                 Value2 = Record[2]
    954                 GuidCommentList = []
    955                 InfPath = self.GetInfFilePathFromID(Record[3])
    956                 Msg = "The GUID format of %s in INF file [%s] does not follow rules" % (Value1, InfPath)
    957                 if Value2.startswith(DT.TAB_SPECIAL_COMMENT):
    958                     GuidCommentList = Value2[2:].split(DT.TAB_SPECIAL_COMMENT)
    959                     if GuidCommentList[0].strip().startswith(DT.TAB_INF_USAGE_UNDEFINED):
    960                         continue
    961                     elif len(GuidCommentList) > 1:
    962                         if not GuidCommentList[0].strip().startswith((DT.TAB_INF_USAGE_PRO,
    963                                                                       DT.TAB_INF_USAGE_SOME_PRO,
    964                                                                       DT.TAB_INF_USAGE_CON,
    965                                                                       DT.TAB_INF_USAGE_SOME_CON)):
    966                             EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_GUID, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])
    967                         if not (GuidCommentList[1].strip()).startswith(DT.TAB_INF_GUIDTYPE_VAR) and \
    968                             not GuidCommentList[1].strip().startswith((DT.TAB_INF_GUIDTYPE_EVENT,
    969                                                                        DT.TAB_INF_GUIDTYPE_HII,
    970                                                                        DT.TAB_INF_GUIDTYPE_FILE,
    971                                                                        DT.TAB_INF_GUIDTYPE_HOB,
    972                                                                        DT.TAB_INF_GUIDTYPE_FV,
    973                                                                        DT.TAB_INF_GUIDTYPE_ST,
    974                                                                        DT.TAB_INF_GUIDTYPE_TSG,
    975                                                                        DT.TAB_INF_GUIDTYPE_GUID,
    976                                                                        DT.TAB_INF_GUIDTYPE_PROTOCOL,
    977                                                                        DT.TAB_INF_GUIDTYPE_PPI,
    978                                                                        DT.TAB_INF_USAGE_UNDEFINED)):
    979                                 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_GUID, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])
    980                     else:
    981                         EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_GUID, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])
    982                 else:
    983                     EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_GUID, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])
    984 
    985     # Check Protocol Format in module INF

    986     def MetaDataFileCheckModuleFileProtocolFormat(self):
    987         if EccGlobalData.gConfig.MetaDataFileCheckModuleFileProtocolFormat or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
    988             EdkLogger.quiet("Check Protocol Format in module INF ...")
    989             Table = EccGlobalData.gDb.TblInf
    990             SqlCommand = """
    991                          select ID, Value1, Usage, BelongsToFile from %s where Model = %s group by ID
    992                          """ % (Table.Table, MODEL_EFI_PROTOCOL)
    993             RecordSet = Table.Exec(SqlCommand)
    994             for Record in RecordSet:
    995                 Value1 = Record[1]
    996                 Value2 = Record[2]
    997                 GuidCommentList = []
    998                 InfPath = self.GetInfFilePathFromID(Record[3])
    999                 Msg = "The Protocol format of %s in INF file [%s] does not follow rules" % (Value1, InfPath)
   1000                 if Value2.startswith(DT.TAB_SPECIAL_COMMENT):
   1001                     GuidCommentList = Value2[2:].split(DT.TAB_SPECIAL_COMMENT)
   1002                     if len(GuidCommentList) >= 1:
   1003                         if not GuidCommentList[0].strip().startswith((DT.TAB_INF_USAGE_PRO,
   1004                                                                       DT.TAB_INF_USAGE_SOME_PRO,
   1005                                                                       DT.TAB_INF_USAGE_CON,
   1006                                                                       DT.TAB_INF_USAGE_SOME_CON,
   1007                                                                       DT.TAB_INF_USAGE_NOTIFY,
   1008                                                                       DT.TAB_INF_USAGE_TO_START,
   1009                                                                       DT.TAB_INF_USAGE_BY_START,
   1010                                                                       DT.TAB_INF_USAGE_UNDEFINED)):
   1011                             EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PROTOCOL, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])
   1012                 else:
   1013                     EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PROTOCOL, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])
   1014 
   1015 
   1016     # Check Ppi Format in module INF

   1017     def MetaDataFileCheckModuleFilePpiFormat(self):
   1018         if EccGlobalData.gConfig.MetaDataFileCheckModuleFilePpiFormat or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
   1019             EdkLogger.quiet("Check Ppi Format in module INF ...")
   1020             Table = EccGlobalData.gDb.TblInf
   1021             SqlCommand = """
   1022                          select ID, Value1, Usage, BelongsToFile from %s where Model = %s group by ID
   1023                          """ % (Table.Table, MODEL_EFI_PPI)
   1024             RecordSet = Table.Exec(SqlCommand)
   1025             for Record in RecordSet:
   1026                 Value1 = Record[1]
   1027                 Value2 = Record[2]
   1028                 GuidCommentList = []
   1029                 InfPath = self.GetInfFilePathFromID(Record[3])
   1030                 Msg = "The Ppi format of %s in INF file [%s] does not follow rules" % (Value1, InfPath)
   1031                 if Value2.startswith(DT.TAB_SPECIAL_COMMENT):
   1032                     GuidCommentList = Value2[2:].split(DT.TAB_SPECIAL_COMMENT)
   1033                     if len(GuidCommentList) >= 1:
   1034                         if not GuidCommentList[0].strip().startswith((DT.TAB_INF_USAGE_PRO,
   1035                                                                       DT.TAB_INF_USAGE_SOME_PRO,
   1036                                                                       DT.TAB_INF_USAGE_CON,
   1037                                                                       DT.TAB_INF_USAGE_SOME_CON,
   1038                                                                       DT.TAB_INF_USAGE_NOTIFY,
   1039                                                                       DT.TAB_INF_USAGE_UNDEFINED)):
   1040                             EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PPI, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])
   1041                 else:
   1042                     EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PPI, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])
   1043 
   1044     # Check Pcd Format in module INF

   1045     def MetaDataFileCheckModuleFilePcdFormat(self):
   1046         if EccGlobalData.gConfig.MetaDataFileCheckModuleFilePcdFormat or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
   1047             EdkLogger.quiet("Check Pcd Format in module INF ...")
   1048             Table = EccGlobalData.gDb.TblInf
   1049             SqlCommand = """
   1050                          select ID, Model, Value1, Value2, Usage, BelongsToFile from %s where Model >= %s and Model < %s group by ID
   1051                          """ % (Table.Table, MODEL_PCD, MODEL_META_DATA_HEADER)
   1052             RecordSet = Table.Exec(SqlCommand)
   1053             for Record in RecordSet:
   1054                 Model = Record[1]
   1055                 PcdName = Record[2] + '.' + Record[3]
   1056                 Usage = Record[4]
   1057                 PcdCommentList = []
   1058                 InfPath = self.GetInfFilePathFromID(Record[5])
   1059                 Msg = "The Pcd format of %s in INF file [%s] does not follow rules" % (PcdName, InfPath)
   1060                 if Usage.startswith(DT.TAB_SPECIAL_COMMENT):
   1061                     PcdCommentList = Usage[2:].split(DT.TAB_SPECIAL_COMMENT)
   1062                     if len(PcdCommentList) >= 1:
   1063                         if Model in [MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_FEATURE_FLAG] \
   1064                             and not PcdCommentList[0].strip().startswith((DT.TAB_INF_USAGE_SOME_PRO,
   1065                                                                           DT.TAB_INF_USAGE_CON,
   1066                                                                           DT.TAB_INF_USAGE_UNDEFINED)):
   1067                             EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PCD, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])
   1068                         if Model in [MODEL_PCD_PATCHABLE_IN_MODULE, MODEL_PCD_DYNAMIC, MODEL_PCD_DYNAMIC_EX] \
   1069                             and not PcdCommentList[0].strip().startswith((DT.TAB_INF_USAGE_PRO,
   1070                                                                           DT.TAB_INF_USAGE_SOME_PRO,
   1071                                                                           DT.TAB_INF_USAGE_CON,
   1072                                                                           DT.TAB_INF_USAGE_SOME_CON,
   1073                                                                           DT.TAB_INF_USAGE_UNDEFINED)):
   1074                             EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PCD, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])
   1075                 else:
   1076                     EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PCD, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])
   1077 
   1078     # Check whether these is duplicate Guid/Ppi/Protocol name

   1079     def CheckGuidProtocolPpi(self, ErrorID, Model, Table):
   1080         Name = ''
   1081         if Model == MODEL_EFI_GUID:
   1082             Name = 'guid'
   1083         if Model == MODEL_EFI_PROTOCOL:
   1084             Name = 'protocol'
   1085         if Model == MODEL_EFI_PPI:
   1086             Name = 'ppi'
   1087         SqlCommand = """
   1088                      select A.ID, A.Value1 from %s as A, %s as B
   1089                      where A.Model = %s and B.Model = %s
   1090                      and A.Value1 like B.Value1 and A.ID <> B.ID
   1091                      and A.Scope1 = B.Scope1
   1092                      and A.Enabled > -1
   1093                      and B.Enabled > -1
   1094                      group by A.ID
   1095                      """ % (Table.Table, Table.Table, Model, Model)
   1096         RecordSet = Table.Exec(SqlCommand)
   1097         for Record in RecordSet:
   1098             if not EccGlobalData.gException.IsException(ErrorID, Record[1]):
   1099                 EccGlobalData.gDb.TblReport.Insert(ErrorID, OtherMsg="The %s name [%s] is defined more than one time" % (Name.upper(), Record[1]), BelongsToTable=Table.Table, BelongsToItem=Record[0])
   1100 
   1101     # Check whether these is duplicate Guid/Ppi/Protocol value

   1102     def CheckGuidProtocolPpiValue(self, ErrorID, Model):
   1103         Name = ''
   1104         Table = EccGlobalData.gDb.TblDec
   1105         if Model == MODEL_EFI_GUID:
   1106             Name = 'guid'
   1107         if Model == MODEL_EFI_PROTOCOL:
   1108             Name = 'protocol'
   1109         if Model == MODEL_EFI_PPI:
   1110             Name = 'ppi'
   1111         SqlCommand = """
   1112                      select A.ID, A.Value1, A.Value2 from %s as A, %s as B
   1113                      where A.Model = %s and B.Model = %s
   1114                      and A.Value2 like B.Value2 and A.ID <> B.ID
   1115                      and A.Scope1 = B.Scope1 and A.Value1 <> B.Value1
   1116                      group by A.ID
   1117                      """ % (Table.Table, Table.Table, Model, Model)
   1118         RecordSet = Table.Exec(SqlCommand)
   1119         for Record in RecordSet:     
   1120             if not EccGlobalData.gException.IsException(ErrorID, Record[2]):
   1121                 EccGlobalData.gDb.TblReport.Insert(ErrorID, OtherMsg="The %s value [%s] is used more than one time" % (Name.upper(), Record[2]), BelongsToTable=Table.Table, BelongsToItem=Record[0])
   1122 
   1123     # Naming Convention Check

   1124     def NamingConventionCheck(self):
   1125         if EccGlobalData.gConfig.NamingConventionCheckDefineStatement == '1' \
   1126         or EccGlobalData.gConfig.NamingConventionCheckTypedefStatement == '1' \
   1127         or EccGlobalData.gConfig.NamingConventionCheckIfndefStatement == '1' \
   1128         or EccGlobalData.gConfig.NamingConventionCheckVariableName == '1' \
   1129         or EccGlobalData.gConfig.NamingConventionCheckSingleCharacterVariable == '1' \
   1130         or EccGlobalData.gConfig.NamingConventionCheckAll == '1'\
   1131         or EccGlobalData.gConfig.CheckAll == '1':
   1132             for Dirpath, Dirnames, Filenames in self.WalkTree():
   1133                 for F in Filenames:
   1134                     if os.path.splitext(F)[1] in ('.h', '.c'):
   1135                         FullName = os.path.join(Dirpath, F)
   1136                         Id = c.GetTableID(FullName)
   1137                         if Id < 0:
   1138                             continue
   1139                         FileTable = 'Identifier' + str(Id)
   1140                         self.NamingConventionCheckDefineStatement(FileTable)
   1141                         self.NamingConventionCheckTypedefStatement(FileTable)
   1142                         self.NamingConventionCheckIfndefStatement(FileTable)
   1143                         self.NamingConventionCheckVariableName(FileTable)
   1144                         self.NamingConventionCheckSingleCharacterVariable(FileTable)
   1145 
   1146         self.NamingConventionCheckPathName()
   1147         self.NamingConventionCheckFunctionName()
   1148 
   1149     # Check whether only capital letters are used for #define declarations

   1150     def NamingConventionCheckDefineStatement(self, FileTable):
   1151         if EccGlobalData.gConfig.NamingConventionCheckDefineStatement == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
   1152             EdkLogger.quiet("Checking naming covention of #define statement ...")
   1153 
   1154             SqlCommand = """select ID, Value from %s where Model = %s""" % (FileTable, MODEL_IDENTIFIER_MACRO_DEFINE)
   1155             RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
   1156             for Record in RecordSet:
   1157                 Name = Record[1].strip().split()[1]
   1158                 if Name.find('(') != -1:
   1159                     Name = Name[0:Name.find('(')]
   1160                 if Name.upper() != Name:
   1161                     if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_DEFINE_STATEMENT, Name):
   1162                         EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_DEFINE_STATEMENT, OtherMsg="The #define name [%s] does not follow the rules" % (Name), BelongsToTable=FileTable, BelongsToItem=Record[0])
   1163 
   1164     # Check whether only capital letters are used for typedef declarations

   1165     def NamingConventionCheckTypedefStatement(self, FileTable):
   1166         if EccGlobalData.gConfig.NamingConventionCheckTypedefStatement == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
   1167             EdkLogger.quiet("Checking naming covention of #typedef statement ...")
   1168 
   1169             SqlCommand = """select ID, Name from %s where Model = %s""" % (FileTable, MODEL_IDENTIFIER_TYPEDEF)
   1170             RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
   1171             for Record in RecordSet:
   1172                 Name = Record[1].strip()
   1173                 if Name != '' and Name != None:
   1174                     if Name[0] == '(':
   1175                         Name = Name[1:Name.find(')')]
   1176                     if Name.find('(') > -1:
   1177                         Name = Name[Name.find('(') + 1 : Name.find(')')]
   1178                     Name = Name.replace('WINAPI', '')
   1179                     Name = Name.replace('*', '').strip()
   1180                     if Name.upper() != Name:
   1181                         if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_TYPEDEF_STATEMENT, Name):
   1182                             EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_TYPEDEF_STATEMENT, OtherMsg="The #typedef name [%s] does not follow the rules" % (Name), BelongsToTable=FileTable, BelongsToItem=Record[0])
   1183 
   1184     # Check whether the #ifndef at the start of an include file uses both prefix and postfix underscore characters, '_'.

   1185     def NamingConventionCheckIfndefStatement(self, FileTable):
   1186         if EccGlobalData.gConfig.NamingConventionCheckTypedefStatement == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
   1187             EdkLogger.quiet("Checking naming covention of #ifndef statement ...")
   1188 
   1189             SqlCommand = """select ID, Value from %s where Model = %s""" % (FileTable, MODEL_IDENTIFIER_MACRO_IFNDEF)
   1190             RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
   1191             for Record in RecordSet:
   1192                 Name = Record[1].replace('#ifndef', '').strip()
   1193                 if Name[0] != '_' or Name[-1] != '_':
   1194                     if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_IFNDEF_STATEMENT, Name):
   1195                         EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_IFNDEF_STATEMENT, OtherMsg="The #ifndef name [%s] does not follow the rules" % (Name), BelongsToTable=FileTable, BelongsToItem=Record[0])
   1196 
   1197     # Rule for path name, variable name and function name

   1198     # 1. First character should be upper case

   1199     # 2. Existing lower case in a word

   1200     # 3. No space existence

   1201     # Check whether the path name followed the rule

   1202     def NamingConventionCheckPathName(self):
   1203         if EccGlobalData.gConfig.NamingConventionCheckPathName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
   1204             EdkLogger.quiet("Checking naming covention of file path name ...")
   1205             Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$')
   1206             SqlCommand = """select ID, Name from File"""
   1207             RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
   1208             for Record in RecordSet:
   1209                 if not Pattern.match(Record[1]):
   1210                     if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_PATH_NAME, Record[1]):
   1211                         EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_PATH_NAME, OtherMsg="The file path [%s] does not follow the rules" % (Record[1]), BelongsToTable='File', BelongsToItem=Record[0])
   1212 
   1213     # Rule for path name, variable name and function name

   1214     # 1. First character should be upper case

   1215     # 2. Existing lower case in a word

   1216     # 3. No space existence

   1217     # 4. Global variable name must start with a 'g'

   1218     # Check whether the variable name followed the rule

   1219     def NamingConventionCheckVariableName(self, FileTable):
   1220         if EccGlobalData.gConfig.NamingConventionCheckVariableName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
   1221             EdkLogger.quiet("Checking naming covention of variable name ...")
   1222             Pattern = re.compile(r'^[A-Zgm]+\S*[a-z]\S*$')
   1223 
   1224             SqlCommand = """select ID, Name from %s where Model = %s""" % (FileTable, MODEL_IDENTIFIER_VARIABLE)
   1225             RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
   1226             for Record in RecordSet:
   1227                 Var = Record[1]
   1228                 if Var.startswith('CONST'):
   1229                     Var = Var[5:].lstrip()
   1230                 if not Pattern.match(Var):
   1231                     if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Record[1]):
   1232                         EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, OtherMsg="The variable name [%s] does not follow the rules" % (Record[1]), BelongsToTable=FileTable, BelongsToItem=Record[0])
   1233 
   1234     # Rule for path name, variable name and function name

   1235     # 1. First character should be upper case

   1236     # 2. Existing lower case in a word

   1237     # 3. No space existence

   1238     # Check whether the function name followed the rule

   1239     def NamingConventionCheckFunctionName(self):
   1240         if EccGlobalData.gConfig.NamingConventionCheckFunctionName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
   1241             EdkLogger.quiet("Checking naming covention of function name ...")
   1242             Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$')
   1243             SqlCommand = """select ID, Name from Function"""
   1244             RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
   1245             for Record in RecordSet:
   1246                 if not Pattern.match(Record[1]):
   1247                     if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_FUNCTION_NAME, Record[1]):
   1248                         EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_FUNCTION_NAME, OtherMsg="The function name [%s] does not follow the rules" % (Record[1]), BelongsToTable='Function', BelongsToItem=Record[0])
   1249 
   1250     # Check whether NO use short variable name with single character

   1251     def NamingConventionCheckSingleCharacterVariable(self, FileTable):
   1252         if EccGlobalData.gConfig.NamingConventionCheckSingleCharacterVariable == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
   1253             EdkLogger.quiet("Checking naming covention of single character variable name ...")
   1254 
   1255             SqlCommand = """select ID, Name from %s where Model = %s""" % (FileTable, MODEL_IDENTIFIER_VARIABLE)
   1256             RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
   1257             for Record in RecordSet:
   1258                 Variable = Record[1].replace('*', '')
   1259                 if len(Variable) == 1:
   1260                     if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_SINGLE_CHARACTER_VARIABLE, Record[1]):
   1261                         EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_SINGLE_CHARACTER_VARIABLE, OtherMsg="The variable name [%s] does not follow the rules" % (Record[1]), BelongsToTable=FileTable, BelongsToItem=Record[0])
   1262 
   1263 ##

   1264 #

   1265 # This acts like the main() function for the script, unless it is 'import'ed into another

   1266 # script.

   1267 #

   1268 if __name__ == '__main__':
   1269     Check = Check()
   1270     Check.Check()
   1271