2009-07-17 09:10:31 +00:00
## @file
# This file is used to define checkpoints used by ECC tool
#
2021-02-16 17:29:07 +08:00
# Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
2020-01-10 16:37:46 +08:00
# Copyright (c) 2008 - 2020, Intel Corporation. All rights reserved.<BR>
2019-04-03 16:03:11 -07:00
# SPDX-License-Identifier: BSD-2-Clause-Patent
2009-07-17 09:10:31 +00:00
#
2018-07-13 18:18:42 +08:00
from __future__ import absolute_import
2014-08-15 03:06:48 +00:00
import Common.LongFilePathOs as os
2009-07-17 09:10:31 +00:00
import re
from CommonDataClass.DataClass import *
2014-08-25 01:16:34 +00:00
import Common.DataType as DT
2018-08-08 11:18:06 +08:00
from Ecc.EccToolError import *
from Ecc.MetaDataParser import ParseHeaderCommentSection
from Ecc import EccGlobalData
from Ecc import c
2014-08-25 01:16:34 +00:00
from Common.LongFilePathSupport import OpenLongFilePath as open
2015-10-08 09:28:51 +00:00
from Common.MultipleWorkspace import MultipleWorkspace as mws
2009-07-17 09:10:31 +00:00
## Check
#
# This class is to define checkpoints used by ECC tool
#
# @param object: Inherited from object class
#
class Check ( object ):
def __init__ ( self ):
pass
# Check all required checkpoints
def Check ( self ):
2010-09-06 01:58:00 +00:00
self . GeneralCheck ()
2009-07-17 09:10:31 +00:00
self . MetaDataFileCheck ()
self . DoxygenCheck ()
self . IncludeFileCheck ()
self . PredicateExpressionCheck ()
self . DeclAndDataTypeCheck ()
self . FunctionLayoutCheck ()
self . NamingConventionCheck ()
2017-04-11 16:17:19 +08:00
self . SmmCommParaCheck ()
def SmmCommParaCheck ( self ):
self . SmmCommParaCheckBufferType ()
# Check if SMM communication function has correct parameter type
# 1. Get function calling with instance./->Communicate() interface
# and make sure the protocol instance is of type EFI_SMM_COMMUNICATION_PROTOCOL.
# 2. Find the origin of the 2nd parameter of Communicate() interface, if -
# a. it is a local buffer on stack
# report error.
# b. it is a global buffer, check the driver that holds the global buffer is of type DXE_RUNTIME_DRIVER
# report success.
# c. it is a buffer by AllocatePage/AllocatePool (may be wrapped by nested function calls),
# check the EFI_MEMORY_TYPE to be EfiRuntimeServicesCode,EfiRuntimeServicesData,
# EfiACPIMemoryNVS or EfiReservedMemoryType
# report success.
# d. it is a buffer located via EFI_SYSTEM_TABLE.ConfigurationTable (may be wrapped by nested function calls)
# report warning to indicate human code review.
# e. it is a buffer from other kind of pointers (may need to trace into nested function calls to locate),
# repeat checks in a.b.c and d.
def SmmCommParaCheckBufferType ( self ):
if EccGlobalData . gConfig . SmmCommParaCheckBufferType == '1' or EccGlobalData . gConfig . SmmCommParaCheckAll == '1' :
EdkLogger . quiet ( "Checking SMM communication parameter type ..." )
# Get all EFI_SMM_COMMUNICATION_PROTOCOL interface
CommApiList = []
for IdentifierTable in EccGlobalData . gIdentifierTableList :
SqlCommand = """select ID, Name, BelongsToFile from %s
where Modifier = 'EFI_SMM_COMMUNICATION_PROTOCOL*' """ % ( IdentifierTable )
RecordSet = EccGlobalData . gDb . TblFile . Exec ( SqlCommand )
if RecordSet :
for Record in RecordSet :
if Record [ 1 ] not in CommApiList :
CommApiList . append ( Record [ 1 ])
# For each interface, check the second parameter
for CommApi in CommApiList :
for IdentifierTable in EccGlobalData . gIdentifierTableList :
SqlCommand = """select ID, Name, Value, BelongsToFile, StartLine from %s
where Name = ' %s ->Communicate' and Model = %s """ \
% ( IdentifierTable , CommApi , MODEL_IDENTIFIER_FUNCTION_CALLING )
RecordSet = EccGlobalData . gDb . TblFile . Exec ( SqlCommand )
if RecordSet :
# print IdentifierTable
for Record in RecordSet :
# Get the second parameter for Communicate function
SecondPara = Record [ 2 ] . split ( ',' )[ 1 ] . strip ()
SecondParaIndex = None
if SecondPara . startswith ( '&' ):
SecondPara = SecondPara [ 1 :]
if SecondPara . endswith ( ']' ):
SecondParaIndex = SecondPara [ SecondPara . find ( '[' ) + 1 : - 1 ]
SecondPara = SecondPara [: SecondPara . find ( '[' )]
# Get the ID
Id = Record [ 0 ]
# Get the BelongsToFile
BelongsToFile = Record [ 3 ]
# Get the source file path
SqlCommand = """select FullPath from File where ID = %s """ % BelongsToFile
NewRecordSet = EccGlobalData . gDb . TblFile . Exec ( SqlCommand )
FullPath = NewRecordSet [ 0 ][ 0 ]
# Get the line no of function calling
StartLine = Record [ 4 ]
# Get the module type
SqlCommand = """select Value3 from INF where BelongsToFile = (select ID from File
where Path = (select Path from File where ID = %s ) and Model = 1011)
and Value2 = 'MODULE_TYPE'""" % BelongsToFile
NewRecordSet = EccGlobalData . gDb . TblFile . Exec ( SqlCommand )
ModuleType = NewRecordSet [ 0 ][ 0 ] if NewRecordSet else None
# print BelongsToFile, FullPath, StartLine, ModuleType, SecondPara
Value = FindPara ( FullPath , SecondPara , StartLine )
# Find the value of the parameter
if Value :
if 'AllocatePage' in Value \
or 'AllocatePool' in Value \
or 'AllocateRuntimePool' in Value \
or 'AllocateZeroPool' in Value :
pass
else :
if '->' in Value :
if not EccGlobalData . gException . IsException (
ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE , Value ):
EccGlobalData . gDb . TblReport . Insert ( ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE ,
OtherMsg = "Please review the buffer type"
+ "is correct or not. If it is correct" +
" please add [ %s ] to exception list"
% Value ,
BelongsToTable = IdentifierTable ,
BelongsToItem = Id )
else :
if not EccGlobalData . gException . IsException (
ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE , Value ):
EccGlobalData . gDb . TblReport . Insert ( ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE ,
OtherMsg = "Please review the buffer type"
+ "is correct or not. If it is correct" +
" please add [ %s ] to exception list"
% Value ,
BelongsToTable = IdentifierTable ,
BelongsToItem = Id )
# Not find the value of the parameter
else :
SqlCommand = """select ID, Modifier, Name, Value, Model, BelongsToFunction from %s
where Name = ' %s ' and StartLine < %s order by StartLine DESC""" \
% ( IdentifierTable , SecondPara , StartLine )
NewRecordSet = EccGlobalData . gDb . TblFile . Exec ( SqlCommand )
if NewRecordSet :
Value = NewRecordSet [ 0 ][ 1 ]
if 'AllocatePage' in Value \
or 'AllocatePool' in Value \
or 'AllocateRuntimePool' in Value \
or 'AllocateZeroPool' in Value :
pass
else :
if not EccGlobalData . gException . IsException (
ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE , Value ):
EccGlobalData . gDb . TblReport . Insert ( ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE ,
OtherMsg = "Please review the buffer type"
+ "is correct or not. If it is correct" +
" please add [ %s ] to exception list"
% Value ,
BelongsToTable = IdentifierTable ,
BelongsToItem = Id )
else :
pass
2009-07-17 09:10:31 +00:00
2014-08-25 01:16:34 +00:00
# Check UNI files
def UniCheck ( self ):
if EccGlobalData . gConfig . GeneralCheckUni == '1' or EccGlobalData . gConfig . GeneralCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking whether UNI file is UTF-16 ..." )
SqlCommand = """select ID, FullPath, ExtName from File where ExtName like 'uni'"""
RecordSet = EccGlobalData . gDb . TblFile . Exec ( SqlCommand )
for Record in RecordSet :
File = Record [ 1 ]
FileIn = open ( File , 'rb' ) . read ( 2 )
if FileIn != ' \xff\xfe ' :
OtherMsg = "File %s is not a valid UTF-16 UNI file" % Record [ 1 ]
EccGlobalData . gDb . TblReport . Insert ( ERROR_GENERAL_CHECK_UNI , OtherMsg = OtherMsg , BelongsToTable = 'File' , BelongsToItem = Record [ 0 ])
2010-09-06 01:58:00 +00:00
# General Checking
def GeneralCheck ( self ):
2014-08-25 01:16:34 +00:00
self . UniCheck ()
2018-07-23 13:57:57 +08:00
self . GeneralCheckNoTab ()
self . GeneralCheckLineEnding ()
self . GeneralCheckTrailingWhiteSpaceLine ()
# Check whether NO Tab is used, replaced with spaces
def GeneralCheckNoTab ( self ):
if EccGlobalData . gConfig . GeneralCheckNoTab == '1' or EccGlobalData . gConfig . GeneralCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking No TAB used in file ..." )
SqlCommand = """select ID, FullPath, ExtName from File where ExtName in ('.dec', '.inf', '.dsc', 'c', 'h')"""
RecordSet = EccGlobalData . gDb . TblFile . Exec ( SqlCommand )
for Record in RecordSet :
if Record [ 2 ] . upper () not in EccGlobalData . gConfig . BinaryExtList :
op = open ( Record [ 1 ]) . readlines ()
IndexOfLine = 0
for Line in op :
IndexOfLine += 1
IndexOfChar = 0
for Char in Line :
IndexOfChar += 1
if Char == ' \t ' :
OtherMsg = "File %s has TAB char at line %s column %s " % ( Record [ 1 ], IndexOfLine , IndexOfChar )
EccGlobalData . gDb . TblReport . Insert ( ERROR_GENERAL_CHECK_NO_TAB , OtherMsg = OtherMsg , BelongsToTable = 'File' , BelongsToItem = Record [ 0 ])
# Check Only use CRLF (Carriage Return Line Feed) line endings.
def GeneralCheckLineEnding ( self ):
if EccGlobalData . gConfig . GeneralCheckLineEnding == '1' or EccGlobalData . gConfig . GeneralCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking line ending in file ..." )
SqlCommand = """select ID, FullPath, ExtName from File where ExtName in ('.dec', '.inf', '.dsc', 'c', 'h')"""
RecordSet = EccGlobalData . gDb . TblFile . Exec ( SqlCommand )
for Record in RecordSet :
if Record [ 2 ] . upper () not in EccGlobalData . gConfig . BinaryExtList :
op = open ( Record [ 1 ], 'rb' ) . readlines ()
IndexOfLine = 0
for Line in op :
IndexOfLine += 1
2019-01-04 17:35:10 +08:00
if not bytes . decode ( Line ) . endswith ( ' \r\n ' ):
2018-07-23 13:57:57 +08:00
OtherMsg = "File %s has invalid line ending at line %s " % ( Record [ 1 ], IndexOfLine )
EccGlobalData . gDb . TblReport . Insert ( ERROR_GENERAL_CHECK_INVALID_LINE_ENDING , OtherMsg = OtherMsg , BelongsToTable = 'File' , BelongsToItem = Record [ 0 ])
# Check if there is no trailing white space in one line.
def GeneralCheckTrailingWhiteSpaceLine ( self ):
if EccGlobalData . gConfig . GeneralCheckTrailingWhiteSpaceLine == '1' or EccGlobalData . gConfig . GeneralCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking trailing white space line in file ..." )
SqlCommand = """select ID, FullPath, ExtName from File where ExtName in ('.dec', '.inf', '.dsc', 'c', 'h')"""
RecordSet = EccGlobalData . gDb . TblFile . Exec ( SqlCommand )
for Record in RecordSet :
if Record [ 2 ] . upper () not in EccGlobalData . gConfig . BinaryExtList :
2019-01-04 17:35:10 +08:00
op = open ( Record [ 1 ], 'r' ) . readlines ()
2018-07-23 13:57:57 +08:00
IndexOfLine = 0
for Line in op :
IndexOfLine += 1
if Line . replace ( ' \r ' , '' ) . replace ( ' \n ' , '' ) . endswith ( ' ' ):
OtherMsg = "File %s has trailing white spaces at line %s " % ( Record [ 1 ], IndexOfLine )
EccGlobalData . gDb . TblReport . Insert ( ERROR_GENERAL_CHECK_TRAILING_WHITE_SPACE_LINE , OtherMsg = OtherMsg , BelongsToTable = 'File' , BelongsToItem = Record [ 0 ])
2010-09-06 01:58:00 +00:00
2009-07-17 09:10:31 +00:00
# C Function Layout Checking
def FunctionLayoutCheck ( self ):
self . FunctionLayoutCheckReturnType ()
self . FunctionLayoutCheckModifier ()
self . FunctionLayoutCheckName ()
self . FunctionLayoutCheckPrototype ()
self . FunctionLayoutCheckBody ()
self . FunctionLayoutCheckLocalVariable ()
2018-10-17 10:22:04 +08:00
self . FunctionLayoutCheckDeprecated ()
2019-10-01 13:42:32 +01:00
2018-10-17 10:22:04 +08:00
# To check if the deprecated functions are used
def FunctionLayoutCheckDeprecated ( self ):
if EccGlobalData . gConfig . CFunctionLayoutCheckNoDeprecated == '1' or EccGlobalData . gConfig . CFunctionLayoutCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking function no deprecated one being used ..." )
DeprecatedFunctionSet = ( 'UnicodeValueToString' ,
'AsciiValueToString' ,
'StrCpy' ,
'StrnCpy' ,
'StrCat' ,
'StrnCat' ,
'UnicodeStrToAsciiStr' ,
'AsciiStrCpy' ,
'AsciiStrnCpy' ,
'AsciiStrCat' ,
'AsciiStrnCat' ,
'AsciiStrToUnicodeStr' ,
'PcdSet8' ,
'PcdSet16' ,
'PcdSet32' ,
'PcdSet64' ,
'PcdSetPtr' ,
'PcdSetBool' ,
'PcdSetEx8' ,
'PcdSetEx16' ,
'PcdSetEx32' ,
'PcdSetEx64' ,
'PcdSetExPtr' ,
'PcdSetExBool' ,
'LibPcdSet8' ,
'LibPcdSet16' ,
'LibPcdSet32' ,
'LibPcdSet64' ,
'LibPcdSetPtr' ,
'LibPcdSetBool' ,
'LibPcdSetEx8' ,
'LibPcdSetEx16' ,
'LibPcdSetEx32' ,
'LibPcdSetEx64' ,
'LibPcdSetExPtr' ,
'LibPcdSetExBool' ,
'GetVariable' ,
'GetEfiGlobalVariable' ,
)
for IdentifierTable in EccGlobalData . gIdentifierTableList :
SqlCommand = """select ID, Name, BelongsToFile from %s
where Model = %s """ % ( IdentifierTable , MODEL_IDENTIFIER_FUNCTION_CALLING )
RecordSet = EccGlobalData . gDb . TblFile . Exec ( SqlCommand )
for Record in RecordSet :
for Key in DeprecatedFunctionSet :
if Key == Record [ 1 ]:
if not EccGlobalData . gException . IsException ( ERROR_C_FUNCTION_LAYOUT_CHECK_NO_DEPRECATE , Key ):
OtherMsg = 'The function [ %s ] is deprecated which should NOT be used' % Key
EccGlobalData . gDb . TblReport . Insert ( ERROR_C_FUNCTION_LAYOUT_CHECK_NO_DEPRECATE ,
OtherMsg = OtherMsg ,
BelongsToTable = IdentifierTable ,
BelongsToItem = Record [ 0 ])
2009-07-17 09:10:31 +00:00
def WalkTree ( self ):
IgnoredPattern = c . GetIgnoredDirListPattern ()
for Dirpath , Dirnames , Filenames in os . walk ( EccGlobalData . gTarget ):
for Dir in Dirnames :
Dirname = os . path . join ( Dirpath , Dir )
if os . path . islink ( Dirname ):
Dirname = os . path . realpath ( Dirname )
if os . path . isdir ( Dirname ):
# symlinks to directories are treated as directories
Dirnames . remove ( Dir )
Dirnames . append ( Dirname )
if IgnoredPattern . match ( Dirpath . upper ()):
continue
2015-06-25 07:43:03 +00:00
for f in Filenames [:]:
if f . lower () in EccGlobalData . gConfig . SkipFileList :
Filenames . remove ( f )
2009-07-17 09:10:31 +00:00
yield ( Dirpath , Dirnames , Filenames )
# Check whether return type exists and in the first line
def FunctionLayoutCheckReturnType ( self ):
if EccGlobalData . gConfig . CFunctionLayoutCheckReturnType == '1' or EccGlobalData . gConfig . CFunctionLayoutCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking function layout return type ..." )
2010-09-06 01:58:00 +00:00
# for Dirpath, Dirnames, Filenames in self.WalkTree():
# for F in Filenames:
# if os.path.splitext(F)[1] in ('.c', '.h'):
# FullName = os.path.join(Dirpath, F)
# c.CheckFuncLayoutReturnType(FullName)
for FullName in EccGlobalData . gCFileList + EccGlobalData . gHFileList :
c . CheckFuncLayoutReturnType ( FullName )
2009-07-17 09:10:31 +00:00
# Check whether any optional functional modifiers exist and next to the return type
def FunctionLayoutCheckModifier ( self ):
if EccGlobalData . gConfig . CFunctionLayoutCheckOptionalFunctionalModifier == '1' or EccGlobalData . gConfig . CFunctionLayoutCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking function layout modifier ..." )
2010-09-06 01:58:00 +00:00
# for Dirpath, Dirnames, Filenames in self.WalkTree():
# for F in Filenames:
# if os.path.splitext(F)[1] in ('.c', '.h'):
# FullName = os.path.join(Dirpath, F)
# c.CheckFuncLayoutModifier(FullName)
for FullName in EccGlobalData . gCFileList + EccGlobalData . gHFileList :
c . CheckFuncLayoutModifier ( FullName )
2009-07-17 09:10:31 +00:00
# Check whether the next line contains the function name, left justified, followed by the beginning of the parameter list
# Check whether the closing parenthesis is on its own line and also indented two spaces
def FunctionLayoutCheckName ( self ):
if EccGlobalData . gConfig . CFunctionLayoutCheckFunctionName == '1' or EccGlobalData . gConfig . CFunctionLayoutCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking function layout function name ..." )
2010-09-06 01:58:00 +00:00
# for Dirpath, Dirnames, Filenames in self.WalkTree():
# for F in Filenames:
# if os.path.splitext(F)[1] in ('.c', '.h'):
# FullName = os.path.join(Dirpath, F)
# c.CheckFuncLayoutName(FullName)
for FullName in EccGlobalData . gCFileList + EccGlobalData . gHFileList :
c . CheckFuncLayoutName ( FullName )
2009-07-17 09:10:31 +00:00
# Check whether the function prototypes in include files have the same form as function definitions
def FunctionLayoutCheckPrototype ( self ):
if EccGlobalData . gConfig . CFunctionLayoutCheckFunctionPrototype == '1' or EccGlobalData . gConfig . CFunctionLayoutCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking function layout function prototype ..." )
2010-09-06 01:58:00 +00:00
# for Dirpath, Dirnames, Filenames in self.WalkTree():
# for F in Filenames:
# if os.path.splitext(F)[1] in ('.c'):
# FullName = os.path.join(Dirpath, F)
# EdkLogger.quiet("[PROTOTYPE]" + FullName)
# c.CheckFuncLayoutPrototype(FullName)
for FullName in EccGlobalData . gCFileList :
EdkLogger . quiet ( "[PROTOTYPE]" + FullName )
c . CheckFuncLayoutPrototype ( FullName )
2009-07-17 09:10:31 +00:00
# Check whether the body of a function is contained by open and close braces that must be in the first column
def FunctionLayoutCheckBody ( self ):
if EccGlobalData . gConfig . CFunctionLayoutCheckFunctionBody == '1' or EccGlobalData . gConfig . CFunctionLayoutCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking function layout function body ..." )
2010-09-06 01:58:00 +00:00
# for Dirpath, Dirnames, Filenames in self.WalkTree():
# for F in Filenames:
# if os.path.splitext(F)[1] in ('.c'):
# FullName = os.path.join(Dirpath, F)
# c.CheckFuncLayoutBody(FullName)
for FullName in EccGlobalData . gCFileList :
c . CheckFuncLayoutBody ( FullName )
2009-07-17 09:10:31 +00:00
# Check whether the data declarations is the first code in a module.
# self.CFunctionLayoutCheckDataDeclaration = 1
# Check whether no initialization of a variable as part of its declaration
def FunctionLayoutCheckLocalVariable ( self ):
if EccGlobalData . gConfig . CFunctionLayoutCheckNoInitOfVariable == '1' or EccGlobalData . gConfig . CFunctionLayoutCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking function layout local variables ..." )
2010-09-06 01:58:00 +00:00
# for Dirpath, Dirnames, Filenames in self.WalkTree():
# for F in Filenames:
# if os.path.splitext(F)[1] in ('.c'):
# FullName = os.path.join(Dirpath, F)
# c.CheckFuncLayoutLocalVariable(FullName)
for FullName in EccGlobalData . gCFileList :
c . CheckFuncLayoutLocalVariable ( FullName )
2009-07-17 09:10:31 +00:00
# Check whether no use of STATIC for functions
# self.CFunctionLayoutCheckNoStatic = 1
# Declarations and Data Types Checking
def DeclAndDataTypeCheck ( self ):
self . DeclCheckNoUseCType ()
self . DeclCheckInOutModifier ()
self . DeclCheckEFIAPIModifier ()
self . DeclCheckEnumeratedType ()
self . DeclCheckStructureDeclaration ()
self . DeclCheckSameStructure ()
self . DeclCheckUnionType ()
2019-09-04 17:54:12 +08:00
# Check whether no use of int, unsigned, char, void, long in any .c, .h or .asl files.
2009-07-17 09:10:31 +00:00
def DeclCheckNoUseCType ( self ):
if EccGlobalData . gConfig . DeclarationDataTypeCheckNoUseCType == '1' or EccGlobalData . gConfig . DeclarationDataTypeCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking Declaration No use C type ..." )
2010-09-06 01:58:00 +00:00
# for Dirpath, Dirnames, Filenames in self.WalkTree():
# for F in Filenames:
# if os.path.splitext(F)[1] in ('.h', '.c'):
# FullName = os.path.join(Dirpath, F)
# c.CheckDeclNoUseCType(FullName)
for FullName in EccGlobalData . gCFileList + EccGlobalData . gHFileList :
c . CheckDeclNoUseCType ( FullName )
2009-07-17 09:10:31 +00:00
# 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
def DeclCheckInOutModifier ( self ):
if EccGlobalData . gConfig . DeclarationDataTypeCheckInOutModifier == '1' or EccGlobalData . gConfig . DeclarationDataTypeCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking Declaration argument modifier ..." )
2010-09-06 01:58:00 +00:00
# for Dirpath, Dirnames, Filenames in self.WalkTree():
# for F in Filenames:
# if os.path.splitext(F)[1] in ('.h', '.c'):
# FullName = os.path.join(Dirpath, F)
# c.CheckDeclArgModifier(FullName)
for FullName in EccGlobalData . gCFileList + EccGlobalData . gHFileList :
c . CheckDeclArgModifier ( FullName )
2009-07-17 09:10:31 +00:00
# Check whether the EFIAPI modifier should be used at the entry of drivers, events, and member functions of protocols
def DeclCheckEFIAPIModifier ( self ):
if EccGlobalData . gConfig . DeclarationDataTypeCheckEFIAPIModifier == '1' or EccGlobalData . gConfig . DeclarationDataTypeCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
pass
# Check whether Enumerated Type has a 'typedef' and the name is capital
def DeclCheckEnumeratedType ( self ):
if EccGlobalData . gConfig . DeclarationDataTypeCheckEnumeratedType == '1' or EccGlobalData . gConfig . DeclarationDataTypeCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking Declaration enum typedef ..." )
2010-09-06 01:58:00 +00:00
# for Dirpath, Dirnames, Filenames in self.WalkTree():
# for F in Filenames:
# if os.path.splitext(F)[1] in ('.h', '.c'):
# FullName = os.path.join(Dirpath, F)
# EdkLogger.quiet("[ENUM]" + FullName)
# c.CheckDeclEnumTypedef(FullName)
for FullName in EccGlobalData . gCFileList + EccGlobalData . gHFileList :
EdkLogger . quiet ( "[ENUM]" + FullName )
c . CheckDeclEnumTypedef ( FullName )
2009-07-17 09:10:31 +00:00
# Check whether Structure Type has a 'typedef' and the name is capital
def DeclCheckStructureDeclaration ( self ):
if EccGlobalData . gConfig . DeclarationDataTypeCheckStructureDeclaration == '1' or EccGlobalData . gConfig . DeclarationDataTypeCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking Declaration struct typedef ..." )
2010-09-06 01:58:00 +00:00
# for Dirpath, Dirnames, Filenames in self.WalkTree():
# for F in Filenames:
# if os.path.splitext(F)[1] in ('.h', '.c'):
# FullName = os.path.join(Dirpath, F)
# EdkLogger.quiet("[STRUCT]" + FullName)
# c.CheckDeclStructTypedef(FullName)
for FullName in EccGlobalData . gCFileList + EccGlobalData . gHFileList :
EdkLogger . quiet ( "[STRUCT]" + FullName )
c . CheckDeclStructTypedef ( FullName )
2009-07-17 09:10:31 +00:00
# Check whether having same Structure
def DeclCheckSameStructure ( self ):
if EccGlobalData . gConfig . DeclarationDataTypeCheckSameStructure == '1' or EccGlobalData . gConfig . DeclarationDataTypeCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking same struct ..." )
AllStructure = {}
for IdentifierTable in EccGlobalData . gIdentifierTableList :
2011-11-09 04:32:08 +00:00
SqlCommand = """select ID, Name, BelongsToFile from %s where Model = %s """ % ( IdentifierTable , MODEL_IDENTIFIER_STRUCTURE )
2009-07-17 09:10:31 +00:00
RecordSet = EccGlobalData . gDb . TblFile . Exec ( SqlCommand )
for Record in RecordSet :
if Record [ 1 ] != '' :
if Record [ 1 ] not in AllStructure . keys ():
AllStructure [ Record [ 1 ]] = Record [ 2 ]
else :
ID = AllStructure [ Record [ 1 ]]
SqlCommand = """select FullPath from File where ID = %s """ % ID
NewRecordSet = EccGlobalData . gDb . TblFile . Exec ( SqlCommand )
OtherMsg = "The structure name ' %s ' is duplicate" % Record [ 1 ]
if NewRecordSet != []:
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 ])
if not EccGlobalData . gException . IsException ( ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE , Record [ 1 ]):
2011-11-09 04:32:08 +00:00
EccGlobalData . gDb . TblReport . Insert ( ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE , OtherMsg = OtherMsg , BelongsToTable = IdentifierTable , BelongsToItem = Record [ 0 ])
2009-07-17 09:10:31 +00:00
# Check whether Union Type has a 'typedef' and the name is capital
def DeclCheckUnionType ( self ):
if EccGlobalData . gConfig . DeclarationDataTypeCheckUnionType == '1' or EccGlobalData . gConfig . DeclarationDataTypeCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking Declaration union typedef ..." )
2010-09-06 01:58:00 +00:00
# for Dirpath, Dirnames, Filenames in self.WalkTree():
# for F in Filenames:
# if os.path.splitext(F)[1] in ('.h', '.c'):
# FullName = os.path.join(Dirpath, F)
# EdkLogger.quiet("[UNION]" + FullName)
# c.CheckDeclUnionTypedef(FullName)
for FullName in EccGlobalData . gCFileList + EccGlobalData . gHFileList :
EdkLogger . quiet ( "[UNION]" + FullName )
c . CheckDeclUnionTypedef ( FullName )
2009-07-17 09:10:31 +00:00
# Predicate Expression Checking
def PredicateExpressionCheck ( self ):
self . PredicateExpressionCheckBooleanValue ()
self . PredicateExpressionCheckNonBooleanOperator ()
self . PredicateExpressionCheckComparisonNullType ()
# Check whether Boolean values, variable type BOOLEAN not use explicit comparisons to TRUE or FALSE
def PredicateExpressionCheckBooleanValue ( self ):
if EccGlobalData . gConfig . PredicateExpressionCheckBooleanValue == '1' or EccGlobalData . gConfig . PredicateExpressionCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking predicate expression Boolean value ..." )
2010-09-06 01:58:00 +00:00
# for Dirpath, Dirnames, Filenames in self.WalkTree():
# for F in Filenames:
# if os.path.splitext(F)[1] in ('.c'):
# FullName = os.path.join(Dirpath, F)
# EdkLogger.quiet("[BOOLEAN]" + FullName)
# c.CheckBooleanValueComparison(FullName)
for FullName in EccGlobalData . gCFileList :
EdkLogger . quiet ( "[BOOLEAN]" + FullName )
c . CheckBooleanValueComparison ( FullName )
2009-07-17 09:10:31 +00:00
# Check whether Non-Boolean comparisons use a compare operator (==, !=, >, < >=, <=).
def PredicateExpressionCheckNonBooleanOperator ( self ):
if EccGlobalData . gConfig . PredicateExpressionCheckNonBooleanOperator == '1' or EccGlobalData . gConfig . PredicateExpressionCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking predicate expression Non-Boolean variable..." )
2010-09-06 01:58:00 +00:00
# for Dirpath, Dirnames, Filenames in self.WalkTree():
# for F in Filenames:
# if os.path.splitext(F)[1] in ('.c'):
# FullName = os.path.join(Dirpath, F)
# EdkLogger.quiet("[NON-BOOLEAN]" + FullName)
# c.CheckNonBooleanValueComparison(FullName)
for FullName in EccGlobalData . gCFileList :
EdkLogger . quiet ( "[NON-BOOLEAN]" + FullName )
c . CheckNonBooleanValueComparison ( FullName )
2009-07-17 09:10:31 +00:00
# Check whether a comparison of any pointer to zero must be done via the NULL type
def PredicateExpressionCheckComparisonNullType ( self ):
if EccGlobalData . gConfig . PredicateExpressionCheckComparisonNullType == '1' or EccGlobalData . gConfig . PredicateExpressionCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking predicate expression NULL pointer ..." )
2010-09-06 01:58:00 +00:00
# for Dirpath, Dirnames, Filenames in self.WalkTree():
# for F in Filenames:
# if os.path.splitext(F)[1] in ('.c'):
# FullName = os.path.join(Dirpath, F)
# EdkLogger.quiet("[POINTER]" + FullName)
# c.CheckPointerNullComparison(FullName)
for FullName in EccGlobalData . gCFileList :
EdkLogger . quiet ( "[POINTER]" + FullName )
c . CheckPointerNullComparison ( FullName )
2009-07-17 09:10:31 +00:00
# Include file checking
def IncludeFileCheck ( self ):
self . IncludeFileCheckIfndef ()
self . IncludeFileCheckData ()
self . IncludeFileCheckSameName ()
# Check whether having include files with same name
def IncludeFileCheckSameName ( self ):
if EccGlobalData . gConfig . IncludeFileCheckSameName == '1' or EccGlobalData . gConfig . IncludeFileCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking same header file name ..." )
SqlCommand = """select ID, FullPath from File
where Model = 1002 order by Name """
RecordDict = {}
RecordSet = EccGlobalData . gDb . TblFile . Exec ( SqlCommand )
for Record in RecordSet :
List = Record [ 1 ] . replace ( '/' , ' \\ ' ) . split ( ' \\ ' )
if len ( List ) >= 2 :
Key = List [ - 2 ] + ' \\ ' + List [ - 1 ]
else :
Key = List [ 0 ]
if Key not in RecordDict :
RecordDict [ Key ] = [ Record ]
else :
RecordDict [ Key ] . append ( Record )
for Key in RecordDict :
if len ( RecordDict [ Key ]) > 1 :
for Item in RecordDict [ Key ]:
2015-10-08 09:28:51 +00:00
Path = mws . relpath ( Item [ 1 ], EccGlobalData . gWorkspace )
2010-02-28 23:39:39 +00:00
if not EccGlobalData . gException . IsException ( ERROR_INCLUDE_FILE_CHECK_NAME , Path ):
2011-11-09 04:32:08 +00:00
EccGlobalData . gDb . TblReport . Insert ( ERROR_INCLUDE_FILE_CHECK_NAME , OtherMsg = "The file name for [ %s ] is duplicate" % Path , BelongsToTable = 'File' , BelongsToItem = Item [ 0 ])
2009-07-17 09:10:31 +00:00
# Check whether all include file contents is guarded by a #ifndef statement.
def IncludeFileCheckIfndef ( self ):
if EccGlobalData . gConfig . IncludeFileCheckIfndefStatement == '1' or EccGlobalData . gConfig . IncludeFileCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking header file ifndef ..." )
2010-09-06 01:58:00 +00:00
# for Dirpath, Dirnames, Filenames in self.WalkTree():
# for F in Filenames:
# if os.path.splitext(F)[1] in ('.h'):
# FullName = os.path.join(Dirpath, F)
# MsgList = c.CheckHeaderFileIfndef(FullName)
for FullName in EccGlobalData . gHFileList :
MsgList = c . CheckHeaderFileIfndef ( FullName )
2009-07-17 09:10:31 +00:00
# Check whether include files NOT contain code or define data variables
def IncludeFileCheckData ( self ):
if EccGlobalData . gConfig . IncludeFileCheckData == '1' or EccGlobalData . gConfig . IncludeFileCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking header file data ..." )
2018-10-16 16:21:48 +08:00
# Get all typedef functions
gAllTypedefFun = []
for IdentifierTable in EccGlobalData . gIdentifierTableList :
SqlCommand = """select Name from %s
where Model = %s """ % ( IdentifierTable , MODEL_IDENTIFIER_TYPEDEF )
RecordSet = EccGlobalData . gDb . TblFile . Exec ( SqlCommand )
for Record in RecordSet :
if Record [ 0 ] . startswith ( '(' ):
gAllTypedefFun . append ( Record [ 0 ])
2010-09-06 01:58:00 +00:00
# for Dirpath, Dirnames, Filenames in self.WalkTree():
# for F in Filenames:
# if os.path.splitext(F)[1] in ('.h'):
# FullName = os.path.join(Dirpath, F)
# MsgList = c.CheckHeaderFileData(FullName)
for FullName in EccGlobalData . gHFileList :
2018-10-16 16:21:48 +08:00
MsgList = c . CheckHeaderFileData ( FullName , gAllTypedefFun )
2009-07-17 09:10:31 +00:00
# Doxygen document checking
def DoxygenCheck ( self ):
self . DoxygenCheckFileHeader ()
self . DoxygenCheckFunctionHeader ()
self . DoxygenCheckCommentDescription ()
self . DoxygenCheckCommentFormat ()
self . DoxygenCheckCommand ()
# Check whether the file headers are followed Doxygen special documentation blocks in section 2.3.5
def DoxygenCheckFileHeader ( self ):
if EccGlobalData . gConfig . DoxygenCheckFileHeader == '1' or EccGlobalData . gConfig . DoxygenCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking Doxygen file header ..." )
for Dirpath , Dirnames , Filenames in self . WalkTree ():
for F in Filenames :
2010-05-18 05:04:32 +00:00
Ext = os . path . splitext ( F )[ 1 ]
if Ext in ( '.h' , '.c' ):
2009-07-17 09:10:31 +00:00
FullName = os . path . join ( Dirpath , F )
MsgList = c . CheckFileHeaderDoxygenComments ( FullName )
2010-05-18 05:04:32 +00:00
elif Ext in ( '.inf' , '.dec' , '.dsc' , '.fdf' ):
FullName = os . path . join ( Dirpath , F )
2010-09-06 01:58:00 +00:00
op = open ( FullName ) . readlines ()
2011-12-07 06:19:28 +00:00
FileLinesList = op
LineNo = 0
2018-07-05 17:40:04 +08:00
CurrentSection = MODEL_UNKNOWN
2011-12-07 06:19:28 +00:00
HeaderSectionLines = []
2018-07-05 17:40:04 +08:00
HeaderCommentStart = False
2011-12-07 06:19:28 +00:00
HeaderCommentEnd = False
2018-07-05 17:40:04 +08:00
2011-12-07 06:19:28 +00:00
for Line in FileLinesList :
LineNo = LineNo + 1
Line = Line . strip ()
if ( LineNo < len ( FileLinesList ) - 1 ):
NextLine = FileLinesList [ LineNo ] . strip ()
2018-07-05 17:40:04 +08:00
2011-12-07 06:19:28 +00:00
#
# blank line
#
if ( Line == '' or not Line ) and LineNo == len ( FileLinesList ):
LastSectionFalg = True
#
# check whether file header comment section started
#
if Line . startswith ( '#' ) and \
( Line . find ( '@file' ) > - 1 ) and \
not HeaderCommentStart :
if CurrentSection != MODEL_UNKNOWN :
SqlStatement = """ select ID from File where FullPath like ' %s '""" % FullName
ResultSet = EccGlobalData . gDb . TblFile . Exec ( SqlStatement )
for Result in ResultSet :
Msg = 'INF/DEC/DSC/FDF file header comment should begin with ""## @file"" or ""# @file""at the very top file'
EccGlobalData . gDb . TblReport . Insert ( ERROR_DOXYGEN_CHECK_FILE_HEADER , Msg , "File" , Result [ 0 ])
else :
CurrentSection = MODEL_IDENTIFIER_FILE_HEADER
#
# Append the first line to section lines.
#
HeaderSectionLines . append (( Line , LineNo ))
HeaderCommentStart = True
2018-07-05 17:40:04 +08:00
continue
2011-12-07 06:19:28 +00:00
#
# Collect Header content.
#
if ( Line . startswith ( '#' ) and CurrentSection == MODEL_IDENTIFIER_FILE_HEADER ) and \
HeaderCommentStart and not Line . startswith ( '##' ) and not \
HeaderCommentEnd and NextLine != '' :
HeaderSectionLines . append (( Line , LineNo ))
continue
#
# Header content end
#
if ( Line . startswith ( '##' ) or not Line . strip () . startswith ( "#" )) and HeaderCommentStart \
and not HeaderCommentEnd :
if Line . startswith ( '##' ):
HeaderCommentEnd = True
HeaderSectionLines . append (( Line , LineNo ))
ParseHeaderCommentSection ( HeaderSectionLines , FullName )
break
if HeaderCommentStart == False :
2010-05-18 05:04:32 +00:00
SqlStatement = """ select ID from File where FullPath like ' %s '""" % FullName
ResultSet = EccGlobalData . gDb . TblFile . Exec ( SqlStatement )
for Result in ResultSet :
2011-12-07 06:19:28 +00:00
Msg = 'INF/DEC/DSC/FDF file header comment should begin with ""## @file"" or ""# @file"" at the very top file'
2010-05-18 05:04:32 +00:00
EccGlobalData . gDb . TblReport . Insert ( ERROR_DOXYGEN_CHECK_FILE_HEADER , Msg , "File" , Result [ 0 ])
2011-12-07 06:19:28 +00:00
if HeaderCommentEnd == False :
SqlStatement = """ select ID from File where FullPath like ' %s '""" % FullName
ResultSet = EccGlobalData . gDb . TblFile . Exec ( SqlStatement )
for Result in ResultSet :
Msg = 'INF/DEC/DSC/FDF file header comment should end with ""##"" at the end of file header comment block'
# Check whether File header Comment End with '##'
if EccGlobalData . gConfig . HeaderCheckFileCommentEnd == '1' or EccGlobalData . gConfig . HeaderCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EccGlobalData . gDb . TblReport . Insert ( ERROR_DOXYGEN_CHECK_FILE_HEADER , Msg , "File" , Result [ 0 ])
2010-09-06 01:58:00 +00:00
2018-07-05 17:40:04 +08:00
2009-07-17 09:10:31 +00:00
# Check whether the function headers are followed Doxygen special documentation blocks in section 2.3.5
def DoxygenCheckFunctionHeader ( self ):
if EccGlobalData . gConfig . DoxygenCheckFunctionHeader == '1' or EccGlobalData . gConfig . DoxygenCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking Doxygen function header ..." )
2010-09-06 01:58:00 +00:00
# for Dirpath, Dirnames, Filenames in self.WalkTree():
# for F in Filenames:
# if os.path.splitext(F)[1] in ('.h', '.c'):
# FullName = os.path.join(Dirpath, F)
# MsgList = c.CheckFuncHeaderDoxygenComments(FullName)
for FullName in EccGlobalData . gCFileList + EccGlobalData . gHFileList :
MsgList = c . CheckFuncHeaderDoxygenComments ( FullName )
2009-07-17 09:10:31 +00:00
# Check whether the first line of text in a comment block is a brief description of the element being documented.
# The brief description must end with a period.
def DoxygenCheckCommentDescription ( self ):
if EccGlobalData . gConfig . DoxygenCheckCommentDescription == '1' or EccGlobalData . gConfig . DoxygenCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
pass
# Check whether comment lines with '///< ... text ...' format, if it is used, it should be after the code section.
def DoxygenCheckCommentFormat ( self ):
if EccGlobalData . gConfig . DoxygenCheckCommentFormat == '1' or EccGlobalData . gConfig . DoxygenCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking Doxygen comment ///< ..." )
2010-09-06 01:58:00 +00:00
# for Dirpath, Dirnames, Filenames in self.WalkTree():
# for F in Filenames:
# if os.path.splitext(F)[1] in ('.h', '.c'):
# FullName = os.path.join(Dirpath, F)
# MsgList = c.CheckDoxygenTripleForwardSlash(FullName)
for FullName in EccGlobalData . gCFileList + EccGlobalData . gHFileList :
MsgList = c . CheckDoxygenTripleForwardSlash ( FullName )
2009-07-17 09:10:31 +00:00
# Check whether only Doxygen commands allowed to mark the code are @bug and @todo.
def DoxygenCheckCommand ( self ):
if EccGlobalData . gConfig . DoxygenCheckCommand == '1' or EccGlobalData . gConfig . DoxygenCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking Doxygen command ..." )
2010-09-06 01:58:00 +00:00
# for Dirpath, Dirnames, Filenames in self.WalkTree():
# for F in Filenames:
# if os.path.splitext(F)[1] in ('.h', '.c'):
# FullName = os.path.join(Dirpath, F)
# MsgList = c.CheckDoxygenCommand(FullName)
for FullName in EccGlobalData . gCFileList + EccGlobalData . gHFileList :
MsgList = c . CheckDoxygenCommand ( FullName )
2009-07-17 09:10:31 +00:00
# Meta-Data File Processing Checking
def MetaDataFileCheck ( self ):
self . MetaDataFileCheckPathName ()
self . MetaDataFileCheckGenerateFileList ()
self . MetaDataFileCheckLibraryInstance ()
self . MetaDataFileCheckLibraryInstanceDependent ()
self . MetaDataFileCheckLibraryInstanceOrder ()
self . MetaDataFileCheckLibraryNoUse ()
2015-06-25 08:01:59 +00:00
self . MetaDataFileCheckLibraryDefinedInDec ()
2009-07-17 09:10:31 +00:00
self . MetaDataFileCheckBinaryInfInFdf ()
self . MetaDataFileCheckPcdDuplicate ()
self . MetaDataFileCheckPcdFlash ()
self . MetaDataFileCheckPcdNoUse ()
self . MetaDataFileCheckGuidDuplicate ()
self . MetaDataFileCheckModuleFileNoUse ()
self . MetaDataFileCheckPcdType ()
2010-05-18 05:04:32 +00:00
self . MetaDataFileCheckModuleFileGuidDuplication ()
2014-08-25 01:16:34 +00:00
self . MetaDataFileCheckModuleFileGuidFormat ()
self . MetaDataFileCheckModuleFileProtocolFormat ()
self . MetaDataFileCheckModuleFilePpiFormat ()
self . MetaDataFileCheckModuleFilePcdFormat ()
2009-07-17 09:10:31 +00:00
# Check whether each file defined in meta-data exists
def MetaDataFileCheckPathName ( self ):
if EccGlobalData . gConfig . MetaDataFileCheckPathName == '1' or EccGlobalData . gConfig . MetaDataFileCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
# This item is covered when parsing Inf/Dec/Dsc files
pass
# Generate a list for all files defined in meta-data files
def MetaDataFileCheckGenerateFileList ( self ):
if EccGlobalData . gConfig . MetaDataFileCheckGenerateFileList == '1' or EccGlobalData . gConfig . MetaDataFileCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
# This item is covered when parsing Inf/Dec/Dsc files
pass
# Check whether all Library Instances defined for a given module (or dependent library instance) match the module's type.
# Each Library Instance must specify the Supported Module Types in its Inf file,
# and any module specifying the library instance must be one of the supported types.
def MetaDataFileCheckLibraryInstance ( self ):
if EccGlobalData . gConfig . MetaDataFileCheckLibraryInstance == '1' or EccGlobalData . gConfig . MetaDataFileCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking for library instance type issue ..." )
2011-12-07 06:19:28 +00:00
SqlCommand = """select A.ID, A.Value3, B.Value3 from Inf as A left join Inf as B
where A.Value2 = 'LIBRARY_CLASS' and A.Model = %s
and B.Value2 = 'MODULE_TYPE' and B.Model = %s and A.BelongsToFile = B.BelongsToFile
2009-07-17 09:10:31 +00:00
group by A.BelongsToFile""" % ( MODEL_META_DATA_HEADER , MODEL_META_DATA_HEADER )
RecordSet = EccGlobalData . gDb . TblInf . Exec ( SqlCommand )
LibraryClasses = {}
for Record in RecordSet :
List = Record [ 1 ] . split ( '|' , 1 )
SupModType = []
if len ( List ) == 1 :
2014-08-25 01:16:34 +00:00
SupModType = DT . SUP_MODULE_LIST_STRING . split ( DT . TAB_VALUE_SPLIT )
2009-07-17 09:10:31 +00:00
elif len ( List ) == 2 :
SupModType = List [ 1 ] . split ()
if List [ 0 ] not in LibraryClasses :
LibraryClasses [ List [ 0 ]] = SupModType
else :
for Item in SupModType :
if Item not in LibraryClasses [ List [ 0 ]]:
LibraryClasses [ List [ 0 ]] . append ( Item )
2018-04-27 00:57:53 +08:00
if Record [ 2 ] != DT . SUP_MODULE_BASE and Record [ 2 ] not in SupModType :
2011-11-09 04:32:08 +00:00
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 ])
2009-07-17 09:10:31 +00:00
2011-12-07 06:19:28 +00:00
SqlCommand = """select A.ID, A.Value1, B.Value3 from Inf as A left join Inf as B
where A.Model = %s and B.Value2 = ' %s ' and B.Model = %s
2009-07-17 09:10:31 +00:00
and B.BelongsToFile = A.BelongsToFile""" \
% ( MODEL_EFI_LIBRARY_CLASS , 'MODULE_TYPE' , MODEL_META_DATA_HEADER )
RecordSet = EccGlobalData . gDb . TblInf . Exec ( SqlCommand )
# Merge all LibraryClasses' supmodlist
RecordDict = {}
for Record in RecordSet :
if Record [ 1 ] not in RecordDict :
RecordDict [ Record [ 1 ]] = [ str ( Record [ 2 ])]
else :
if Record [ 2 ] not in RecordDict [ Record [ 1 ]]:
RecordDict [ Record [ 1 ]] . append ( Record [ 2 ])
for Record in RecordSet :
if Record [ 1 ] in LibraryClasses :
2018-04-27 00:57:53 +08:00
if Record [ 2 ] not in LibraryClasses [ Record [ 1 ]] and DT . SUP_MODULE_BASE not in RecordDict [ Record [ 1 ]]:
2009-07-17 09:10:31 +00:00
if not EccGlobalData . gException . IsException ( ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1 , Record [ 1 ]):
2011-11-09 04:32:08 +00:00
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 ])
2009-07-17 09:10:31 +00:00
else :
if not EccGlobalData . gException . IsException ( ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1 , Record [ 1 ]):
2011-11-09 04:32:08 +00:00
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 ])
2009-07-17 09:10:31 +00:00
# Check whether a Library Instance has been defined for all dependent library classes
def MetaDataFileCheckLibraryInstanceDependent ( self ):
if EccGlobalData . gConfig . MetaDataFileCheckLibraryInstanceDependent == '1' or EccGlobalData . gConfig . MetaDataFileCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking for library instance dependent issue ..." )
SqlCommand = """select ID, Value1, Value2 from Dsc where Model = %s """ % MODEL_EFI_LIBRARY_CLASS
LibraryClasses = EccGlobalData . gDb . TblDsc . Exec ( SqlCommand )
for LibraryClass in LibraryClasses :
2011-12-07 06:19:28 +00:00
if LibraryClass [ 1 ] . upper () == 'NULL' or LibraryClass [ 1 ] . startswith ( '!ifdef' ) or LibraryClass [ 1 ] . startswith ( '!ifndef' ) or LibraryClass [ 1 ] . endswith ( '!endif' ):
continue
else :
2015-10-08 09:28:51 +00:00
LibraryIns = os . path . normpath ( mws . join ( EccGlobalData . gWorkspace , LibraryClass [ 2 ]))
2015-12-14 08:08:21 +00:00
SkipDirString = '|' . join ( EccGlobalData . gConfig . SkipDirList )
p = re . compile ( r '.*[ \\ /](?: %s ^\S)[ \\ /]?.*' % SkipDirString )
if p . match ( os . path . split ( LibraryIns )[ 0 ] . upper ()):
continue
2011-12-07 06:19:28 +00:00
SqlCommand = """select Value3 from Inf where BelongsToFile =
2009-07-17 09:10:31 +00:00
(select ID from File where lower(FullPath) = lower(' %s '))
2018-04-27 00:57:57 +08:00
and Value2 = ' %s '""" % ( LibraryIns , DT . PLATFORM_COMPONENT_TYPE_LIBRARY_CLASS )
2009-07-17 09:10:31 +00:00
RecordSet = EccGlobalData . gDb . TblInf . Exec ( SqlCommand )
IsFound = False
for Record in RecordSet :
LibName = Record [ 0 ] . split ( '|' , 1 )[ 0 ]
if LibraryClass [ 1 ] == LibName :
IsFound = True
if not IsFound :
if not EccGlobalData . gException . IsException ( ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_DEPENDENT , LibraryClass [ 1 ]):
2011-11-09 04:32:08 +00:00
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 ])
2009-07-17 09:10:31 +00:00
# Check whether the Library Instances specified by the LibraryClasses sections are listed in order of dependencies
def MetaDataFileCheckLibraryInstanceOrder ( self ):
if EccGlobalData . gConfig . MetaDataFileCheckLibraryInstanceOrder == '1' or EccGlobalData . gConfig . MetaDataFileCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
# This checkpoint is not necessary for Ecc check
pass
# Check whether the unnecessary inclusion of library classes in the Inf file
2011-11-25 06:21:03 +00:00
# Check whether the unnecessary duplication of library classe names in the DSC file
2009-07-17 09:10:31 +00:00
def MetaDataFileCheckLibraryNoUse ( self ):
if EccGlobalData . gConfig . MetaDataFileCheckLibraryNoUse == '1' or EccGlobalData . gConfig . MetaDataFileCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking for library instance not used ..." )
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 )
RecordSet = EccGlobalData . gDb . TblInf . Exec ( SqlCommand )
for Record in RecordSet :
if not EccGlobalData . gException . IsException ( ERROR_META_DATA_FILE_CHECK_LIBRARY_NO_USE , Record [ 1 ]):
2011-11-09 04:32:08 +00:00
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 ])
2011-11-25 06:21:03 +00:00
SqlCommand = """
select A.ID, A.Value1, A.BelongsToFile, A.StartLine, B.StartLine from Dsc as A left join Dsc as B
2018-06-25 18:31:27 +08:00
where A.Model = %s and B.Model = %s and A.Scope1 = B.Scope1 and A.Scope2 = B.Scope2 and A.ID != B.ID
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""" \
2011-11-25 06:21:03 +00:00
% ( MODEL_EFI_LIBRARY_CLASS , MODEL_EFI_LIBRARY_CLASS )
RecordSet = EccGlobalData . gDb . TblDsc . Exec ( SqlCommand )
for Record in RecordSet :
2014-09-22 07:37:28 +00:00
if Record [ 3 ] and Record [ 4 ] and Record [ 3 ] != Record [ 4 ] and Record [ 1 ] != 'NULL' :
2011-11-25 06:21:03 +00:00
SqlCommand = """select FullPath from File where ID = %s """ % ( Record [ 2 ])
FilePathList = EccGlobalData . gDb . TblFile . Exec ( SqlCommand )
for FilePath in FilePathList :
if not EccGlobalData . gException . IsException ( ERROR_META_DATA_FILE_CHECK_LIBRARY_NAME_DUPLICATE , Record [ 1 ]):
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 ])
2018-07-05 17:40:04 +08:00
2015-06-25 08:01:59 +00:00
# Check the header file in Include\Library directory whether be defined in the package DEC file.
def MetaDataFileCheckLibraryDefinedInDec ( self ):
if EccGlobalData . gConfig . MetaDataFileCheckLibraryDefinedInDec == '1' or EccGlobalData . gConfig . MetaDataFileCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking for library instance whether be defined in the package dec file ..." )
SqlCommand = """
select A.Value1, A.StartLine, A.ID, B.Value1 from Inf as A left join Dec as B
on A.Model = B.Model and A.Value1 = B.Value1 where A.Model= %s
""" % MODEL_EFI_LIBRARY_CLASS
RecordSet = EccGlobalData . gDb . TblDsc . Exec ( SqlCommand )
for Record in RecordSet :
LibraryInInf , Line , ID , LibraryDec = Record
if not LibraryDec :
if not EccGlobalData . gException . IsException ( ERROR_META_DATA_FILE_CHECK_LIBRARY_NOT_DEFINED , LibraryInInf ):
EccGlobalData . gDb . TblReport . Insert ( ERROR_META_DATA_FILE_CHECK_LIBRARY_NOT_DEFINED , \
2018-07-05 17:40:04 +08:00
OtherMsg = "The Library Class [ %s ] in %s line is not defined in the associated package file." % ( LibraryInInf , Line ),
2015-06-25 08:01:59 +00:00
BelongsToTable = 'Inf' , BelongsToItem = ID )
2018-07-05 17:40:04 +08:00
2009-07-17 09:10:31 +00:00
# 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
def MetaDataFileCheckBinaryInfInFdf ( self ):
if EccGlobalData . gConfig . MetaDataFileCheckBinaryInfInFdf == '1' or EccGlobalData . gConfig . MetaDataFileCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking for non-binary modules defined in FDF files ..." )
SqlCommand = """select A.ID, A.Value1 from Fdf as A
where A.Model = %s
and A.Enabled > -1
and A.Value1 not in
(select B.Value1 from Dsc as B
where B.Model = %s
and B.Enabled > -1)""" % ( MODEL_META_DATA_COMPONENT , MODEL_META_DATA_COMPONENT )
RecordSet = EccGlobalData . gDb . TblFdf . Exec ( SqlCommand )
for Record in RecordSet :
FdfID = Record [ 0 ]
FilePath = Record [ 1 ]
2015-10-08 09:28:51 +00:00
FilePath = os . path . normpath ( mws . join ( EccGlobalData . gWorkspace , FilePath ))
2009-07-17 09:10:31 +00:00
SqlCommand = """select ID from Inf where Model = %s and BelongsToFile = (select ID from File where FullPath like ' %s ')
""" % ( MODEL_EFI_SOURCE_FILE , FilePath )
NewRecordSet = EccGlobalData . gDb . TblFile . Exec ( SqlCommand )
2011-11-09 04:32:08 +00:00
if NewRecordSet != []:
2009-07-17 09:10:31 +00:00
if not EccGlobalData . gException . IsException ( ERROR_META_DATA_FILE_CHECK_BINARY_INF_IN_FDF , FilePath ):
2011-11-09 04:32:08 +00:00
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 )
2009-07-17 09:10:31 +00:00
# Check whether a PCD is set in a Dsc file or the FDF file, but not in both.
def MetaDataFileCheckPcdDuplicate ( self ):
if EccGlobalData . gConfig . MetaDataFileCheckPcdDuplicate == '1' or EccGlobalData . gConfig . MetaDataFileCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking for duplicate PCDs defined in both DSC and FDF files ..." )
SqlCommand = """
2011-12-07 06:19:28 +00:00
select A.ID, A.Value1, A.Value2, A.BelongsToFile, B.ID, B.Value1, B.Value2, B.BelongsToFile from Dsc as A, Fdf as B
2009-07-17 09:10:31 +00:00
where A.Model >= %s and A.Model < %s
and B.Model >= %s and B.Model < %s
2011-12-07 06:19:28 +00:00
and A.Value1 = B.Value1
2009-07-17 09:10:31 +00:00
and A.Value2 = B.Value2
and A.Enabled > -1
and B.Enabled > -1
group by A.ID
2011-11-09 04:32:08 +00:00
""" % ( MODEL_PCD , MODEL_META_DATA_HEADER , MODEL_PCD , MODEL_META_DATA_HEADER )
2009-07-17 09:10:31 +00:00
RecordSet = EccGlobalData . gDb . TblDsc . Exec ( SqlCommand )
for Record in RecordSet :
2011-12-07 06:19:28 +00:00
SqlCommand1 = """select Name from File where ID = %s """ % Record [ 3 ]
SqlCommand2 = """select Name from File where ID = %s """ % Record [ 7 ]
2010-02-28 23:39:39 +00:00
DscFileName = os . path . splitext ( EccGlobalData . gDb . TblDsc . Exec ( SqlCommand1 )[ 0 ][ 0 ])[ 0 ]
FdfFileName = os . path . splitext ( EccGlobalData . gDb . TblDsc . Exec ( SqlCommand2 )[ 0 ][ 0 ])[ 0 ]
if DscFileName != FdfFileName :
continue
2011-12-07 06:19:28 +00:00
if not EccGlobalData . gException . IsException ( ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE , Record [ 1 ] + '.' + Record [ 2 ]):
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 ])
if not EccGlobalData . gException . IsException ( ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE , Record [ 5 ] + '.' + Record [ 6 ]):
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 ])
2009-07-17 09:10:31 +00:00
EdkLogger . quiet ( "Checking for duplicate PCDs defined in DEC files ..." )
SqlCommand = """
2011-12-07 06:19:28 +00:00
select A.ID, A.Value1, A.Value2, A.Model, B.Model from Dec as A left join Dec as B
2009-07-17 09:10:31 +00:00
where A.Model >= %s and A.Model < %s
and B.Model >= %s and B.Model < %s
2011-12-07 06:19:28 +00:00
and A.Value1 = B.Value1
2009-07-17 09:10:31 +00:00
and A.Value2 = B.Value2
2011-12-07 06:19:28 +00:00
and A.Scope1 = B.Scope1
2018-06-25 18:31:27 +08:00
and A.ID != B.ID
2011-12-07 06:19:28 +00:00
and A.Model = B.Model
2009-07-17 09:10:31 +00:00
and A.Enabled > -1
and B.Enabled > -1
and A.BelongsToFile = B.BelongsToFile
group by A.ID
2011-11-09 04:32:08 +00:00
""" % ( MODEL_PCD , MODEL_META_DATA_HEADER , MODEL_PCD , MODEL_META_DATA_HEADER )
2011-12-07 06:19:28 +00:00
RecordSet = EccGlobalData . gDb . TblDec . Exec ( SqlCommand )
2009-07-17 09:10:31 +00:00
for Record in RecordSet :
2011-12-07 06:19:28 +00:00
RecordCat = Record [ 1 ] + '.' + Record [ 2 ]
if not EccGlobalData . gException . IsException ( ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE , RecordCat ):
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 ])
2009-07-17 09:10:31 +00:00
# Check whether PCD settings in the FDF file can only be related to flash.
def MetaDataFileCheckPcdFlash ( self ):
if EccGlobalData . gConfig . MetaDataFileCheckPcdFlash == '1' or EccGlobalData . gConfig . MetaDataFileCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking only Flash related PCDs are used in FDF ..." )
SqlCommand = """
2011-12-07 06:19:28 +00:00
select ID, Value1, Value2, BelongsToFile from Fdf as A
2009-07-17 09:10:31 +00:00
where A.Model >= %s and Model < %s
and A.Enabled > -1
and A.Value2 not like ' %% Flash %% '
2011-11-09 04:32:08 +00:00
""" % ( MODEL_PCD , MODEL_META_DATA_HEADER )
2009-07-17 09:10:31 +00:00
RecordSet = EccGlobalData . gDb . TblFdf . Exec ( SqlCommand )
for Record in RecordSet :
2011-12-07 06:19:28 +00:00
if not EccGlobalData . gException . IsException ( ERROR_META_DATA_FILE_CHECK_PCD_FLASH , Record [ 1 ] + '.' + Record [ 2 ]):
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 ])
2009-07-17 09:10:31 +00:00
# Check whether PCDs used in Inf files but not specified in Dsc or FDF files
def MetaDataFileCheckPcdNoUse ( self ):
if EccGlobalData . gConfig . MetaDataFileCheckPcdNoUse == '1' or EccGlobalData . gConfig . MetaDataFileCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking for non-specified PCDs ..." )
SqlCommand = """
2011-12-07 06:19:28 +00:00
select ID, Value1, Value2, BelongsToFile from Inf as A
2009-07-17 09:10:31 +00:00
where A.Model >= %s and Model < %s
and A.Enabled > -1
2011-12-07 06:19:28 +00:00
and (A.Value1, A.Value2) not in
(select Value1, Value2 from Dsc as B
2009-07-17 09:10:31 +00:00
where B.Model >= %s and B.Model < %s
and B.Enabled > -1)
2011-12-07 06:19:28 +00:00
and (A.Value1, A.Value2) not in
(select Value1, Value2 from Fdf as C
2009-07-17 09:10:31 +00:00
where C.Model >= %s and C.Model < %s
and C.Enabled > -1)
2011-11-09 04:32:08 +00:00
""" % ( MODEL_PCD , MODEL_META_DATA_HEADER , MODEL_PCD , MODEL_META_DATA_HEADER , MODEL_PCD , MODEL_META_DATA_HEADER )
2009-07-17 09:10:31 +00:00
RecordSet = EccGlobalData . gDb . TblInf . Exec ( SqlCommand )
for Record in RecordSet :
2011-12-07 06:19:28 +00:00
if not EccGlobalData . gException . IsException ( ERROR_META_DATA_FILE_CHECK_PCD_NO_USE , Record [ 1 ] + '.' + Record [ 2 ]):
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 ])
2009-07-17 09:10:31 +00:00
# Check whether having duplicate guids defined for Guid/Protocol/Ppi
def MetaDataFileCheckGuidDuplicate ( self ):
if EccGlobalData . gConfig . MetaDataFileCheckGuidDuplicate == '1' or EccGlobalData . gConfig . MetaDataFileCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking for duplicate GUID/PPI/PROTOCOL ..." )
# Check Guid
self . CheckGuidProtocolPpi ( ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID , MODEL_EFI_GUID , EccGlobalData . gDb . TblDec )
self . CheckGuidProtocolPpi ( ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID , MODEL_EFI_GUID , EccGlobalData . gDb . TblDsc )
self . CheckGuidProtocolPpiValue ( ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID , MODEL_EFI_GUID )
# Check protocol
self . CheckGuidProtocolPpi ( ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL , MODEL_EFI_PROTOCOL , EccGlobalData . gDb . TblDec )
self . CheckGuidProtocolPpi ( ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL , MODEL_EFI_PROTOCOL , EccGlobalData . gDb . TblDsc )
self . CheckGuidProtocolPpiValue ( ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL , MODEL_EFI_PROTOCOL )
# Check ppi
self . CheckGuidProtocolPpi ( ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI , MODEL_EFI_PPI , EccGlobalData . gDb . TblDec )
self . CheckGuidProtocolPpi ( ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI , MODEL_EFI_PPI , EccGlobalData . gDb . TblDsc )
self . CheckGuidProtocolPpiValue ( ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI , MODEL_EFI_PPI )
# Check whether all files under module directory are described in INF files
def MetaDataFileCheckModuleFileNoUse ( self ):
if EccGlobalData . gConfig . MetaDataFileCheckModuleFileNoUse == '1' or EccGlobalData . gConfig . MetaDataFileCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking for no used module files ..." )
SqlCommand = """
2011-12-07 06:19:28 +00:00
select upper(Path) from File where ID in (select BelongsToFile from Inf where BelongsToFile != -1)
2009-07-17 09:10:31 +00:00
"""
InfPathSet = EccGlobalData . gDb . TblInf . Exec ( SqlCommand )
InfPathList = []
for Item in InfPathSet :
if Item [ 0 ] not in InfPathList :
InfPathList . append ( Item [ 0 ])
SqlCommand = """
select ID, Path, FullPath from File where upper(FullPath) not in
2020-09-01 18:23:15 +08:00
(select upper(A.Path) || ' %s ' || upper(B.Value1) from File as A, INF as B
2009-07-17 09:10:31 +00:00
where A.ID in (select BelongsToFile from INF where Model = %s group by BelongsToFile) and
B.BelongsToFile = A.ID and B.Model = %s )
and (Model = %s or Model = %s )
2020-09-01 18:23:15 +08:00
""" % ( os . sep , MODEL_EFI_SOURCE_FILE , MODEL_EFI_SOURCE_FILE , MODEL_FILE_C , MODEL_FILE_H )
2009-07-17 09:10:31 +00:00
RecordSet = EccGlobalData . gDb . TblInf . Exec ( SqlCommand )
for Record in RecordSet :
Path = Record [ 1 ]
2024-09-18 16:40:08 +01:00
Path = Path . upper () . replace ( r '\X64' , '' ) . replace ( r '\IA32' , '' ) . replace ( r '\EBC' , '' ) . replace ( r '\IPF' , '' ) . replace ( r '\ARM' , '' )
2009-07-17 09:10:31 +00:00
if Path in InfPathList :
if not EccGlobalData . gException . IsException ( ERROR_META_DATA_FILE_CHECK_MODULE_FILE_NO_USE , Record [ 2 ]):
2011-11-09 04:32:08 +00:00
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 ])
2009-07-17 09:10:31 +00:00
# Check whether the PCD is correctly used in C function via its type
def MetaDataFileCheckPcdType ( self ):
if EccGlobalData . gConfig . MetaDataFileCheckPcdType == '1' or EccGlobalData . gConfig . MetaDataFileCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking for pcd type in c code function usage ..." )
SqlCommand = """
2011-12-07 06:19:28 +00:00
select ID, Model, Value1, Value2, BelongsToFile from INF where Model > %s and Model < %s
2009-07-17 09:10:31 +00:00
""" % ( MODEL_PCD , MODEL_META_DATA_HEADER )
PcdSet = EccGlobalData . gDb . TblInf . Exec ( SqlCommand )
for Pcd in PcdSet :
Model = Pcd [ 1 ]
PcdName = Pcd [ 2 ]
2011-12-07 06:19:28 +00:00
if Pcd [ 3 ]:
PcdName = Pcd [ 3 ]
BelongsToFile = Pcd [ 4 ]
2009-07-17 09:10:31 +00:00
SqlCommand = """
select ID from File where FullPath in
2020-09-01 18:23:15 +08:00
(select B.Path || ' %s ' || A.Value1 from INF as A, File as B where A.Model = %s and A.BelongsToFile = %s
2010-09-06 01:58:00 +00:00
and B.ID = %s and (B.Model = %s or B.Model = %s ))
2020-09-01 18:23:15 +08:00
""" % ( os . sep , MODEL_EFI_SOURCE_FILE , BelongsToFile , BelongsToFile , MODEL_FILE_C , MODEL_FILE_H )
2009-07-17 09:10:31 +00:00
TableSet = EccGlobalData . gDb . TblFile . Exec ( SqlCommand )
for Tbl in TableSet :
TblName = 'Identifier' + str ( Tbl [ 0 ])
SqlCommand = """
2010-02-28 23:39:39 +00:00
select Name, ID from %s where value like ' %s ' and Model = %s
2009-07-17 09:10:31 +00:00
""" % ( TblName , PcdName , MODEL_IDENTIFIER_FUNCTION_CALLING )
RecordSet = EccGlobalData . gDb . TblInf . Exec ( SqlCommand )
TblNumber = TblName . replace ( 'Identifier' , '' )
for Record in RecordSet :
FunName = Record [ 0 ]
if not EccGlobalData . gException . IsException ( ERROR_META_DATA_FILE_CHECK_PCD_TYPE , FunName ):
if Model in [ MODEL_PCD_FIXED_AT_BUILD ] and not FunName . startswith ( 'FixedPcdGet' ):
2011-11-09 04:32:08 +00:00
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 ])
2009-07-17 09:10:31 +00:00
if Model in [ MODEL_PCD_FEATURE_FLAG ] and ( not FunName . startswith ( 'FeaturePcdGet' ) and not FunName . startswith ( 'FeaturePcdSet' )):
2011-11-09 04:32:08 +00:00
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 ])
2009-07-17 09:10:31 +00:00
if Model in [ MODEL_PCD_PATCHABLE_IN_MODULE ] and ( not FunName . startswith ( 'PatchablePcdGet' ) and not FunName . startswith ( 'PatchablePcdSet' )):
2011-11-09 04:32:08 +00:00
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 ])
2009-07-17 09:10:31 +00:00
#ERROR_META_DATA_FILE_CHECK_PCD_TYPE
pass
2010-05-18 05:04:32 +00:00
# Internal worker function to get the INF workspace relative path from FileID
def GetInfFilePathFromID ( self , FileID ):
Table = EccGlobalData . gDb . TblFile
SqlCommand = """select A.FullPath from %s as A where A.ID = %s """ % ( Table . Table , FileID )
RecordSet = Table . Exec ( SqlCommand )
Path = ""
for Record in RecordSet :
2015-10-08 09:28:51 +00:00
Path = mws . relpath ( Record [ 0 ], EccGlobalData . gWorkspace )
2010-05-18 05:04:32 +00:00
return Path
2010-09-06 01:58:00 +00:00
2010-05-18 05:04:32 +00:00
# Check whether two module INFs under one workspace has the same FILE_GUID value
def MetaDataFileCheckModuleFileGuidDuplication ( self ):
if EccGlobalData . gConfig . MetaDataFileCheckModuleFileGuidDuplication == '1' or EccGlobalData . gConfig . MetaDataFileCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
EdkLogger . quiet ( "Checking for pcd type in c code function usage ..." )
Table = EccGlobalData . gDb . TblInf
SqlCommand = """
2011-12-07 06:19:28 +00:00
select A.ID, A.Value3, A.BelongsToFile, B.BelongsToFile from %s as A, %s as B
where A.Value2 = 'FILE_GUID' and B.Value2 = 'FILE_GUID' and
2018-06-25 18:31:27 +08:00
A.Value3 = B.Value3 and A.ID != B.ID group by A.ID
2010-05-18 05:04:32 +00:00
""" % ( Table . Table , Table . Table )
RecordSet = Table . Exec ( SqlCommand )
for Record in RecordSet :
InfPath1 = self . GetInfFilePathFromID ( Record [ 2 ])
InfPath2 = self . GetInfFilePathFromID ( Record [ 3 ])
if InfPath1 and InfPath2 :
if not EccGlobalData . gException . IsException ( ERROR_META_DATA_FILE_CHECK_MODULE_FILE_GUID_DUPLICATION , InfPath1 ):
Msg = "The FILE_GUID of INF file [ %s ] is duplicated with that of %s " % ( InfPath1 , InfPath2 )
2011-11-09 04:32:08 +00:00
EccGlobalData . gDb . TblReport . Insert ( ERROR_META_DATA_FILE_CHECK_MODULE_FILE_GUID_DUPLICATION , OtherMsg = Msg , BelongsToTable = Table . Table , BelongsToItem = Record [ 0 ])
2010-09-06 01:58:00 +00:00
2010-05-18 05:04:32 +00:00
2014-08-25 01:16:34 +00:00
# Check Guid Format in module INF
def MetaDataFileCheckModuleFileGuidFormat ( self ):
2017-04-10 10:57:18 +08:00
if EccGlobalData . gConfig . MetaDataFileCheckModuleFileGuidFormat == '1' or EccGlobalData . gConfig . MetaDataFileCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
2014-08-25 01:16:34 +00:00
EdkLogger . quiet ( "Check Guid Format in module INF ..." )
Table = EccGlobalData . gDb . TblInf
SqlCommand = """
select ID, Value1, Usage, BelongsToFile from %s where Model = %s group by ID
""" % ( Table . Table , MODEL_EFI_GUID )
RecordSet = Table . Exec ( SqlCommand )
for Record in RecordSet :
Value1 = Record [ 1 ]
Value2 = Record [ 2 ]
GuidCommentList = []
InfPath = self . GetInfFilePathFromID ( Record [ 3 ])
Msg = "The GUID format of %s in INF file [ %s ] does not follow rules" % ( Value1 , InfPath )
if Value2 . startswith ( DT . TAB_SPECIAL_COMMENT ):
GuidCommentList = Value2 [ 2 :] . split ( DT . TAB_SPECIAL_COMMENT )
if GuidCommentList [ 0 ] . strip () . startswith ( DT . TAB_INF_USAGE_UNDEFINED ):
continue
elif len ( GuidCommentList ) > 1 :
if not GuidCommentList [ 0 ] . strip () . startswith (( DT . TAB_INF_USAGE_PRO ,
DT . TAB_INF_USAGE_SOME_PRO ,
DT . TAB_INF_USAGE_CON ,
DT . TAB_INF_USAGE_SOME_CON )):
EccGlobalData . gDb . TblReport . Insert ( ERROR_META_DATA_FILE_CHECK_FORMAT_GUID , OtherMsg = Msg , BelongsToTable = Table . Table , BelongsToItem = Record [ 0 ])
if not ( GuidCommentList [ 1 ] . strip ()) . startswith ( DT . TAB_INF_GUIDTYPE_VAR ) and \
not GuidCommentList [ 1 ] . strip () . startswith (( DT . TAB_INF_GUIDTYPE_EVENT ,
DT . TAB_INF_GUIDTYPE_HII ,
DT . TAB_INF_GUIDTYPE_FILE ,
DT . TAB_INF_GUIDTYPE_HOB ,
DT . TAB_INF_GUIDTYPE_FV ,
DT . TAB_INF_GUIDTYPE_ST ,
DT . TAB_INF_GUIDTYPE_TSG ,
DT . TAB_INF_GUIDTYPE_GUID ,
DT . TAB_INF_GUIDTYPE_PROTOCOL ,
DT . TAB_INF_GUIDTYPE_PPI ,
DT . TAB_INF_USAGE_UNDEFINED )):
EccGlobalData . gDb . TblReport . Insert ( ERROR_META_DATA_FILE_CHECK_FORMAT_GUID , OtherMsg = Msg , BelongsToTable = Table . Table , BelongsToItem = Record [ 0 ])
else :
EccGlobalData . gDb . TblReport . Insert ( ERROR_META_DATA_FILE_CHECK_FORMAT_GUID , OtherMsg = Msg , BelongsToTable = Table . Table , BelongsToItem = Record [ 0 ])
else :
EccGlobalData . gDb . TblReport . Insert ( ERROR_META_DATA_FILE_CHECK_FORMAT_GUID , OtherMsg = Msg , BelongsToTable = Table . Table , BelongsToItem = Record [ 0 ])
# Check Protocol Format in module INF
def MetaDataFileCheckModuleFileProtocolFormat ( self ):
2017-04-10 10:57:18 +08:00
if EccGlobalData . gConfig . MetaDataFileCheckModuleFileProtocolFormat == '1' or EccGlobalData . gConfig . MetaDataFileCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
2014-08-25 01:16:34 +00:00
EdkLogger . quiet ( "Check Protocol Format in module INF ..." )
Table = EccGlobalData . gDb . TblInf
SqlCommand = """
select ID, Value1, Usage, BelongsToFile from %s where Model = %s group by ID
""" % ( Table . Table , MODEL_EFI_PROTOCOL )
RecordSet = Table . Exec ( SqlCommand )
for Record in RecordSet :
Value1 = Record [ 1 ]
Value2 = Record [ 2 ]
GuidCommentList = []
InfPath = self . GetInfFilePathFromID ( Record [ 3 ])
Msg = "The Protocol format of %s in INF file [ %s ] does not follow rules" % ( Value1 , InfPath )
if Value2 . startswith ( DT . TAB_SPECIAL_COMMENT ):
GuidCommentList = Value2 [ 2 :] . split ( DT . TAB_SPECIAL_COMMENT )
if len ( GuidCommentList ) >= 1 :
if not GuidCommentList [ 0 ] . strip () . startswith (( DT . TAB_INF_USAGE_PRO ,
DT . TAB_INF_USAGE_SOME_PRO ,
DT . TAB_INF_USAGE_CON ,
DT . TAB_INF_USAGE_SOME_CON ,
DT . TAB_INF_USAGE_NOTIFY ,
DT . TAB_INF_USAGE_TO_START ,
DT . TAB_INF_USAGE_BY_START ,
DT . TAB_INF_USAGE_UNDEFINED )):
EccGlobalData . gDb . TblReport . Insert ( ERROR_META_DATA_FILE_CHECK_FORMAT_PROTOCOL , OtherMsg = Msg , BelongsToTable = Table . Table , BelongsToItem = Record [ 0 ])
else :
EccGlobalData . gDb . TblReport . Insert ( ERROR_META_DATA_FILE_CHECK_FORMAT_PROTOCOL , OtherMsg = Msg , BelongsToTable = Table . Table , BelongsToItem = Record [ 0 ])
# Check Ppi Format in module INF
def MetaDataFileCheckModuleFilePpiFormat ( self ):
2017-04-10 10:57:18 +08:00
if EccGlobalData . gConfig . MetaDataFileCheckModuleFilePpiFormat == '1' or EccGlobalData . gConfig . MetaDataFileCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
2014-08-25 01:16:34 +00:00
EdkLogger . quiet ( "Check Ppi Format in module INF ..." )
Table = EccGlobalData . gDb . TblInf
SqlCommand = """
select ID, Value1, Usage, BelongsToFile from %s where Model = %s group by ID
""" % ( Table . Table , MODEL_EFI_PPI )
RecordSet = Table . Exec ( SqlCommand )
for Record in RecordSet :
Value1 = Record [ 1 ]
Value2 = Record [ 2 ]
GuidCommentList = []
InfPath = self . GetInfFilePathFromID ( Record [ 3 ])
Msg = "The Ppi format of %s in INF file [ %s ] does not follow rules" % ( Value1 , InfPath )
if Value2 . startswith ( DT . TAB_SPECIAL_COMMENT ):
GuidCommentList = Value2 [ 2 :] . split ( DT . TAB_SPECIAL_COMMENT )
if len ( GuidCommentList ) >= 1 :
if not GuidCommentList [ 0 ] . strip () . startswith (( DT . TAB_INF_USAGE_PRO ,
DT . TAB_INF_USAGE_SOME_PRO ,
DT . TAB_INF_USAGE_CON ,
DT . TAB_INF_USAGE_SOME_CON ,
DT . TAB_INF_USAGE_NOTIFY ,
DT . TAB_INF_USAGE_UNDEFINED )):
EccGlobalData . gDb . TblReport . Insert ( ERROR_META_DATA_FILE_CHECK_FORMAT_PPI , OtherMsg = Msg , BelongsToTable = Table . Table , BelongsToItem = Record [ 0 ])
else :
EccGlobalData . gDb . TblReport . Insert ( ERROR_META_DATA_FILE_CHECK_FORMAT_PPI , OtherMsg = Msg , BelongsToTable = Table . Table , BelongsToItem = Record [ 0 ])
# Check Pcd Format in module INF
def MetaDataFileCheckModuleFilePcdFormat ( self ):
2017-04-10 10:57:18 +08:00
if EccGlobalData . gConfig . MetaDataFileCheckModuleFilePcdFormat == '1' or EccGlobalData . gConfig . MetaDataFileCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
2014-08-25 01:16:34 +00:00
EdkLogger . quiet ( "Check Pcd Format in module INF ..." )
Table = EccGlobalData . gDb . TblInf
SqlCommand = """
select ID, Model, Value1, Value2, Usage, BelongsToFile from %s where Model >= %s and Model < %s group by ID
""" % ( Table . Table , MODEL_PCD , MODEL_META_DATA_HEADER )
RecordSet = Table . Exec ( SqlCommand )
for Record in RecordSet :
Model = Record [ 1 ]
PcdName = Record [ 2 ] + '.' + Record [ 3 ]
Usage = Record [ 4 ]
PcdCommentList = []
InfPath = self . GetInfFilePathFromID ( Record [ 5 ])
Msg = "The Pcd format of %s in INF file [ %s ] does not follow rules" % ( PcdName , InfPath )
if Usage . startswith ( DT . TAB_SPECIAL_COMMENT ):
PcdCommentList = Usage [ 2 :] . split ( DT . TAB_SPECIAL_COMMENT )
if len ( PcdCommentList ) >= 1 :
if Model in [ MODEL_PCD_FIXED_AT_BUILD , MODEL_PCD_FEATURE_FLAG ] \
and not PcdCommentList [ 0 ] . strip () . startswith (( DT . TAB_INF_USAGE_SOME_PRO ,
DT . TAB_INF_USAGE_CON ,
DT . TAB_INF_USAGE_UNDEFINED )):
EccGlobalData . gDb . TblReport . Insert ( ERROR_META_DATA_FILE_CHECK_FORMAT_PCD , OtherMsg = Msg , BelongsToTable = Table . Table , BelongsToItem = Record [ 0 ])
if Model in [ MODEL_PCD_PATCHABLE_IN_MODULE , MODEL_PCD_DYNAMIC , MODEL_PCD_DYNAMIC_EX ] \
and not PcdCommentList [ 0 ] . strip () . startswith (( DT . TAB_INF_USAGE_PRO ,
DT . TAB_INF_USAGE_SOME_PRO ,
DT . TAB_INF_USAGE_CON ,
DT . TAB_INF_USAGE_SOME_CON ,
DT . TAB_INF_USAGE_UNDEFINED )):
EccGlobalData . gDb . TblReport . Insert ( ERROR_META_DATA_FILE_CHECK_FORMAT_PCD , OtherMsg = Msg , BelongsToTable = Table . Table , BelongsToItem = Record [ 0 ])
else :
EccGlobalData . gDb . TblReport . Insert ( ERROR_META_DATA_FILE_CHECK_FORMAT_PCD , OtherMsg = Msg , BelongsToTable = Table . Table , BelongsToItem = Record [ 0 ])
2009-07-17 09:10:31 +00:00
# Check whether these is duplicate Guid/Ppi/Protocol name
def CheckGuidProtocolPpi ( self , ErrorID , Model , Table ):
Name = ''
if Model == MODEL_EFI_GUID :
Name = 'guid'
if Model == MODEL_EFI_PROTOCOL :
Name = 'protocol'
if Model == MODEL_EFI_PPI :
Name = 'ppi'
SqlCommand = """
select A.ID, A.Value1 from %s as A, %s as B
where A.Model = %s and B.Model = %s
2018-06-25 18:31:27 +08:00
and A.Value1 like B.Value1 and A.ID != B.ID
2011-12-07 06:19:28 +00:00
and A.Scope1 = B.Scope1
2009-07-17 09:10:31 +00:00
and A.Enabled > -1
and B.Enabled > -1
group by A.ID
""" % ( Table . Table , Table . Table , Model , Model )
RecordSet = Table . Exec ( SqlCommand )
for Record in RecordSet :
if not EccGlobalData . gException . IsException ( ErrorID , Record [ 1 ]):
2011-11-09 04:32:08 +00:00
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 ])
2009-07-17 09:10:31 +00:00
# Check whether these is duplicate Guid/Ppi/Protocol value
def CheckGuidProtocolPpiValue ( self , ErrorID , Model ):
Name = ''
Table = EccGlobalData . gDb . TblDec
if Model == MODEL_EFI_GUID :
Name = 'guid'
if Model == MODEL_EFI_PROTOCOL :
Name = 'protocol'
if Model == MODEL_EFI_PPI :
Name = 'ppi'
SqlCommand = """
2011-12-07 06:19:28 +00:00
select A.ID, A.Value1, A.Value2 from %s as A, %s as B
2009-07-17 09:10:31 +00:00
where A.Model = %s and B.Model = %s
2018-06-25 18:31:27 +08:00
and A.Value2 like B.Value2 and A.ID != B.ID
and A.Scope1 = B.Scope1 and A.Value1 != B.Value1
2009-07-17 09:10:31 +00:00
group by A.ID
""" % ( Table . Table , Table . Table , Model , Model )
RecordSet = Table . Exec ( SqlCommand )
2018-07-05 17:40:04 +08:00
for Record in RecordSet :
2015-06-25 08:08:55 +00:00
if not EccGlobalData . gException . IsException ( ErrorID , Record [ 2 ]):
2011-12-07 06:19:28 +00:00
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 ])
2009-07-17 09:10:31 +00:00
# Naming Convention Check
def NamingConventionCheck ( self ):
2010-02-28 23:39:39 +00:00
if EccGlobalData . gConfig . NamingConventionCheckDefineStatement == '1' \
or EccGlobalData . gConfig . NamingConventionCheckTypedefStatement == '1' \
or EccGlobalData . gConfig . NamingConventionCheckIfndefStatement == '1' \
or EccGlobalData . gConfig . NamingConventionCheckVariableName == '1' \
or EccGlobalData . gConfig . NamingConventionCheckSingleCharacterVariable == '1' \
or EccGlobalData . gConfig . NamingConventionCheckAll == '1' \
or EccGlobalData . gConfig . CheckAll == '1' :
for Dirpath , Dirnames , Filenames in self . WalkTree ():
for F in Filenames :
if os . path . splitext ( F )[ 1 ] in ( '.h' , '.c' ):
FullName = os . path . join ( Dirpath , F )
Id = c . GetTableID ( FullName )
if Id < 0 :
continue
FileTable = 'Identifier' + str ( Id )
self . NamingConventionCheckDefineStatement ( FileTable )
self . NamingConventionCheckTypedefStatement ( FileTable )
self . NamingConventionCheckVariableName ( FileTable )
self . NamingConventionCheckSingleCharacterVariable ( FileTable )
2017-04-10 10:57:18 +08:00
if os . path . splitext ( F )[ 1 ] in ( '.h' ):
self . NamingConventionCheckIfndefStatement ( FileTable )
2009-07-17 09:10:31 +00:00
self . NamingConventionCheckPathName ()
self . NamingConventionCheckFunctionName ()
2010-02-28 23:39:39 +00:00
2009-07-17 09:10:31 +00:00
# Check whether only capital letters are used for #define declarations
def NamingConventionCheckDefineStatement ( self , FileTable ):
if EccGlobalData . gConfig . NamingConventionCheckDefineStatement == '1' or EccGlobalData . gConfig . NamingConventionCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
2019-02-06 15:44:39 +08:00
EdkLogger . quiet ( "Checking naming convention of #define statement ..." )
2010-02-28 23:39:39 +00:00
2011-11-09 04:32:08 +00:00
SqlCommand = """select ID, Value from %s where Model = %s """ % ( FileTable , MODEL_IDENTIFIER_MACRO_DEFINE )
2009-07-17 09:10:31 +00:00
RecordSet = EccGlobalData . gDb . TblFile . Exec ( SqlCommand )
for Record in RecordSet :
Name = Record [ 1 ] . strip () . split ()[ 1 ]
if Name . find ( '(' ) != - 1 :
Name = Name [ 0 : Name . find ( '(' )]
if Name . upper () != Name :
if not EccGlobalData . gException . IsException ( ERROR_NAMING_CONVENTION_CHECK_DEFINE_STATEMENT , Name ):
2011-11-09 04:32:08 +00:00
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 ])
2009-07-17 09:10:31 +00:00
# Check whether only capital letters are used for typedef declarations
def NamingConventionCheckTypedefStatement ( self , FileTable ):
if EccGlobalData . gConfig . NamingConventionCheckTypedefStatement == '1' or EccGlobalData . gConfig . NamingConventionCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
2019-02-06 15:44:39 +08:00
EdkLogger . quiet ( "Checking naming convention of #typedef statement ..." )
2010-02-28 23:39:39 +00:00
2011-11-09 04:32:08 +00:00
SqlCommand = """select ID, Name from %s where Model = %s """ % ( FileTable , MODEL_IDENTIFIER_TYPEDEF )
2009-07-17 09:10:31 +00:00
RecordSet = EccGlobalData . gDb . TblFile . Exec ( SqlCommand )
for Record in RecordSet :
Name = Record [ 1 ] . strip ()
2018-03-27 04:25:43 +08:00
if Name != '' and Name is not None :
2009-07-17 09:10:31 +00:00
if Name [ 0 ] == '(' :
Name = Name [ 1 : Name . find ( ')' )]
if Name . find ( '(' ) > - 1 :
Name = Name [ Name . find ( '(' ) + 1 : Name . find ( ')' )]
Name = Name . replace ( 'WINAPI' , '' )
Name = Name . replace ( '*' , '' ) . strip ()
if Name . upper () != Name :
if not EccGlobalData . gException . IsException ( ERROR_NAMING_CONVENTION_CHECK_TYPEDEF_STATEMENT , Name ):
2011-11-09 04:32:08 +00:00
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 ])
2009-07-17 09:10:31 +00:00
# Check whether the #ifndef at the start of an include file uses both prefix and postfix underscore characters, '_'.
def NamingConventionCheckIfndefStatement ( self , FileTable ):
2017-04-10 10:57:18 +08:00
if EccGlobalData . gConfig . NamingConventionCheckIfndefStatement == '1' or EccGlobalData . gConfig . NamingConventionCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
2019-02-06 15:44:39 +08:00
EdkLogger . quiet ( "Checking naming convention of #ifndef statement ..." )
2010-02-28 23:39:39 +00:00
2011-11-09 04:32:08 +00:00
SqlCommand = """select ID, Value from %s where Model = %s """ % ( FileTable , MODEL_IDENTIFIER_MACRO_IFNDEF )
2009-07-17 09:10:31 +00:00
RecordSet = EccGlobalData . gDb . TblFile . Exec ( SqlCommand )
2021-03-17 17:59:37 +08:00
if RecordSet :
# Only check the first ifndef statement of the file
FirstDefine = sorted ( RecordSet , key = lambda Record : Record [ 0 ])[ 0 ]
Name = FirstDefine [ 1 ] . replace ( '#ifndef' , '' ) . strip ()
2021-02-16 17:29:07 +08:00
if Name [ 0 ] == '_' or Name [ - 1 ] != '_' or Name [ - 2 ] == '_' :
2009-07-17 09:10:31 +00:00
if not EccGlobalData . gException . IsException ( ERROR_NAMING_CONVENTION_CHECK_IFNDEF_STATEMENT , Name ):
2021-03-17 17:59:37 +08:00
EccGlobalData . gDb . TblReport . Insert ( ERROR_NAMING_CONVENTION_CHECK_IFNDEF_STATEMENT , OtherMsg = "The #ifndef name [ %s ] does not follow the rules" % ( Name ), BelongsToTable = FileTable , BelongsToItem = FirstDefine [ 0 ])
2009-07-17 09:10:31 +00:00
# Rule for path name, variable name and function name
# 1. First character should be upper case
# 2. Existing lower case in a word
# 3. No space existence
# Check whether the path name followed the rule
def NamingConventionCheckPathName ( self ):
if EccGlobalData . gConfig . NamingConventionCheckPathName == '1' or EccGlobalData . gConfig . NamingConventionCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
2019-02-06 15:44:39 +08:00
EdkLogger . quiet ( "Checking naming convention of file path name ..." )
2009-07-17 09:10:31 +00:00
Pattern = re . compile ( r '^[A-Z]+\S*[a-z]\S*$' )
SqlCommand = """select ID, Name from File"""
RecordSet = EccGlobalData . gDb . TblFile . Exec ( SqlCommand )
for Record in RecordSet :
if not Pattern . match ( Record [ 1 ]):
if not EccGlobalData . gException . IsException ( ERROR_NAMING_CONVENTION_CHECK_PATH_NAME , Record [ 1 ]):
2011-11-09 04:32:08 +00:00
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 ])
2009-07-17 09:10:31 +00:00
# Rule for path name, variable name and function name
# 1. First character should be upper case
# 2. Existing lower case in a word
# 3. No space existence
# 4. Global variable name must start with a 'g'
# Check whether the variable name followed the rule
def NamingConventionCheckVariableName ( self , FileTable ):
if EccGlobalData . gConfig . NamingConventionCheckVariableName == '1' or EccGlobalData . gConfig . NamingConventionCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
2019-02-06 15:44:39 +08:00
EdkLogger . quiet ( "Checking naming convention of variable name ..." )
2009-07-17 09:10:31 +00:00
Pattern = re . compile ( r '^[A-Zgm]+\S*[a-z]\S*$' )
2010-02-28 23:39:39 +00:00
2020-01-10 16:37:46 +08:00
SqlCommand = """select ID, Name, Modifier from %s where Model = %s """ % ( FileTable , MODEL_IDENTIFIER_VARIABLE )
2009-07-17 09:10:31 +00:00
RecordSet = EccGlobalData . gDb . TblFile . Exec ( SqlCommand )
for Record in RecordSet :
2015-09-14 07:12:29 +00:00
Var = Record [ 1 ]
2020-01-10 16:37:46 +08:00
Modifier = Record [ 2 ]
2015-09-14 07:12:29 +00:00
if Var . startswith ( 'CONST' ):
Var = Var [ 5 :] . lstrip ()
2020-01-10 16:37:46 +08:00
if not Pattern . match ( Var ) and not ( Modifier . endswith ( '*' ) and Var . startswith ( 'p' )):
2009-07-17 09:10:31 +00:00
if not EccGlobalData . gException . IsException ( ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME , Record [ 1 ]):
2011-11-09 04:32:08 +00:00
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 ])
2009-07-17 09:10:31 +00:00
# Rule for path name, variable name and function name
# 1. First character should be upper case
# 2. Existing lower case in a word
# 3. No space existence
# Check whether the function name followed the rule
def NamingConventionCheckFunctionName ( self ):
if EccGlobalData . gConfig . NamingConventionCheckFunctionName == '1' or EccGlobalData . gConfig . NamingConventionCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
2019-02-06 15:44:39 +08:00
EdkLogger . quiet ( "Checking naming convention of function name ..." )
2009-07-17 09:10:31 +00:00
Pattern = re . compile ( r '^[A-Z]+\S*[a-z]\S*$' )
SqlCommand = """select ID, Name from Function"""
RecordSet = EccGlobalData . gDb . TblFile . Exec ( SqlCommand )
for Record in RecordSet :
if not Pattern . match ( Record [ 1 ]):
if not EccGlobalData . gException . IsException ( ERROR_NAMING_CONVENTION_CHECK_FUNCTION_NAME , Record [ 1 ]):
2011-11-09 04:32:08 +00:00
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 ])
2009-07-17 09:10:31 +00:00
# Check whether NO use short variable name with single character
def NamingConventionCheckSingleCharacterVariable ( self , FileTable ):
if EccGlobalData . gConfig . NamingConventionCheckSingleCharacterVariable == '1' or EccGlobalData . gConfig . NamingConventionCheckAll == '1' or EccGlobalData . gConfig . CheckAll == '1' :
2019-02-06 15:44:39 +08:00
EdkLogger . quiet ( "Checking naming convention of single character variable name ..." )
2010-02-28 23:39:39 +00:00
2011-11-09 04:32:08 +00:00
SqlCommand = """select ID, Name from %s where Model = %s """ % ( FileTable , MODEL_IDENTIFIER_VARIABLE )
2009-07-17 09:10:31 +00:00
RecordSet = EccGlobalData . gDb . TblFile . Exec ( SqlCommand )
for Record in RecordSet :
Variable = Record [ 1 ] . replace ( '*' , '' )
if len ( Variable ) == 1 :
if not EccGlobalData . gException . IsException ( ERROR_NAMING_CONVENTION_CHECK_SINGLE_CHARACTER_VARIABLE , Record [ 1 ]):
2011-11-09 04:32:08 +00:00
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 ])
2009-07-17 09:10:31 +00:00
2017-04-11 16:17:19 +08:00
def FindPara ( FilePath , Para , CallingLine ):
Lines = open ( FilePath ) . readlines ()
Line = ''
for Index in range ( CallingLine - 1 , 0 , - 1 ):
# Find the nearest statement for Para
Line = Lines [ Index ] . strip ()
if Line . startswith ( ' %s = ' % Para ):
Line = Line . strip ()
return Line
break
return ''
2009-07-17 09:10:31 +00:00
##
#
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
#
if __name__ == '__main__' :
Check = Check ()
Check . Check ()