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