]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Ecc/Check.py
BaseTools: Remove equality operator with None
[mirror_edk2.git] / BaseTools / Source / Python / Ecc / Check.py
CommitLineData
30fdf114
LG
1## @file\r
2# This file is used to define checkpoints used by ECC tool\r
3#\r
f8c1facf 4# Copyright (c) 2008 - 2017, Intel Corporation. All rights reserved.<BR>\r
40d841f6 5# This program and the accompanying materials\r
30fdf114
LG
6# are licensed and made available under the terms and conditions of the BSD License\r
7# which accompanies this distribution. The full text of the license may be found at\r
8# http://opensource.org/licenses/bsd-license.php\r
9#\r
10# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12#\r
1be2ed90 13import Common.LongFilePathOs as os\r
30fdf114
LG
14import re\r
15from CommonDataClass.DataClass import *\r
b3d07ff8 16import Common.DataType as DT\r
30fdf114 17from EccToolError import *\r
d0acc87a 18from MetaDataParser import ParseHeaderCommentSection\r
30fdf114
LG
19import EccGlobalData\r
20import c\r
b3d07ff8 21from Common.LongFilePathSupport import OpenLongFilePath as open\r
c4f52e12 22from Common.MultipleWorkspace import MultipleWorkspace as mws\r
30fdf114
LG
23\r
24## Check\r
25#\r
26# This class is to define checkpoints used by ECC tool\r
27#\r
28# @param object: Inherited from object class\r
29#\r
30class Check(object):\r
31 def __init__(self):\r
32 pass\r
33\r
34 # Check all required checkpoints\r
35 def Check(self):\r
e56468c0 36 self.GeneralCheck()\r
30fdf114
LG
37 self.MetaDataFileCheck()\r
38 self.DoxygenCheck()\r
39 self.IncludeFileCheck()\r
40 self.PredicateExpressionCheck()\r
41 self.DeclAndDataTypeCheck()\r
42 self.FunctionLayoutCheck()\r
43 self.NamingConventionCheck()\r
703ef6cf
HC
44 self.SmmCommParaCheck()\r
45\r
46 def SmmCommParaCheck(self):\r
47 self.SmmCommParaCheckBufferType()\r
48\r
49\r
50 # Check if SMM communication function has correct parameter type\r
51 # 1. Get function calling with instance./->Communicate() interface\r
52 # and make sure the protocol instance is of type EFI_SMM_COMMUNICATION_PROTOCOL.\r
53 # 2. Find the origin of the 2nd parameter of Communicate() interface, if -\r
54 # a. it is a local buffer on stack\r
55 # report error.\r
56 # b. it is a global buffer, check the driver that holds the global buffer is of type DXE_RUNTIME_DRIVER\r
57 # report success.\r
58 # c. it is a buffer by AllocatePage/AllocatePool (may be wrapped by nested function calls),\r
59 # check the EFI_MEMORY_TYPE to be EfiRuntimeServicesCode,EfiRuntimeServicesData,\r
60 # EfiACPIMemoryNVS or EfiReservedMemoryType\r
61 # report success.\r
62 # d. it is a buffer located via EFI_SYSTEM_TABLE.ConfigurationTable (may be wrapped by nested function calls)\r
63 # report warning to indicate human code review.\r
64 # e. it is a buffer from other kind of pointers (may need to trace into nested function calls to locate),\r
65 # repeat checks in a.b.c and d.\r
66 def SmmCommParaCheckBufferType(self):\r
67 if EccGlobalData.gConfig.SmmCommParaCheckBufferType == '1' or EccGlobalData.gConfig.SmmCommParaCheckAll == '1':\r
68 EdkLogger.quiet("Checking SMM communication parameter type ...")\r
69 # Get all EFI_SMM_COMMUNICATION_PROTOCOL interface\r
70 CommApiList = []\r
71 for IdentifierTable in EccGlobalData.gIdentifierTableList:\r
72 SqlCommand = """select ID, Name, BelongsToFile from %s\r
73 where Modifier = 'EFI_SMM_COMMUNICATION_PROTOCOL*' """ % (IdentifierTable)\r
74 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
75 if RecordSet:\r
76 for Record in RecordSet:\r
77 if Record[1] not in CommApiList:\r
78 CommApiList.append(Record[1])\r
79 # For each interface, check the second parameter\r
80 for CommApi in CommApiList:\r
81 for IdentifierTable in EccGlobalData.gIdentifierTableList:\r
82 SqlCommand = """select ID, Name, Value, BelongsToFile, StartLine from %s\r
83 where Name = '%s->Communicate' and Model = %s""" \\r
84 % (IdentifierTable, CommApi, MODEL_IDENTIFIER_FUNCTION_CALLING)\r
85 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
86 if RecordSet:\r
87 # print IdentifierTable\r
88 for Record in RecordSet:\r
89 # Get the second parameter for Communicate function\r
90 SecondPara = Record[2].split(',')[1].strip()\r
91 SecondParaIndex = None\r
92 if SecondPara.startswith('&'):\r
93 SecondPara = SecondPara[1:]\r
94 if SecondPara.endswith(']'):\r
95 SecondParaIndex = SecondPara[SecondPara.find('[') + 1:-1]\r
96 SecondPara = SecondPara[:SecondPara.find('[')]\r
97 # Get the ID\r
98 Id = Record[0]\r
99 # Get the BelongsToFile\r
100 BelongsToFile = Record[3]\r
101 # Get the source file path\r
102 SqlCommand = """select FullPath from File where ID = %s""" % BelongsToFile\r
103 NewRecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
104 FullPath = NewRecordSet[0][0]\r
105 # Get the line no of function calling\r
106 StartLine = Record[4]\r
107 # Get the module type\r
108 SqlCommand = """select Value3 from INF where BelongsToFile = (select ID from File\r
109 where Path = (select Path from File where ID = %s) and Model = 1011)\r
110 and Value2 = 'MODULE_TYPE'""" % BelongsToFile\r
111 NewRecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
112 ModuleType = NewRecordSet[0][0] if NewRecordSet else None\r
113\r
114 # print BelongsToFile, FullPath, StartLine, ModuleType, SecondPara\r
115\r
116 Value = FindPara(FullPath, SecondPara, StartLine)\r
117 # Find the value of the parameter\r
118 if Value:\r
119 if 'AllocatePage' in Value \\r
120 or 'AllocatePool' in Value \\r
121 or 'AllocateRuntimePool' in Value \\r
122 or 'AllocateZeroPool' in Value:\r
123 pass\r
124 else:\r
125 if '->' in Value:\r
126 if not EccGlobalData.gException.IsException(\r
127 ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE, Value):\r
128 EccGlobalData.gDb.TblReport.Insert(ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE,\r
129 OtherMsg="Please review the buffer type"\r
130 + "is correct or not. If it is correct" +\r
131 " please add [%s] to exception list"\r
132 % Value,\r
133 BelongsToTable=IdentifierTable,\r
134 BelongsToItem=Id)\r
135 else:\r
136 if not EccGlobalData.gException.IsException(\r
137 ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE, Value):\r
138 EccGlobalData.gDb.TblReport.Insert(ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE,\r
139 OtherMsg="Please review the buffer type"\r
140 + "is correct or not. If it is correct" +\r
141 " please add [%s] to exception list"\r
142 % Value,\r
143 BelongsToTable=IdentifierTable,\r
144 BelongsToItem=Id)\r
145\r
146\r
147 # Not find the value of the parameter\r
148 else:\r
149 SqlCommand = """select ID, Modifier, Name, Value, Model, BelongsToFunction from %s\r
150 where Name = '%s' and StartLine < %s order by StartLine DESC""" \\r
151 % (IdentifierTable, SecondPara, StartLine)\r
152 NewRecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
153 if NewRecordSet:\r
154 Value = NewRecordSet[0][1]\r
155 if 'AllocatePage' in Value \\r
156 or 'AllocatePool' in Value \\r
157 or 'AllocateRuntimePool' in Value \\r
158 or 'AllocateZeroPool' in Value:\r
159 pass\r
160 else:\r
161 if not EccGlobalData.gException.IsException(\r
162 ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE, Value):\r
163 EccGlobalData.gDb.TblReport.Insert(ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE,\r
164 OtherMsg="Please review the buffer type"\r
165 + "is correct or not. If it is correct" +\r
166 " please add [%s] to exception list"\r
167 % Value,\r
168 BelongsToTable=IdentifierTable,\r
169 BelongsToItem=Id)\r
170 else:\r
171 pass\r
30fdf114 172\r
b3d07ff8
HC
173 # Check UNI files\r
174 def UniCheck(self):\r
175 if EccGlobalData.gConfig.GeneralCheckUni == '1' or EccGlobalData.gConfig.GeneralCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
176 EdkLogger.quiet("Checking whether UNI file is UTF-16 ...")\r
177 SqlCommand = """select ID, FullPath, ExtName from File where ExtName like 'uni'"""\r
178 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
179 for Record in RecordSet:\r
180 File = Record[1]\r
181 FileIn = open(File, 'rb').read(2)\r
182 if FileIn != '\xff\xfe':\r
183 OtherMsg = "File %s is not a valid UTF-16 UNI file" % Record[1]\r
184 EccGlobalData.gDb.TblReport.Insert(ERROR_GENERAL_CHECK_UNI, OtherMsg=OtherMsg, BelongsToTable='File', BelongsToItem=Record[0])\r
185\r
e56468c0 186 # General Checking\r
187 def GeneralCheck(self):\r
188 self.GeneralCheckNonAcsii()\r
b3d07ff8 189 self.UniCheck()\r
e56468c0 190\r
191 # Check whether file has non ACSII char\r
192 def GeneralCheckNonAcsii(self):\r
193 if EccGlobalData.gConfig.GeneralCheckNonAcsii == '1' or EccGlobalData.gConfig.GeneralCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
194 EdkLogger.quiet("Checking Non-ACSII char in file ...")\r
8d62ae35 195 SqlCommand = """select ID, FullPath, ExtName from File where ExtName in ('.dec', '.inf', '.dsc', 'c', 'h')"""\r
d0acc87a 196 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
e56468c0 197 for Record in RecordSet:\r
198 if Record[2].upper() not in EccGlobalData.gConfig.BinaryExtList:\r
199 op = open(Record[1]).readlines()\r
200 IndexOfLine = 0\r
201 for Line in op:\r
202 IndexOfLine += 1\r
203 IndexOfChar = 0\r
204 for Char in Line:\r
205 IndexOfChar += 1\r
206 if ord(Char) > 126:\r
d40b2ee6
LG
207 OtherMsg = "File %s has Non-ASCII char at line %s column %s" % (Record[1], IndexOfLine, IndexOfChar)\r
208 EccGlobalData.gDb.TblReport.Insert(ERROR_GENERAL_CHECK_NON_ACSII, OtherMsg=OtherMsg, BelongsToTable='File', BelongsToItem=Record[0])\r
e56468c0 209\r
30fdf114
LG
210 # C Function Layout Checking\r
211 def FunctionLayoutCheck(self):\r
212 self.FunctionLayoutCheckReturnType()\r
213 self.FunctionLayoutCheckModifier()\r
214 self.FunctionLayoutCheckName()\r
215 self.FunctionLayoutCheckPrototype()\r
216 self.FunctionLayoutCheckBody()\r
217 self.FunctionLayoutCheckLocalVariable()\r
218\r
219 def WalkTree(self):\r
220 IgnoredPattern = c.GetIgnoredDirListPattern()\r
221 for Dirpath, Dirnames, Filenames in os.walk(EccGlobalData.gTarget):\r
222 for Dir in Dirnames:\r
223 Dirname = os.path.join(Dirpath, Dir)\r
224 if os.path.islink(Dirname):\r
225 Dirname = os.path.realpath(Dirname)\r
226 if os.path.isdir(Dirname):\r
227 # symlinks to directories are treated as directories\r
228 Dirnames.remove(Dir)\r
229 Dirnames.append(Dirname)\r
230 if IgnoredPattern.match(Dirpath.upper()):\r
231 continue\r
8c3f9b4e
HC
232 for f in Filenames[:]:\r
233 if f.lower() in EccGlobalData.gConfig.SkipFileList:\r
234 Filenames.remove(f)\r
30fdf114
LG
235 yield (Dirpath, Dirnames, Filenames)\r
236\r
237 # Check whether return type exists and in the first line\r
238 def FunctionLayoutCheckReturnType(self):\r
239 if EccGlobalData.gConfig.CFunctionLayoutCheckReturnType == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
240 EdkLogger.quiet("Checking function layout return type ...")\r
241\r
e56468c0 242# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
243# for F in Filenames:\r
244# if os.path.splitext(F)[1] in ('.c', '.h'):\r
245# FullName = os.path.join(Dirpath, F)\r
246# c.CheckFuncLayoutReturnType(FullName)\r
247 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
248 c.CheckFuncLayoutReturnType(FullName)\r
30fdf114
LG
249\r
250 # Check whether any optional functional modifiers exist and next to the return type\r
251 def FunctionLayoutCheckModifier(self):\r
252 if EccGlobalData.gConfig.CFunctionLayoutCheckOptionalFunctionalModifier == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
253 EdkLogger.quiet("Checking function layout modifier ...")\r
254\r
e56468c0 255# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
256# for F in Filenames:\r
257# if os.path.splitext(F)[1] in ('.c', '.h'):\r
258# FullName = os.path.join(Dirpath, F)\r
259# c.CheckFuncLayoutModifier(FullName)\r
260 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
261 c.CheckFuncLayoutModifier(FullName)\r
30fdf114
LG
262\r
263 # Check whether the next line contains the function name, left justified, followed by the beginning of the parameter list\r
264 # Check whether the closing parenthesis is on its own line and also indented two spaces\r
265 def FunctionLayoutCheckName(self):\r
266 if EccGlobalData.gConfig.CFunctionLayoutCheckFunctionName == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
267 EdkLogger.quiet("Checking function layout function name ...")\r
268\r
e56468c0 269# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
270# for F in Filenames:\r
271# if os.path.splitext(F)[1] in ('.c', '.h'):\r
272# FullName = os.path.join(Dirpath, F)\r
273# c.CheckFuncLayoutName(FullName)\r
274 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
275 c.CheckFuncLayoutName(FullName)\r
276\r
30fdf114
LG
277 # Check whether the function prototypes in include files have the same form as function definitions\r
278 def FunctionLayoutCheckPrototype(self):\r
279 if EccGlobalData.gConfig.CFunctionLayoutCheckFunctionPrototype == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
280 EdkLogger.quiet("Checking function layout function prototype ...")\r
281\r
e56468c0 282# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
283# for F in Filenames:\r
284# if os.path.splitext(F)[1] in ('.c'):\r
285# FullName = os.path.join(Dirpath, F)\r
286# EdkLogger.quiet("[PROTOTYPE]" + FullName)\r
287# c.CheckFuncLayoutPrototype(FullName)\r
288 for FullName in EccGlobalData.gCFileList:\r
289 EdkLogger.quiet("[PROTOTYPE]" + FullName)\r
290 c.CheckFuncLayoutPrototype(FullName)\r
30fdf114
LG
291\r
292 # Check whether the body of a function is contained by open and close braces that must be in the first column\r
293 def FunctionLayoutCheckBody(self):\r
294 if EccGlobalData.gConfig.CFunctionLayoutCheckFunctionBody == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
295 EdkLogger.quiet("Checking function layout function body ...")\r
296\r
e56468c0 297# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
298# for F in Filenames:\r
299# if os.path.splitext(F)[1] in ('.c'):\r
300# FullName = os.path.join(Dirpath, F)\r
301# c.CheckFuncLayoutBody(FullName)\r
302 for FullName in EccGlobalData.gCFileList:\r
303 c.CheckFuncLayoutBody(FullName)\r
30fdf114
LG
304\r
305 # Check whether the data declarations is the first code in a module.\r
306 # self.CFunctionLayoutCheckDataDeclaration = 1\r
307 # Check whether no initialization of a variable as part of its declaration\r
308 def FunctionLayoutCheckLocalVariable(self):\r
309 if EccGlobalData.gConfig.CFunctionLayoutCheckNoInitOfVariable == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
310 EdkLogger.quiet("Checking function layout local variables ...")\r
311\r
e56468c0 312# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
313# for F in Filenames:\r
314# if os.path.splitext(F)[1] in ('.c'):\r
315# FullName = os.path.join(Dirpath, F)\r
316# c.CheckFuncLayoutLocalVariable(FullName)\r
317\r
318 for FullName in EccGlobalData.gCFileList:\r
319 c.CheckFuncLayoutLocalVariable(FullName)\r
30fdf114
LG
320\r
321 # Check whether no use of STATIC for functions\r
322 # self.CFunctionLayoutCheckNoStatic = 1\r
323\r
324 # Declarations and Data Types Checking\r
325 def DeclAndDataTypeCheck(self):\r
326 self.DeclCheckNoUseCType()\r
327 self.DeclCheckInOutModifier()\r
328 self.DeclCheckEFIAPIModifier()\r
329 self.DeclCheckEnumeratedType()\r
330 self.DeclCheckStructureDeclaration()\r
331 self.DeclCheckSameStructure()\r
332 self.DeclCheckUnionType()\r
333\r
334\r
335 # Check whether no use of int, unsigned, char, void, static, long in any .c, .h or .asl files.\r
336 def DeclCheckNoUseCType(self):\r
337 if EccGlobalData.gConfig.DeclarationDataTypeCheckNoUseCType == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
338 EdkLogger.quiet("Checking Declaration No use C type ...")\r
339\r
e56468c0 340# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
341# for F in Filenames:\r
342# if os.path.splitext(F)[1] in ('.h', '.c'):\r
343# FullName = os.path.join(Dirpath, F)\r
344# c.CheckDeclNoUseCType(FullName)\r
345 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
346 c.CheckDeclNoUseCType(FullName)\r
30fdf114
LG
347\r
348 # Check whether the modifiers IN, OUT, OPTIONAL, and UNALIGNED are used only to qualify arguments to a function and should not appear in a data type declaration\r
349 def DeclCheckInOutModifier(self):\r
350 if EccGlobalData.gConfig.DeclarationDataTypeCheckInOutModifier == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
351 EdkLogger.quiet("Checking Declaration argument modifier ...")\r
352\r
e56468c0 353# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
354# for F in Filenames:\r
355# if os.path.splitext(F)[1] in ('.h', '.c'):\r
356# FullName = os.path.join(Dirpath, F)\r
357# c.CheckDeclArgModifier(FullName)\r
358 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
359 c.CheckDeclArgModifier(FullName)\r
30fdf114
LG
360\r
361 # Check whether the EFIAPI modifier should be used at the entry of drivers, events, and member functions of protocols\r
362 def DeclCheckEFIAPIModifier(self):\r
363 if EccGlobalData.gConfig.DeclarationDataTypeCheckEFIAPIModifier == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
364 pass\r
365\r
366 # Check whether Enumerated Type has a 'typedef' and the name is capital\r
367 def DeclCheckEnumeratedType(self):\r
368 if EccGlobalData.gConfig.DeclarationDataTypeCheckEnumeratedType == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
369 EdkLogger.quiet("Checking Declaration enum typedef ...")\r
370\r
e56468c0 371# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
372# for F in Filenames:\r
373# if os.path.splitext(F)[1] in ('.h', '.c'):\r
374# FullName = os.path.join(Dirpath, F)\r
375# EdkLogger.quiet("[ENUM]" + FullName)\r
376# c.CheckDeclEnumTypedef(FullName)\r
377 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
378 EdkLogger.quiet("[ENUM]" + FullName)\r
379 c.CheckDeclEnumTypedef(FullName)\r
30fdf114
LG
380\r
381 # Check whether Structure Type has a 'typedef' and the name is capital\r
382 def DeclCheckStructureDeclaration(self):\r
383 if EccGlobalData.gConfig.DeclarationDataTypeCheckStructureDeclaration == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
384 EdkLogger.quiet("Checking Declaration struct typedef ...")\r
385\r
e56468c0 386# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
387# for F in Filenames:\r
388# if os.path.splitext(F)[1] in ('.h', '.c'):\r
389# FullName = os.path.join(Dirpath, F)\r
390# EdkLogger.quiet("[STRUCT]" + FullName)\r
391# c.CheckDeclStructTypedef(FullName)\r
392 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
393 EdkLogger.quiet("[STRUCT]" + FullName)\r
394 c.CheckDeclStructTypedef(FullName)\r
30fdf114
LG
395\r
396 # Check whether having same Structure\r
397 def DeclCheckSameStructure(self):\r
398 if EccGlobalData.gConfig.DeclarationDataTypeCheckSameStructure == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
399 EdkLogger.quiet("Checking same struct ...")\r
400 AllStructure = {}\r
401 for IdentifierTable in EccGlobalData.gIdentifierTableList:\r
d40b2ee6 402 SqlCommand = """select ID, Name, BelongsToFile from %s where Model = %s""" % (IdentifierTable, MODEL_IDENTIFIER_STRUCTURE)\r
30fdf114
LG
403 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
404 for Record in RecordSet:\r
405 if Record[1] != '':\r
406 if Record[1] not in AllStructure.keys():\r
407 AllStructure[Record[1]] = Record[2]\r
408 else:\r
409 ID = AllStructure[Record[1]]\r
410 SqlCommand = """select FullPath from File where ID = %s """ % ID\r
411 NewRecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
412 OtherMsg = "The structure name '%s' is duplicate" % Record[1]\r
413 if NewRecordSet != []:\r
414 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])\r
415 if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE, Record[1]):\r
d40b2ee6 416 EccGlobalData.gDb.TblReport.Insert(ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE, OtherMsg=OtherMsg, BelongsToTable=IdentifierTable, BelongsToItem=Record[0])\r
30fdf114
LG
417\r
418 # Check whether Union Type has a 'typedef' and the name is capital\r
419 def DeclCheckUnionType(self):\r
420 if EccGlobalData.gConfig.DeclarationDataTypeCheckUnionType == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
421 EdkLogger.quiet("Checking Declaration union typedef ...")\r
422\r
e56468c0 423# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
424# for F in Filenames:\r
425# if os.path.splitext(F)[1] in ('.h', '.c'):\r
426# FullName = os.path.join(Dirpath, F)\r
427# EdkLogger.quiet("[UNION]" + FullName)\r
428# c.CheckDeclUnionTypedef(FullName)\r
429 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
430 EdkLogger.quiet("[UNION]" + FullName)\r
431 c.CheckDeclUnionTypedef(FullName)\r
30fdf114
LG
432\r
433 # Predicate Expression Checking\r
434 def PredicateExpressionCheck(self):\r
435 self.PredicateExpressionCheckBooleanValue()\r
436 self.PredicateExpressionCheckNonBooleanOperator()\r
437 self.PredicateExpressionCheckComparisonNullType()\r
438\r
439 # Check whether Boolean values, variable type BOOLEAN not use explicit comparisons to TRUE or FALSE\r
440 def PredicateExpressionCheckBooleanValue(self):\r
441 if EccGlobalData.gConfig.PredicateExpressionCheckBooleanValue == '1' or EccGlobalData.gConfig.PredicateExpressionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
442 EdkLogger.quiet("Checking predicate expression Boolean value ...")\r
443\r
e56468c0 444# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
445# for F in Filenames:\r
446# if os.path.splitext(F)[1] in ('.c'):\r
447# FullName = os.path.join(Dirpath, F)\r
448# EdkLogger.quiet("[BOOLEAN]" + FullName)\r
449# c.CheckBooleanValueComparison(FullName)\r
450 for FullName in EccGlobalData.gCFileList:\r
451 EdkLogger.quiet("[BOOLEAN]" + FullName)\r
452 c.CheckBooleanValueComparison(FullName)\r
30fdf114
LG
453\r
454 # Check whether Non-Boolean comparisons use a compare operator (==, !=, >, < >=, <=).\r
455 def PredicateExpressionCheckNonBooleanOperator(self):\r
456 if EccGlobalData.gConfig.PredicateExpressionCheckNonBooleanOperator == '1' or EccGlobalData.gConfig.PredicateExpressionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
457 EdkLogger.quiet("Checking predicate expression Non-Boolean variable...")\r
458\r
e56468c0 459# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
460# for F in Filenames:\r
461# if os.path.splitext(F)[1] in ('.c'):\r
462# FullName = os.path.join(Dirpath, F)\r
463# EdkLogger.quiet("[NON-BOOLEAN]" + FullName)\r
464# c.CheckNonBooleanValueComparison(FullName)\r
465 for FullName in EccGlobalData.gCFileList:\r
466 EdkLogger.quiet("[NON-BOOLEAN]" + FullName)\r
467 c.CheckNonBooleanValueComparison(FullName)\r
468\r
30fdf114
LG
469 # Check whether a comparison of any pointer to zero must be done via the NULL type\r
470 def PredicateExpressionCheckComparisonNullType(self):\r
471 if EccGlobalData.gConfig.PredicateExpressionCheckComparisonNullType == '1' or EccGlobalData.gConfig.PredicateExpressionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
472 EdkLogger.quiet("Checking predicate expression NULL pointer ...")\r
473\r
e56468c0 474# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
475# for F in Filenames:\r
476# if os.path.splitext(F)[1] in ('.c'):\r
477# FullName = os.path.join(Dirpath, F)\r
478# EdkLogger.quiet("[POINTER]" + FullName)\r
479# c.CheckPointerNullComparison(FullName)\r
480 for FullName in EccGlobalData.gCFileList:\r
481 EdkLogger.quiet("[POINTER]" + FullName)\r
482 c.CheckPointerNullComparison(FullName)\r
483\r
30fdf114
LG
484 # Include file checking\r
485 def IncludeFileCheck(self):\r
486 self.IncludeFileCheckIfndef()\r
487 self.IncludeFileCheckData()\r
488 self.IncludeFileCheckSameName()\r
489\r
490 # Check whether having include files with same name\r
491 def IncludeFileCheckSameName(self):\r
492 if EccGlobalData.gConfig.IncludeFileCheckSameName == '1' or EccGlobalData.gConfig.IncludeFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
493 EdkLogger.quiet("Checking same header file name ...")\r
494 SqlCommand = """select ID, FullPath from File\r
495 where Model = 1002 order by Name """\r
496 RecordDict = {}\r
497 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
498 for Record in RecordSet:\r
499 List = Record[1].replace('/', '\\').split('\\')\r
500 if len(List) >= 2:\r
501 Key = List[-2] + '\\' + List[-1]\r
502 else:\r
503 Key = List[0]\r
504 if Key not in RecordDict:\r
505 RecordDict[Key] = [Record]\r
506 else:\r
507 RecordDict[Key].append(Record)\r
508\r
509 for Key in RecordDict:\r
510 if len(RecordDict[Key]) > 1:\r
511 for Item in RecordDict[Key]:\r
c4f52e12 512 Path = mws.relpath(Item[1], EccGlobalData.gWorkspace)\r
52302d4d 513 if not EccGlobalData.gException.IsException(ERROR_INCLUDE_FILE_CHECK_NAME, Path):\r
d40b2ee6 514 EccGlobalData.gDb.TblReport.Insert(ERROR_INCLUDE_FILE_CHECK_NAME, OtherMsg="The file name for [%s] is duplicate" % Path, BelongsToTable='File', BelongsToItem=Item[0])\r
30fdf114
LG
515\r
516 # Check whether all include file contents is guarded by a #ifndef statement.\r
517 def IncludeFileCheckIfndef(self):\r
518 if EccGlobalData.gConfig.IncludeFileCheckIfndefStatement == '1' or EccGlobalData.gConfig.IncludeFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
519 EdkLogger.quiet("Checking header file ifndef ...")\r
520\r
e56468c0 521# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
522# for F in Filenames:\r
523# if os.path.splitext(F)[1] in ('.h'):\r
524# FullName = os.path.join(Dirpath, F)\r
525# MsgList = c.CheckHeaderFileIfndef(FullName)\r
526 for FullName in EccGlobalData.gHFileList:\r
527 MsgList = c.CheckHeaderFileIfndef(FullName)\r
30fdf114
LG
528\r
529 # Check whether include files NOT contain code or define data variables\r
530 def IncludeFileCheckData(self):\r
531 if EccGlobalData.gConfig.IncludeFileCheckData == '1' or EccGlobalData.gConfig.IncludeFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
532 EdkLogger.quiet("Checking header file data ...")\r
533\r
e56468c0 534# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
535# for F in Filenames:\r
536# if os.path.splitext(F)[1] in ('.h'):\r
537# FullName = os.path.join(Dirpath, F)\r
538# MsgList = c.CheckHeaderFileData(FullName)\r
539 for FullName in EccGlobalData.gHFileList:\r
540 MsgList = c.CheckHeaderFileData(FullName)\r
30fdf114
LG
541\r
542 # Doxygen document checking\r
543 def DoxygenCheck(self):\r
544 self.DoxygenCheckFileHeader()\r
545 self.DoxygenCheckFunctionHeader()\r
546 self.DoxygenCheckCommentDescription()\r
547 self.DoxygenCheckCommentFormat()\r
548 self.DoxygenCheckCommand()\r
549\r
550 # Check whether the file headers are followed Doxygen special documentation blocks in section 2.3.5\r
551 def DoxygenCheckFileHeader(self):\r
552 if EccGlobalData.gConfig.DoxygenCheckFileHeader == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
553 EdkLogger.quiet("Checking Doxygen file header ...")\r
554\r
555 for Dirpath, Dirnames, Filenames in self.WalkTree():\r
556 for F in Filenames:\r
40d841f6
LG
557 Ext = os.path.splitext(F)[1]\r
558 if Ext in ('.h', '.c'):\r
30fdf114
LG
559 FullName = os.path.join(Dirpath, F)\r
560 MsgList = c.CheckFileHeaderDoxygenComments(FullName)\r
40d841f6
LG
561 elif Ext in ('.inf', '.dec', '.dsc', '.fdf'):\r
562 FullName = os.path.join(Dirpath, F)\r
e56468c0 563 op = open(FullName).readlines()\r
d0acc87a
LG
564 FileLinesList = op\r
565 LineNo = 0\r
566 CurrentSection = MODEL_UNKNOWN \r
567 HeaderSectionLines = []\r
568 HeaderCommentStart = False \r
569 HeaderCommentEnd = False\r
570 \r
571 for Line in FileLinesList:\r
572 LineNo = LineNo + 1\r
573 Line = Line.strip()\r
574 if (LineNo < len(FileLinesList) - 1):\r
575 NextLine = FileLinesList[LineNo].strip()\r
576 \r
577 #\r
578 # blank line\r
579 #\r
580 if (Line == '' or not Line) and LineNo == len(FileLinesList):\r
581 LastSectionFalg = True\r
582\r
583 #\r
584 # check whether file header comment section started\r
585 #\r
586 if Line.startswith('#') and \\r
587 (Line.find('@file') > -1) and \\r
588 not HeaderCommentStart:\r
589 if CurrentSection != MODEL_UNKNOWN:\r
590 SqlStatement = """ select ID from File where FullPath like '%s'""" % FullName\r
591 ResultSet = EccGlobalData.gDb.TblFile.Exec(SqlStatement)\r
592 for Result in ResultSet:\r
593 Msg = 'INF/DEC/DSC/FDF file header comment should begin with ""## @file"" or ""# @file""at the very top file'\r
594 EccGlobalData.gDb.TblReport.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER, Msg, "File", Result[0])\r
595\r
596 else:\r
597 CurrentSection = MODEL_IDENTIFIER_FILE_HEADER\r
598 #\r
599 # Append the first line to section lines.\r
600 #\r
601 HeaderSectionLines.append((Line, LineNo))\r
602 HeaderCommentStart = True\r
603 continue \r
604 \r
605 #\r
606 # Collect Header content.\r
607 #\r
608 if (Line.startswith('#') and CurrentSection == MODEL_IDENTIFIER_FILE_HEADER) and\\r
609 HeaderCommentStart and not Line.startswith('##') and not\\r
610 HeaderCommentEnd and NextLine != '':\r
611 HeaderSectionLines.append((Line, LineNo))\r
612 continue\r
613 #\r
614 # Header content end\r
615 #\r
616 if (Line.startswith('##') or not Line.strip().startswith("#")) and HeaderCommentStart \\r
617 and not HeaderCommentEnd:\r
618 if Line.startswith('##'):\r
619 HeaderCommentEnd = True\r
620 HeaderSectionLines.append((Line, LineNo))\r
621 ParseHeaderCommentSection(HeaderSectionLines, FullName)\r
622 break\r
623 if HeaderCommentStart == False:\r
40d841f6
LG
624 SqlStatement = """ select ID from File where FullPath like '%s'""" % FullName\r
625 ResultSet = EccGlobalData.gDb.TblFile.Exec(SqlStatement)\r
626 for Result in ResultSet:\r
d0acc87a 627 Msg = 'INF/DEC/DSC/FDF file header comment should begin with ""## @file"" or ""# @file"" at the very top file'\r
40d841f6 628 EccGlobalData.gDb.TblReport.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER, Msg, "File", Result[0])\r
d0acc87a
LG
629 if HeaderCommentEnd == False:\r
630 SqlStatement = """ select ID from File where FullPath like '%s'""" % FullName\r
631 ResultSet = EccGlobalData.gDb.TblFile.Exec(SqlStatement)\r
632 for Result in ResultSet:\r
633 Msg = 'INF/DEC/DSC/FDF file header comment should end with ""##"" at the end of file header comment block'\r
634 # Check whether File header Comment End with '##'\r
635 if EccGlobalData.gConfig.HeaderCheckFileCommentEnd == '1' or EccGlobalData.gConfig.HeaderCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
636 EccGlobalData.gDb.TblReport.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER, Msg, "File", Result[0])\r
e56468c0 637\r
d0acc87a 638 \r
30fdf114
LG
639\r
640 # Check whether the function headers are followed Doxygen special documentation blocks in section 2.3.5\r
641 def DoxygenCheckFunctionHeader(self):\r
642 if EccGlobalData.gConfig.DoxygenCheckFunctionHeader == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
643 EdkLogger.quiet("Checking Doxygen function header ...")\r
644\r
e56468c0 645# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
646# for F in Filenames:\r
647# if os.path.splitext(F)[1] in ('.h', '.c'):\r
648# FullName = os.path.join(Dirpath, F)\r
649# MsgList = c.CheckFuncHeaderDoxygenComments(FullName)\r
650 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
651 MsgList = c.CheckFuncHeaderDoxygenComments(FullName)\r
652\r
30fdf114
LG
653\r
654 # Check whether the first line of text in a comment block is a brief description of the element being documented.\r
655 # The brief description must end with a period.\r
656 def DoxygenCheckCommentDescription(self):\r
657 if EccGlobalData.gConfig.DoxygenCheckCommentDescription == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
658 pass\r
659\r
660 # Check whether comment lines with '///< ... text ...' format, if it is used, it should be after the code section.\r
661 def DoxygenCheckCommentFormat(self):\r
662 if EccGlobalData.gConfig.DoxygenCheckCommentFormat == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
663 EdkLogger.quiet("Checking Doxygen comment ///< ...")\r
664\r
e56468c0 665# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
666# for F in Filenames:\r
667# if os.path.splitext(F)[1] in ('.h', '.c'):\r
668# FullName = os.path.join(Dirpath, F)\r
669# MsgList = c.CheckDoxygenTripleForwardSlash(FullName)\r
670 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
671 MsgList = c.CheckDoxygenTripleForwardSlash(FullName)\r
30fdf114
LG
672\r
673 # Check whether only Doxygen commands allowed to mark the code are @bug and @todo.\r
674 def DoxygenCheckCommand(self):\r
675 if EccGlobalData.gConfig.DoxygenCheckCommand == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
676 EdkLogger.quiet("Checking Doxygen command ...")\r
677\r
e56468c0 678# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
679# for F in Filenames:\r
680# if os.path.splitext(F)[1] in ('.h', '.c'):\r
681# FullName = os.path.join(Dirpath, F)\r
682# MsgList = c.CheckDoxygenCommand(FullName)\r
683 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
684 MsgList = c.CheckDoxygenCommand(FullName)\r
30fdf114
LG
685\r
686 # Meta-Data File Processing Checking\r
687 def MetaDataFileCheck(self):\r
688 self.MetaDataFileCheckPathName()\r
689 self.MetaDataFileCheckGenerateFileList()\r
690 self.MetaDataFileCheckLibraryInstance()\r
691 self.MetaDataFileCheckLibraryInstanceDependent()\r
692 self.MetaDataFileCheckLibraryInstanceOrder()\r
693 self.MetaDataFileCheckLibraryNoUse()\r
14239f66 694 self.MetaDataFileCheckLibraryDefinedInDec()\r
30fdf114
LG
695 self.MetaDataFileCheckBinaryInfInFdf()\r
696 self.MetaDataFileCheckPcdDuplicate()\r
697 self.MetaDataFileCheckPcdFlash()\r
698 self.MetaDataFileCheckPcdNoUse()\r
699 self.MetaDataFileCheckGuidDuplicate()\r
700 self.MetaDataFileCheckModuleFileNoUse()\r
701 self.MetaDataFileCheckPcdType()\r
40d841f6 702 self.MetaDataFileCheckModuleFileGuidDuplication()\r
b3d07ff8
HC
703 self.MetaDataFileCheckModuleFileGuidFormat()\r
704 self.MetaDataFileCheckModuleFileProtocolFormat()\r
705 self.MetaDataFileCheckModuleFilePpiFormat()\r
706 self.MetaDataFileCheckModuleFilePcdFormat()\r
30fdf114
LG
707\r
708 # Check whether each file defined in meta-data exists\r
709 def MetaDataFileCheckPathName(self):\r
710 if EccGlobalData.gConfig.MetaDataFileCheckPathName == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
711 # This item is covered when parsing Inf/Dec/Dsc files\r
712 pass\r
713\r
714 # Generate a list for all files defined in meta-data files\r
715 def MetaDataFileCheckGenerateFileList(self):\r
716 if EccGlobalData.gConfig.MetaDataFileCheckGenerateFileList == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
717 # This item is covered when parsing Inf/Dec/Dsc files\r
718 pass\r
719\r
720 # Check whether all Library Instances defined for a given module (or dependent library instance) match the module's type.\r
721 # Each Library Instance must specify the Supported Module Types in its Inf file,\r
722 # and any module specifying the library instance must be one of the supported types.\r
723 def MetaDataFileCheckLibraryInstance(self):\r
724 if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstance == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
725 EdkLogger.quiet("Checking for library instance type issue ...")\r
d0acc87a
LG
726 SqlCommand = """select A.ID, A.Value3, B.Value3 from Inf as A left join Inf as B\r
727 where A.Value2 = 'LIBRARY_CLASS' and A.Model = %s\r
728 and B.Value2 = 'MODULE_TYPE' and B.Model = %s and A.BelongsToFile = B.BelongsToFile\r
30fdf114
LG
729 group by A.BelongsToFile""" % (MODEL_META_DATA_HEADER, MODEL_META_DATA_HEADER)\r
730 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
731 LibraryClasses = {}\r
732 for Record in RecordSet:\r
733 List = Record[1].split('|', 1)\r
734 SupModType = []\r
735 if len(List) == 1:\r
b3d07ff8 736 SupModType = DT.SUP_MODULE_LIST_STRING.split(DT.TAB_VALUE_SPLIT)\r
30fdf114
LG
737 elif len(List) == 2:\r
738 SupModType = List[1].split()\r
739\r
740 if List[0] not in LibraryClasses:\r
741 LibraryClasses[List[0]] = SupModType\r
742 else:\r
743 for Item in SupModType:\r
744 if Item not in LibraryClasses[List[0]]:\r
745 LibraryClasses[List[0]].append(Item)\r
746\r
747 if Record[2] != 'BASE' and Record[2] not in SupModType:\r
d40b2ee6 748 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])\r
30fdf114 749\r
d0acc87a
LG
750 SqlCommand = """select A.ID, A.Value1, B.Value3 from Inf as A left join Inf as B\r
751 where A.Model = %s and B.Value2 = '%s' and B.Model = %s\r
30fdf114
LG
752 and B.BelongsToFile = A.BelongsToFile""" \\r
753 % (MODEL_EFI_LIBRARY_CLASS, 'MODULE_TYPE', MODEL_META_DATA_HEADER)\r
754 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
755 # Merge all LibraryClasses' supmodlist\r
756 RecordDict = {}\r
757 for Record in RecordSet:\r
758 if Record[1] not in RecordDict:\r
759 RecordDict[Record[1]] = [str(Record[2])]\r
760 else:\r
761 if Record[2] not in RecordDict[Record[1]]:\r
762 RecordDict[Record[1]].append(Record[2])\r
763\r
764 for Record in RecordSet:\r
765 if Record[1] in LibraryClasses:\r
766 if Record[2] not in LibraryClasses[Record[1]] and 'BASE' not in RecordDict[Record[1]]:\r
767 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1, Record[1]):\r
d40b2ee6 768 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])\r
30fdf114
LG
769 else:\r
770 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1, Record[1]):\r
d40b2ee6 771 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])\r
30fdf114
LG
772\r
773 # Check whether a Library Instance has been defined for all dependent library classes\r
774 def MetaDataFileCheckLibraryInstanceDependent(self):\r
775 if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstanceDependent == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
776 EdkLogger.quiet("Checking for library instance dependent issue ...")\r
777 SqlCommand = """select ID, Value1, Value2 from Dsc where Model = %s""" % MODEL_EFI_LIBRARY_CLASS\r
778 LibraryClasses = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)\r
779 for LibraryClass in LibraryClasses:\r
d0acc87a
LG
780 if LibraryClass[1].upper() == 'NULL' or LibraryClass[1].startswith('!ifdef') or LibraryClass[1].startswith('!ifndef') or LibraryClass[1].endswith('!endif'):\r
781 continue\r
782 else:\r
c4f52e12 783 LibraryIns = os.path.normpath(mws.join(EccGlobalData.gWorkspace, LibraryClass[2]))\r
044f6017
HC
784 SkipDirString = '|'.join(EccGlobalData.gConfig.SkipDirList)\r
785 p = re.compile(r'.*[\\/](?:%s^\S)[\\/]?.*' % SkipDirString)\r
786 if p.match(os.path.split(LibraryIns)[0].upper()):\r
787 continue\r
d0acc87a 788 SqlCommand = """select Value3 from Inf where BelongsToFile =\r
30fdf114 789 (select ID from File where lower(FullPath) = lower('%s'))\r
d0acc87a 790 and Value2 = '%s'""" % (LibraryIns, 'LIBRARY_CLASS')\r
30fdf114
LG
791 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
792 IsFound = False\r
793 for Record in RecordSet:\r
794 LibName = Record[0].split('|', 1)[0]\r
795 if LibraryClass[1] == LibName:\r
796 IsFound = True\r
797 if not IsFound:\r
798 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_DEPENDENT, LibraryClass[1]):\r
d40b2ee6 799 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])\r
30fdf114
LG
800\r
801 # Check whether the Library Instances specified by the LibraryClasses sections are listed in order of dependencies\r
802 def MetaDataFileCheckLibraryInstanceOrder(self):\r
803 if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstanceOrder == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
804 # This checkpoint is not necessary for Ecc check\r
805 pass\r
806\r
807 # Check whether the unnecessary inclusion of library classes in the Inf file\r
2bcc713e 808 # Check whether the unnecessary duplication of library classe names in the DSC file\r
30fdf114
LG
809 def MetaDataFileCheckLibraryNoUse(self):\r
810 if EccGlobalData.gConfig.MetaDataFileCheckLibraryNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
811 EdkLogger.quiet("Checking for library instance not used ...")\r
812 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)\r
813 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
814 for Record in RecordSet:\r
815 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_NO_USE, Record[1]):\r
d40b2ee6 816 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])\r
2bcc713e
LG
817 SqlCommand = """\r
818 select A.ID, A.Value1, A.BelongsToFile, A.StartLine, B.StartLine from Dsc as A left join Dsc as B\r
d0acc87a
LG
819 where A.Model = %s and B.Model = %s and A.Scope1 = B.Scope1 and A.Scope2 = B.Scope2 and A.ID <> B.ID\r
820 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""" \\r
2bcc713e
LG
821 % (MODEL_EFI_LIBRARY_CLASS, MODEL_EFI_LIBRARY_CLASS)\r
822 RecordSet = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)\r
823 for Record in RecordSet:\r
e7ae4a7c 824 if Record[3] and Record[4] and Record[3] != Record[4] and Record[1] != 'NULL':\r
2bcc713e
LG
825 SqlCommand = """select FullPath from File where ID = %s""" % (Record[2])\r
826 FilePathList = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
827 for FilePath in FilePathList:\r
828 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_NAME_DUPLICATE, Record[1]):\r
829 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])\r
14239f66
HC
830 \r
831 # Check the header file in Include\Library directory whether be defined in the package DEC file.\r
832 def MetaDataFileCheckLibraryDefinedInDec(self):\r
833 if EccGlobalData.gConfig.MetaDataFileCheckLibraryDefinedInDec == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
834 EdkLogger.quiet("Checking for library instance whether be defined in the package dec file ...")\r
835 SqlCommand = """\r
836 select A.Value1, A.StartLine, A.ID, B.Value1 from Inf as A left join Dec as B\r
837 on A.Model = B.Model and A.Value1 = B.Value1 where A.Model=%s\r
838 """ % MODEL_EFI_LIBRARY_CLASS\r
839 RecordSet = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)\r
840 for Record in RecordSet:\r
841 LibraryInInf, Line, ID, LibraryDec = Record\r
842 if not LibraryDec:\r
843 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_NOT_DEFINED, LibraryInInf):\r
844 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_NOT_DEFINED, \\r
845 OtherMsg="The Library Class [%s] in %s line is not defined in the associated package file." % (LibraryInInf, Line), \r
846 BelongsToTable='Inf', BelongsToItem=ID)\r
847 \r
30fdf114
LG
848 # 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\r
849 def MetaDataFileCheckBinaryInfInFdf(self):\r
850 if EccGlobalData.gConfig.MetaDataFileCheckBinaryInfInFdf == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
851 EdkLogger.quiet("Checking for non-binary modules defined in FDF files ...")\r
852 SqlCommand = """select A.ID, A.Value1 from Fdf as A\r
853 where A.Model = %s\r
854 and A.Enabled > -1\r
855 and A.Value1 not in\r
856 (select B.Value1 from Dsc as B\r
857 where B.Model = %s\r
858 and B.Enabled > -1)""" % (MODEL_META_DATA_COMPONENT, MODEL_META_DATA_COMPONENT)\r
859 RecordSet = EccGlobalData.gDb.TblFdf.Exec(SqlCommand)\r
860 for Record in RecordSet:\r
861 FdfID = Record[0]\r
862 FilePath = Record[1]\r
c4f52e12 863 FilePath = os.path.normpath(mws.join(EccGlobalData.gWorkspace, FilePath))\r
30fdf114
LG
864 SqlCommand = """select ID from Inf where Model = %s and BelongsToFile = (select ID from File where FullPath like '%s')\r
865 """ % (MODEL_EFI_SOURCE_FILE, FilePath)\r
866 NewRecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
d40b2ee6 867 if NewRecordSet != []:\r
30fdf114 868 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_BINARY_INF_IN_FDF, FilePath):\r
d40b2ee6 869 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)\r
30fdf114
LG
870\r
871 # Check whether a PCD is set in a Dsc file or the FDF file, but not in both.\r
872 def MetaDataFileCheckPcdDuplicate(self):\r
873 if EccGlobalData.gConfig.MetaDataFileCheckPcdDuplicate == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
874 EdkLogger.quiet("Checking for duplicate PCDs defined in both DSC and FDF files ...")\r
875 SqlCommand = """\r
d0acc87a 876 select A.ID, A.Value1, A.Value2, A.BelongsToFile, B.ID, B.Value1, B.Value2, B.BelongsToFile from Dsc as A, Fdf as B\r
30fdf114
LG
877 where A.Model >= %s and A.Model < %s\r
878 and B.Model >= %s and B.Model < %s\r
d0acc87a 879 and A.Value1 = B.Value1\r
30fdf114
LG
880 and A.Value2 = B.Value2\r
881 and A.Enabled > -1\r
882 and B.Enabled > -1\r
883 group by A.ID\r
d40b2ee6 884 """ % (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER)\r
30fdf114
LG
885 RecordSet = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)\r
886 for Record in RecordSet:\r
d0acc87a
LG
887 SqlCommand1 = """select Name from File where ID = %s""" % Record[3]\r
888 SqlCommand2 = """select Name from File where ID = %s""" % Record[7]\r
52302d4d
LG
889 DscFileName = os.path.splitext(EccGlobalData.gDb.TblDsc.Exec(SqlCommand1)[0][0])[0]\r
890 FdfFileName = os.path.splitext(EccGlobalData.gDb.TblDsc.Exec(SqlCommand2)[0][0])[0]\r
52302d4d
LG
891 if DscFileName != FdfFileName:\r
892 continue\r
d0acc87a
LG
893 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, Record[1] + '.' + Record[2]):\r
894 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])\r
895 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, Record[5] + '.' + Record[6]):\r
896 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])\r
30fdf114
LG
897\r
898 EdkLogger.quiet("Checking for duplicate PCDs defined in DEC files ...")\r
899 SqlCommand = """\r
d0acc87a 900 select A.ID, A.Value1, A.Value2, A.Model, B.Model from Dec as A left join Dec as B\r
30fdf114
LG
901 where A.Model >= %s and A.Model < %s\r
902 and B.Model >= %s and B.Model < %s\r
d0acc87a 903 and A.Value1 = B.Value1\r
30fdf114 904 and A.Value2 = B.Value2\r
d0acc87a
LG
905 and A.Scope1 = B.Scope1\r
906 and A.ID <> B.ID\r
907 and A.Model = B.Model\r
30fdf114
LG
908 and A.Enabled > -1\r
909 and B.Enabled > -1\r
910 and A.BelongsToFile = B.BelongsToFile\r
911 group by A.ID\r
d40b2ee6 912 """ % (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER)\r
d0acc87a 913 RecordSet = EccGlobalData.gDb.TblDec.Exec(SqlCommand)\r
30fdf114 914 for Record in RecordSet:\r
d0acc87a
LG
915 RecordCat = Record[1] + '.' + Record[2]\r
916 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, RecordCat):\r
917 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])\r
30fdf114
LG
918\r
919 # Check whether PCD settings in the FDF file can only be related to flash.\r
920 def MetaDataFileCheckPcdFlash(self):\r
921 if EccGlobalData.gConfig.MetaDataFileCheckPcdFlash == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
922 EdkLogger.quiet("Checking only Flash related PCDs are used in FDF ...")\r
923 SqlCommand = """\r
d0acc87a 924 select ID, Value1, Value2, BelongsToFile from Fdf as A\r
30fdf114
LG
925 where A.Model >= %s and Model < %s\r
926 and A.Enabled > -1\r
927 and A.Value2 not like '%%Flash%%'\r
d40b2ee6 928 """ % (MODEL_PCD, MODEL_META_DATA_HEADER)\r
30fdf114
LG
929 RecordSet = EccGlobalData.gDb.TblFdf.Exec(SqlCommand)\r
930 for Record in RecordSet:\r
d0acc87a
LG
931 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_FLASH, Record[1] + '.' + Record[2]):\r
932 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])\r
30fdf114
LG
933\r
934 # Check whether PCDs used in Inf files but not specified in Dsc or FDF files\r
935 def MetaDataFileCheckPcdNoUse(self):\r
936 if EccGlobalData.gConfig.MetaDataFileCheckPcdNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
937 EdkLogger.quiet("Checking for non-specified PCDs ...")\r
938 SqlCommand = """\r
d0acc87a 939 select ID, Value1, Value2, BelongsToFile from Inf as A\r
30fdf114
LG
940 where A.Model >= %s and Model < %s\r
941 and A.Enabled > -1\r
d0acc87a
LG
942 and (A.Value1, A.Value2) not in\r
943 (select Value1, Value2 from Dsc as B\r
30fdf114
LG
944 where B.Model >= %s and B.Model < %s\r
945 and B.Enabled > -1)\r
d0acc87a
LG
946 and (A.Value1, A.Value2) not in\r
947 (select Value1, Value2 from Fdf as C\r
30fdf114
LG
948 where C.Model >= %s and C.Model < %s\r
949 and C.Enabled > -1)\r
d40b2ee6 950 """ % (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER)\r
30fdf114
LG
951 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
952 for Record in RecordSet:\r
d0acc87a
LG
953 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_NO_USE, Record[1] + '.' + Record[2]):\r
954 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])\r
30fdf114
LG
955\r
956 # Check whether having duplicate guids defined for Guid/Protocol/Ppi\r
957 def MetaDataFileCheckGuidDuplicate(self):\r
958 if EccGlobalData.gConfig.MetaDataFileCheckGuidDuplicate == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
959 EdkLogger.quiet("Checking for duplicate GUID/PPI/PROTOCOL ...")\r
960 # Check Guid\r
961 self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID, EccGlobalData.gDb.TblDec)\r
962 self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID, EccGlobalData.gDb.TblDsc)\r
963 self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID)\r
964 # Check protocol\r
965 self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL, EccGlobalData.gDb.TblDec)\r
966 self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL, EccGlobalData.gDb.TblDsc)\r
967 self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL)\r
968 # Check ppi\r
969 self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI, EccGlobalData.gDb.TblDec)\r
970 self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI, EccGlobalData.gDb.TblDsc)\r
971 self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI)\r
972\r
973 # Check whether all files under module directory are described in INF files\r
974 def MetaDataFileCheckModuleFileNoUse(self):\r
975 if EccGlobalData.gConfig.MetaDataFileCheckModuleFileNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
976 EdkLogger.quiet("Checking for no used module files ...")\r
977 SqlCommand = """\r
d0acc87a 978 select upper(Path) from File where ID in (select BelongsToFile from Inf where BelongsToFile != -1)\r
30fdf114
LG
979 """\r
980 InfPathSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
981 InfPathList = []\r
982 for Item in InfPathSet:\r
983 if Item[0] not in InfPathList:\r
984 InfPathList.append(Item[0])\r
985 SqlCommand = """\r
986 select ID, Path, FullPath from File where upper(FullPath) not in\r
987 (select upper(A.Path) || '\\' || upper(B.Value1) from File as A, INF as B\r
988 where A.ID in (select BelongsToFile from INF where Model = %s group by BelongsToFile) and\r
989 B.BelongsToFile = A.ID and B.Model = %s)\r
990 and (Model = %s or Model = %s)\r
991 """ % (MODEL_EFI_SOURCE_FILE, MODEL_EFI_SOURCE_FILE, MODEL_FILE_C, MODEL_FILE_H)\r
992 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
993 for Record in RecordSet:\r
994 Path = Record[1]\r
b3d07ff8 995 Path = Path.upper().replace('\X64', '').replace('\IA32', '').replace('\EBC', '').replace('\IPF', '').replace('\ARM', '')\r
30fdf114
LG
996 if Path in InfPathList:\r
997 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_NO_USE, Record[2]):\r
d40b2ee6 998 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])\r
30fdf114
LG
999\r
1000 # Check whether the PCD is correctly used in C function via its type\r
1001 def MetaDataFileCheckPcdType(self):\r
1002 if EccGlobalData.gConfig.MetaDataFileCheckPcdType == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
1003 EdkLogger.quiet("Checking for pcd type in c code function usage ...")\r
1004 SqlCommand = """\r
d0acc87a 1005 select ID, Model, Value1, Value2, BelongsToFile from INF where Model > %s and Model < %s\r
30fdf114
LG
1006 """ % (MODEL_PCD, MODEL_META_DATA_HEADER)\r
1007 PcdSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
1008 for Pcd in PcdSet:\r
1009 Model = Pcd[1]\r
1010 PcdName = Pcd[2]\r
d0acc87a
LG
1011 if Pcd[3]:\r
1012 PcdName = Pcd[3]\r
1013 BelongsToFile = Pcd[4]\r
30fdf114
LG
1014 SqlCommand = """\r
1015 select ID from File where FullPath in\r
1016 (select B.Path || '\\' || A.Value1 from INF as A, File as B where A.Model = %s and A.BelongsToFile = %s\r
e56468c0 1017 and B.ID = %s and (B.Model = %s or B.Model = %s))\r
d40b2ee6 1018 """ % (MODEL_EFI_SOURCE_FILE, BelongsToFile, BelongsToFile, MODEL_FILE_C, MODEL_FILE_H)\r
30fdf114
LG
1019 TableSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
1020 for Tbl in TableSet:\r
1021 TblName = 'Identifier' + str(Tbl[0])\r
1022 SqlCommand = """\r
52302d4d 1023 select Name, ID from %s where value like '%s' and Model = %s\r
30fdf114
LG
1024 """ % (TblName, PcdName, MODEL_IDENTIFIER_FUNCTION_CALLING)\r
1025 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
1026 TblNumber = TblName.replace('Identifier', '')\r
1027 for Record in RecordSet:\r
1028 FunName = Record[0]\r
1029 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_TYPE, FunName):\r
1030 if Model in [MODEL_PCD_FIXED_AT_BUILD] and not FunName.startswith('FixedPcdGet'):\r
d40b2ee6 1031 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])\r
30fdf114 1032 if Model in [MODEL_PCD_FEATURE_FLAG] and (not FunName.startswith('FeaturePcdGet') and not FunName.startswith('FeaturePcdSet')):\r
d40b2ee6 1033 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])\r
30fdf114 1034 if Model in [MODEL_PCD_PATCHABLE_IN_MODULE] and (not FunName.startswith('PatchablePcdGet') and not FunName.startswith('PatchablePcdSet')):\r
d40b2ee6 1035 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])\r
30fdf114
LG
1036\r
1037 #ERROR_META_DATA_FILE_CHECK_PCD_TYPE\r
1038 pass\r
1039\r
40d841f6
LG
1040 # Internal worker function to get the INF workspace relative path from FileID\r
1041 def GetInfFilePathFromID(self, FileID):\r
1042 Table = EccGlobalData.gDb.TblFile\r
1043 SqlCommand = """select A.FullPath from %s as A where A.ID = %s""" % (Table.Table, FileID)\r
1044 RecordSet = Table.Exec(SqlCommand)\r
1045 Path = ""\r
1046 for Record in RecordSet:\r
c4f52e12 1047 Path = mws.relpath(Record[0], EccGlobalData.gWorkspace)\r
40d841f6 1048 return Path\r
e56468c0 1049\r
40d841f6
LG
1050 # Check whether two module INFs under one workspace has the same FILE_GUID value\r
1051 def MetaDataFileCheckModuleFileGuidDuplication(self):\r
1052 if EccGlobalData.gConfig.MetaDataFileCheckModuleFileGuidDuplication == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
1053 EdkLogger.quiet("Checking for pcd type in c code function usage ...")\r
1054 Table = EccGlobalData.gDb.TblInf\r
1055 SqlCommand = """\r
d0acc87a
LG
1056 select A.ID, A.Value3, A.BelongsToFile, B.BelongsToFile from %s as A, %s as B\r
1057 where A.Value2 = 'FILE_GUID' and B.Value2 = 'FILE_GUID' and\r
1058 A.Value3 = B.Value3 and A.ID <> B.ID group by A.ID\r
40d841f6
LG
1059 """ % (Table.Table, Table.Table)\r
1060 RecordSet = Table.Exec(SqlCommand)\r
1061 for Record in RecordSet:\r
1062 InfPath1 = self.GetInfFilePathFromID(Record[2])\r
1063 InfPath2 = self.GetInfFilePathFromID(Record[3])\r
1064 if InfPath1 and InfPath2:\r
1065 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_GUID_DUPLICATION, InfPath1):\r
1066 Msg = "The FILE_GUID of INF file [%s] is duplicated with that of %s" % (InfPath1, InfPath2)\r
d40b2ee6 1067 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_GUID_DUPLICATION, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])\r
e56468c0 1068\r
40d841f6 1069\r
b3d07ff8
HC
1070 # Check Guid Format in module INF\r
1071 def MetaDataFileCheckModuleFileGuidFormat(self):\r
f8c1facf 1072 if EccGlobalData.gConfig.MetaDataFileCheckModuleFileGuidFormat == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
b3d07ff8
HC
1073 EdkLogger.quiet("Check Guid Format in module INF ...")\r
1074 Table = EccGlobalData.gDb.TblInf\r
1075 SqlCommand = """\r
1076 select ID, Value1, Usage, BelongsToFile from %s where Model = %s group by ID\r
1077 """ % (Table.Table, MODEL_EFI_GUID)\r
1078 RecordSet = Table.Exec(SqlCommand)\r
1079 for Record in RecordSet:\r
1080 Value1 = Record[1]\r
1081 Value2 = Record[2]\r
1082 GuidCommentList = []\r
1083 InfPath = self.GetInfFilePathFromID(Record[3])\r
1084 Msg = "The GUID format of %s in INF file [%s] does not follow rules" % (Value1, InfPath)\r
1085 if Value2.startswith(DT.TAB_SPECIAL_COMMENT):\r
1086 GuidCommentList = Value2[2:].split(DT.TAB_SPECIAL_COMMENT)\r
1087 if GuidCommentList[0].strip().startswith(DT.TAB_INF_USAGE_UNDEFINED):\r
1088 continue\r
1089 elif len(GuidCommentList) > 1:\r
1090 if not GuidCommentList[0].strip().startswith((DT.TAB_INF_USAGE_PRO,\r
1091 DT.TAB_INF_USAGE_SOME_PRO,\r
1092 DT.TAB_INF_USAGE_CON,\r
1093 DT.TAB_INF_USAGE_SOME_CON)):\r
1094 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_GUID, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])\r
1095 if not (GuidCommentList[1].strip()).startswith(DT.TAB_INF_GUIDTYPE_VAR) and \\r
1096 not GuidCommentList[1].strip().startswith((DT.TAB_INF_GUIDTYPE_EVENT,\r
1097 DT.TAB_INF_GUIDTYPE_HII,\r
1098 DT.TAB_INF_GUIDTYPE_FILE,\r
1099 DT.TAB_INF_GUIDTYPE_HOB,\r
1100 DT.TAB_INF_GUIDTYPE_FV,\r
1101 DT.TAB_INF_GUIDTYPE_ST,\r
1102 DT.TAB_INF_GUIDTYPE_TSG,\r
1103 DT.TAB_INF_GUIDTYPE_GUID,\r
1104 DT.TAB_INF_GUIDTYPE_PROTOCOL,\r
1105 DT.TAB_INF_GUIDTYPE_PPI,\r
1106 DT.TAB_INF_USAGE_UNDEFINED)):\r
1107 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_GUID, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])\r
1108 else:\r
1109 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_GUID, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])\r
1110 else:\r
1111 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_GUID, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])\r
1112\r
1113 # Check Protocol Format in module INF\r
1114 def MetaDataFileCheckModuleFileProtocolFormat(self):\r
f8c1facf 1115 if EccGlobalData.gConfig.MetaDataFileCheckModuleFileProtocolFormat == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
b3d07ff8
HC
1116 EdkLogger.quiet("Check Protocol Format in module INF ...")\r
1117 Table = EccGlobalData.gDb.TblInf\r
1118 SqlCommand = """\r
1119 select ID, Value1, Usage, BelongsToFile from %s where Model = %s group by ID\r
1120 """ % (Table.Table, MODEL_EFI_PROTOCOL)\r
1121 RecordSet = Table.Exec(SqlCommand)\r
1122 for Record in RecordSet:\r
1123 Value1 = Record[1]\r
1124 Value2 = Record[2]\r
1125 GuidCommentList = []\r
1126 InfPath = self.GetInfFilePathFromID(Record[3])\r
1127 Msg = "The Protocol format of %s in INF file [%s] does not follow rules" % (Value1, InfPath)\r
1128 if Value2.startswith(DT.TAB_SPECIAL_COMMENT):\r
1129 GuidCommentList = Value2[2:].split(DT.TAB_SPECIAL_COMMENT)\r
1130 if len(GuidCommentList) >= 1:\r
1131 if not GuidCommentList[0].strip().startswith((DT.TAB_INF_USAGE_PRO,\r
1132 DT.TAB_INF_USAGE_SOME_PRO,\r
1133 DT.TAB_INF_USAGE_CON,\r
1134 DT.TAB_INF_USAGE_SOME_CON,\r
1135 DT.TAB_INF_USAGE_NOTIFY,\r
1136 DT.TAB_INF_USAGE_TO_START,\r
1137 DT.TAB_INF_USAGE_BY_START,\r
1138 DT.TAB_INF_USAGE_UNDEFINED)):\r
1139 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PROTOCOL, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])\r
1140 else:\r
1141 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PROTOCOL, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])\r
1142\r
1143\r
1144 # Check Ppi Format in module INF\r
1145 def MetaDataFileCheckModuleFilePpiFormat(self):\r
f8c1facf 1146 if EccGlobalData.gConfig.MetaDataFileCheckModuleFilePpiFormat == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
b3d07ff8
HC
1147 EdkLogger.quiet("Check Ppi Format in module INF ...")\r
1148 Table = EccGlobalData.gDb.TblInf\r
1149 SqlCommand = """\r
1150 select ID, Value1, Usage, BelongsToFile from %s where Model = %s group by ID\r
1151 """ % (Table.Table, MODEL_EFI_PPI)\r
1152 RecordSet = Table.Exec(SqlCommand)\r
1153 for Record in RecordSet:\r
1154 Value1 = Record[1]\r
1155 Value2 = Record[2]\r
1156 GuidCommentList = []\r
1157 InfPath = self.GetInfFilePathFromID(Record[3])\r
1158 Msg = "The Ppi format of %s in INF file [%s] does not follow rules" % (Value1, InfPath)\r
1159 if Value2.startswith(DT.TAB_SPECIAL_COMMENT):\r
1160 GuidCommentList = Value2[2:].split(DT.TAB_SPECIAL_COMMENT)\r
1161 if len(GuidCommentList) >= 1:\r
1162 if not GuidCommentList[0].strip().startswith((DT.TAB_INF_USAGE_PRO,\r
1163 DT.TAB_INF_USAGE_SOME_PRO,\r
1164 DT.TAB_INF_USAGE_CON,\r
1165 DT.TAB_INF_USAGE_SOME_CON,\r
1166 DT.TAB_INF_USAGE_NOTIFY,\r
1167 DT.TAB_INF_USAGE_UNDEFINED)):\r
1168 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PPI, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])\r
1169 else:\r
1170 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PPI, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])\r
1171\r
1172 # Check Pcd Format in module INF\r
1173 def MetaDataFileCheckModuleFilePcdFormat(self):\r
f8c1facf 1174 if EccGlobalData.gConfig.MetaDataFileCheckModuleFilePcdFormat == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
b3d07ff8
HC
1175 EdkLogger.quiet("Check Pcd Format in module INF ...")\r
1176 Table = EccGlobalData.gDb.TblInf\r
1177 SqlCommand = """\r
1178 select ID, Model, Value1, Value2, Usage, BelongsToFile from %s where Model >= %s and Model < %s group by ID\r
1179 """ % (Table.Table, MODEL_PCD, MODEL_META_DATA_HEADER)\r
1180 RecordSet = Table.Exec(SqlCommand)\r
1181 for Record in RecordSet:\r
1182 Model = Record[1]\r
1183 PcdName = Record[2] + '.' + Record[3]\r
1184 Usage = Record[4]\r
1185 PcdCommentList = []\r
1186 InfPath = self.GetInfFilePathFromID(Record[5])\r
1187 Msg = "The Pcd format of %s in INF file [%s] does not follow rules" % (PcdName, InfPath)\r
1188 if Usage.startswith(DT.TAB_SPECIAL_COMMENT):\r
1189 PcdCommentList = Usage[2:].split(DT.TAB_SPECIAL_COMMENT)\r
1190 if len(PcdCommentList) >= 1:\r
1191 if Model in [MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_FEATURE_FLAG] \\r
1192 and not PcdCommentList[0].strip().startswith((DT.TAB_INF_USAGE_SOME_PRO,\r
1193 DT.TAB_INF_USAGE_CON,\r
1194 DT.TAB_INF_USAGE_UNDEFINED)):\r
1195 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PCD, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])\r
1196 if Model in [MODEL_PCD_PATCHABLE_IN_MODULE, MODEL_PCD_DYNAMIC, MODEL_PCD_DYNAMIC_EX] \\r
1197 and not PcdCommentList[0].strip().startswith((DT.TAB_INF_USAGE_PRO,\r
1198 DT.TAB_INF_USAGE_SOME_PRO,\r
1199 DT.TAB_INF_USAGE_CON,\r
1200 DT.TAB_INF_USAGE_SOME_CON,\r
1201 DT.TAB_INF_USAGE_UNDEFINED)):\r
1202 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PCD, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])\r
1203 else:\r
1204 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PCD, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])\r
1205\r
30fdf114
LG
1206 # Check whether these is duplicate Guid/Ppi/Protocol name\r
1207 def CheckGuidProtocolPpi(self, ErrorID, Model, Table):\r
1208 Name = ''\r
1209 if Model == MODEL_EFI_GUID:\r
1210 Name = 'guid'\r
1211 if Model == MODEL_EFI_PROTOCOL:\r
1212 Name = 'protocol'\r
1213 if Model == MODEL_EFI_PPI:\r
1214 Name = 'ppi'\r
1215 SqlCommand = """\r
1216 select A.ID, A.Value1 from %s as A, %s as B\r
1217 where A.Model = %s and B.Model = %s\r
92e9b9f9 1218 and A.Value1 like B.Value1 and A.ID <> B.ID\r
d0acc87a 1219 and A.Scope1 = B.Scope1\r
30fdf114
LG
1220 and A.Enabled > -1\r
1221 and B.Enabled > -1\r
1222 group by A.ID\r
1223 """ % (Table.Table, Table.Table, Model, Model)\r
1224 RecordSet = Table.Exec(SqlCommand)\r
1225 for Record in RecordSet:\r
1226 if not EccGlobalData.gException.IsException(ErrorID, Record[1]):\r
d40b2ee6 1227 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])\r
30fdf114
LG
1228\r
1229 # Check whether these is duplicate Guid/Ppi/Protocol value\r
1230 def CheckGuidProtocolPpiValue(self, ErrorID, Model):\r
1231 Name = ''\r
1232 Table = EccGlobalData.gDb.TblDec\r
1233 if Model == MODEL_EFI_GUID:\r
1234 Name = 'guid'\r
1235 if Model == MODEL_EFI_PROTOCOL:\r
1236 Name = 'protocol'\r
1237 if Model == MODEL_EFI_PPI:\r
1238 Name = 'ppi'\r
1239 SqlCommand = """\r
d0acc87a 1240 select A.ID, A.Value1, A.Value2 from %s as A, %s as B\r
30fdf114 1241 where A.Model = %s and B.Model = %s\r
92e9b9f9 1242 and A.Value2 like B.Value2 and A.ID <> B.ID\r
d0acc87a 1243 and A.Scope1 = B.Scope1 and A.Value1 <> B.Value1\r
30fdf114
LG
1244 group by A.ID\r
1245 """ % (Table.Table, Table.Table, Model, Model)\r
1246 RecordSet = Table.Exec(SqlCommand)\r
d0acc87a 1247 for Record in RecordSet: \r
e84d2b70 1248 if not EccGlobalData.gException.IsException(ErrorID, Record[2]):\r
d0acc87a 1249 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])\r
30fdf114
LG
1250\r
1251 # Naming Convention Check\r
1252 def NamingConventionCheck(self):\r
52302d4d
LG
1253 if EccGlobalData.gConfig.NamingConventionCheckDefineStatement == '1' \\r
1254 or EccGlobalData.gConfig.NamingConventionCheckTypedefStatement == '1' \\r
1255 or EccGlobalData.gConfig.NamingConventionCheckIfndefStatement == '1' \\r
1256 or EccGlobalData.gConfig.NamingConventionCheckVariableName == '1' \\r
1257 or EccGlobalData.gConfig.NamingConventionCheckSingleCharacterVariable == '1' \\r
1258 or EccGlobalData.gConfig.NamingConventionCheckAll == '1'\\r
1259 or EccGlobalData.gConfig.CheckAll == '1':\r
1260 for Dirpath, Dirnames, Filenames in self.WalkTree():\r
1261 for F in Filenames:\r
1262 if os.path.splitext(F)[1] in ('.h', '.c'):\r
1263 FullName = os.path.join(Dirpath, F)\r
1264 Id = c.GetTableID(FullName)\r
1265 if Id < 0:\r
1266 continue\r
1267 FileTable = 'Identifier' + str(Id)\r
1268 self.NamingConventionCheckDefineStatement(FileTable)\r
1269 self.NamingConventionCheckTypedefStatement(FileTable)\r
52302d4d
LG
1270 self.NamingConventionCheckVariableName(FileTable)\r
1271 self.NamingConventionCheckSingleCharacterVariable(FileTable)\r
f8c1facf
HC
1272 if os.path.splitext(F)[1] in ('.h'):\r
1273 self.NamingConventionCheckIfndefStatement(FileTable)\r
30fdf114
LG
1274\r
1275 self.NamingConventionCheckPathName()\r
1276 self.NamingConventionCheckFunctionName()\r
52302d4d 1277\r
30fdf114
LG
1278 # Check whether only capital letters are used for #define declarations\r
1279 def NamingConventionCheckDefineStatement(self, FileTable):\r
1280 if EccGlobalData.gConfig.NamingConventionCheckDefineStatement == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
1281 EdkLogger.quiet("Checking naming covention of #define statement ...")\r
52302d4d 1282\r
d40b2ee6 1283 SqlCommand = """select ID, Value from %s where Model = %s""" % (FileTable, MODEL_IDENTIFIER_MACRO_DEFINE)\r
30fdf114
LG
1284 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
1285 for Record in RecordSet:\r
1286 Name = Record[1].strip().split()[1]\r
1287 if Name.find('(') != -1:\r
1288 Name = Name[0:Name.find('(')]\r
1289 if Name.upper() != Name:\r
1290 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_DEFINE_STATEMENT, Name):\r
d40b2ee6 1291 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])\r
30fdf114
LG
1292\r
1293 # Check whether only capital letters are used for typedef declarations\r
1294 def NamingConventionCheckTypedefStatement(self, FileTable):\r
1295 if EccGlobalData.gConfig.NamingConventionCheckTypedefStatement == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
1296 EdkLogger.quiet("Checking naming covention of #typedef statement ...")\r
52302d4d 1297\r
d40b2ee6 1298 SqlCommand = """select ID, Name from %s where Model = %s""" % (FileTable, MODEL_IDENTIFIER_TYPEDEF)\r
30fdf114
LG
1299 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
1300 for Record in RecordSet:\r
1301 Name = Record[1].strip()\r
4231a819 1302 if Name != '' and Name is not None:\r
30fdf114
LG
1303 if Name[0] == '(':\r
1304 Name = Name[1:Name.find(')')]\r
1305 if Name.find('(') > -1:\r
1306 Name = Name[Name.find('(') + 1 : Name.find(')')]\r
1307 Name = Name.replace('WINAPI', '')\r
1308 Name = Name.replace('*', '').strip()\r
1309 if Name.upper() != Name:\r
1310 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_TYPEDEF_STATEMENT, Name):\r
d40b2ee6 1311 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])\r
30fdf114
LG
1312\r
1313 # Check whether the #ifndef at the start of an include file uses both prefix and postfix underscore characters, '_'.\r
1314 def NamingConventionCheckIfndefStatement(self, FileTable):\r
f8c1facf 1315 if EccGlobalData.gConfig.NamingConventionCheckIfndefStatement == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
30fdf114 1316 EdkLogger.quiet("Checking naming covention of #ifndef statement ...")\r
52302d4d 1317\r
d40b2ee6 1318 SqlCommand = """select ID, Value from %s where Model = %s""" % (FileTable, MODEL_IDENTIFIER_MACRO_IFNDEF)\r
30fdf114
LG
1319 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
1320 for Record in RecordSet:\r
1321 Name = Record[1].replace('#ifndef', '').strip()\r
1322 if Name[0] != '_' or Name[-1] != '_':\r
1323 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_IFNDEF_STATEMENT, Name):\r
d40b2ee6 1324 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])\r
30fdf114
LG
1325\r
1326 # Rule for path name, variable name and function name\r
1327 # 1. First character should be upper case\r
1328 # 2. Existing lower case in a word\r
1329 # 3. No space existence\r
1330 # Check whether the path name followed the rule\r
1331 def NamingConventionCheckPathName(self):\r
1332 if EccGlobalData.gConfig.NamingConventionCheckPathName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
1333 EdkLogger.quiet("Checking naming covention of file path name ...")\r
1334 Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$')\r
1335 SqlCommand = """select ID, Name from File"""\r
1336 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
1337 for Record in RecordSet:\r
1338 if not Pattern.match(Record[1]):\r
1339 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_PATH_NAME, Record[1]):\r
d40b2ee6 1340 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])\r
30fdf114
LG
1341\r
1342 # Rule for path name, variable name and function name\r
1343 # 1. First character should be upper case\r
1344 # 2. Existing lower case in a word\r
1345 # 3. No space existence\r
1346 # 4. Global variable name must start with a 'g'\r
1347 # Check whether the variable name followed the rule\r
1348 def NamingConventionCheckVariableName(self, FileTable):\r
1349 if EccGlobalData.gConfig.NamingConventionCheckVariableName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
1350 EdkLogger.quiet("Checking naming covention of variable name ...")\r
1351 Pattern = re.compile(r'^[A-Zgm]+\S*[a-z]\S*$')\r
52302d4d 1352\r
d40b2ee6 1353 SqlCommand = """select ID, Name from %s where Model = %s""" % (FileTable, MODEL_IDENTIFIER_VARIABLE)\r
30fdf114
LG
1354 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
1355 for Record in RecordSet:\r
00261e1d
HC
1356 Var = Record[1]\r
1357 if Var.startswith('CONST'):\r
1358 Var = Var[5:].lstrip()\r
1359 if not Pattern.match(Var):\r
30fdf114 1360 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Record[1]):\r
d40b2ee6 1361 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])\r
30fdf114
LG
1362\r
1363 # Rule for path name, variable name and function name\r
1364 # 1. First character should be upper case\r
1365 # 2. Existing lower case in a word\r
1366 # 3. No space existence\r
1367 # Check whether the function name followed the rule\r
1368 def NamingConventionCheckFunctionName(self):\r
1369 if EccGlobalData.gConfig.NamingConventionCheckFunctionName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
1370 EdkLogger.quiet("Checking naming covention of function name ...")\r
1371 Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$')\r
1372 SqlCommand = """select ID, Name from Function"""\r
1373 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
1374 for Record in RecordSet:\r
1375 if not Pattern.match(Record[1]):\r
1376 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_FUNCTION_NAME, Record[1]):\r
d40b2ee6 1377 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])\r
30fdf114
LG
1378\r
1379 # Check whether NO use short variable name with single character\r
1380 def NamingConventionCheckSingleCharacterVariable(self, FileTable):\r
1381 if EccGlobalData.gConfig.NamingConventionCheckSingleCharacterVariable == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
1382 EdkLogger.quiet("Checking naming covention of single character variable name ...")\r
52302d4d 1383\r
d40b2ee6 1384 SqlCommand = """select ID, Name from %s where Model = %s""" % (FileTable, MODEL_IDENTIFIER_VARIABLE)\r
30fdf114
LG
1385 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
1386 for Record in RecordSet:\r
1387 Variable = Record[1].replace('*', '')\r
1388 if len(Variable) == 1:\r
1389 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_SINGLE_CHARACTER_VARIABLE, Record[1]):\r
d40b2ee6 1390 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])\r
30fdf114 1391\r
703ef6cf
HC
1392def FindPara(FilePath, Para, CallingLine):\r
1393 Lines = open(FilePath).readlines()\r
1394 Line = ''\r
1395 for Index in range(CallingLine - 1, 0, -1):\r
1396 # Find the nearest statement for Para\r
1397 Line = Lines[Index].strip()\r
1398 if Line.startswith('%s = ' % Para):\r
1399 Line = Line.strip()\r
1400 return Line\r
1401 break\r
1402\r
1403 return ''\r
1404\r
30fdf114
LG
1405##\r
1406#\r
1407# This acts like the main() function for the script, unless it is 'import'ed into another\r
1408# script.\r
1409#\r
1410if __name__ == '__main__':\r
1411 Check = Check()\r
1412 Check.Check()\r