]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Ecc/Check.py
Sync BaseTool trunk (version r2460) into EDKII BaseTools. The change mainly includes:
[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
40d841f6
LG
4# Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>\r
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
13import os\r
14import re\r
15from CommonDataClass.DataClass import *\r
16from Common.DataType import SUP_MODULE_LIST_STRING, TAB_VALUE_SPLIT\r
17from EccToolError import *\r
d0acc87a 18from MetaDataParser import ParseHeaderCommentSection\r
30fdf114
LG
19import EccGlobalData\r
20import c\r
21\r
22## Check\r
23#\r
24# This class is to define checkpoints used by ECC tool\r
25#\r
26# @param object: Inherited from object class\r
27#\r
28class Check(object):\r
29 def __init__(self):\r
30 pass\r
31\r
32 # Check all required checkpoints\r
33 def Check(self):\r
e56468c0 34 self.GeneralCheck()\r
30fdf114
LG
35 self.MetaDataFileCheck()\r
36 self.DoxygenCheck()\r
37 self.IncludeFileCheck()\r
38 self.PredicateExpressionCheck()\r
39 self.DeclAndDataTypeCheck()\r
40 self.FunctionLayoutCheck()\r
41 self.NamingConventionCheck()\r
42\r
e56468c0 43 # General Checking\r
44 def GeneralCheck(self):\r
45 self.GeneralCheckNonAcsii()\r
46\r
47 # Check whether file has non ACSII char\r
48 def GeneralCheckNonAcsii(self):\r
49 if EccGlobalData.gConfig.GeneralCheckNonAcsii == '1' or EccGlobalData.gConfig.GeneralCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
50 EdkLogger.quiet("Checking Non-ACSII char in file ...")\r
51 SqlCommand = """select ID, FullPath, ExtName from File"""\r
d0acc87a 52 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
e56468c0 53 for Record in RecordSet:\r
54 if Record[2].upper() not in EccGlobalData.gConfig.BinaryExtList:\r
55 op = open(Record[1]).readlines()\r
56 IndexOfLine = 0\r
57 for Line in op:\r
58 IndexOfLine += 1\r
59 IndexOfChar = 0\r
60 for Char in Line:\r
61 IndexOfChar += 1\r
62 if ord(Char) > 126:\r
d40b2ee6
LG
63 OtherMsg = "File %s has Non-ASCII char at line %s column %s" % (Record[1], IndexOfLine, IndexOfChar)\r
64 EccGlobalData.gDb.TblReport.Insert(ERROR_GENERAL_CHECK_NON_ACSII, OtherMsg=OtherMsg, BelongsToTable='File', BelongsToItem=Record[0])\r
e56468c0 65\r
30fdf114
LG
66 # C Function Layout Checking\r
67 def FunctionLayoutCheck(self):\r
68 self.FunctionLayoutCheckReturnType()\r
69 self.FunctionLayoutCheckModifier()\r
70 self.FunctionLayoutCheckName()\r
71 self.FunctionLayoutCheckPrototype()\r
72 self.FunctionLayoutCheckBody()\r
73 self.FunctionLayoutCheckLocalVariable()\r
74\r
75 def WalkTree(self):\r
76 IgnoredPattern = c.GetIgnoredDirListPattern()\r
77 for Dirpath, Dirnames, Filenames in os.walk(EccGlobalData.gTarget):\r
78 for Dir in Dirnames:\r
79 Dirname = os.path.join(Dirpath, Dir)\r
80 if os.path.islink(Dirname):\r
81 Dirname = os.path.realpath(Dirname)\r
82 if os.path.isdir(Dirname):\r
83 # symlinks to directories are treated as directories\r
84 Dirnames.remove(Dir)\r
85 Dirnames.append(Dirname)\r
86 if IgnoredPattern.match(Dirpath.upper()):\r
87 continue\r
88 yield (Dirpath, Dirnames, Filenames)\r
89\r
90 # Check whether return type exists and in the first line\r
91 def FunctionLayoutCheckReturnType(self):\r
92 if EccGlobalData.gConfig.CFunctionLayoutCheckReturnType == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
93 EdkLogger.quiet("Checking function layout return type ...")\r
94\r
e56468c0 95# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
96# for F in Filenames:\r
97# if os.path.splitext(F)[1] in ('.c', '.h'):\r
98# FullName = os.path.join(Dirpath, F)\r
99# c.CheckFuncLayoutReturnType(FullName)\r
100 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
101 c.CheckFuncLayoutReturnType(FullName)\r
30fdf114
LG
102\r
103 # Check whether any optional functional modifiers exist and next to the return type\r
104 def FunctionLayoutCheckModifier(self):\r
105 if EccGlobalData.gConfig.CFunctionLayoutCheckOptionalFunctionalModifier == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
106 EdkLogger.quiet("Checking function layout modifier ...")\r
107\r
e56468c0 108# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
109# for F in Filenames:\r
110# if os.path.splitext(F)[1] in ('.c', '.h'):\r
111# FullName = os.path.join(Dirpath, F)\r
112# c.CheckFuncLayoutModifier(FullName)\r
113 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
114 c.CheckFuncLayoutModifier(FullName)\r
30fdf114
LG
115\r
116 # Check whether the next line contains the function name, left justified, followed by the beginning of the parameter list\r
117 # Check whether the closing parenthesis is on its own line and also indented two spaces\r
118 def FunctionLayoutCheckName(self):\r
119 if EccGlobalData.gConfig.CFunctionLayoutCheckFunctionName == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
120 EdkLogger.quiet("Checking function layout function name ...")\r
121\r
e56468c0 122# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
123# for F in Filenames:\r
124# if os.path.splitext(F)[1] in ('.c', '.h'):\r
125# FullName = os.path.join(Dirpath, F)\r
126# c.CheckFuncLayoutName(FullName)\r
127 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
128 c.CheckFuncLayoutName(FullName)\r
129\r
30fdf114
LG
130 # Check whether the function prototypes in include files have the same form as function definitions\r
131 def FunctionLayoutCheckPrototype(self):\r
132 if EccGlobalData.gConfig.CFunctionLayoutCheckFunctionPrototype == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
133 EdkLogger.quiet("Checking function layout function prototype ...")\r
134\r
e56468c0 135# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
136# for F in Filenames:\r
137# if os.path.splitext(F)[1] in ('.c'):\r
138# FullName = os.path.join(Dirpath, F)\r
139# EdkLogger.quiet("[PROTOTYPE]" + FullName)\r
140# c.CheckFuncLayoutPrototype(FullName)\r
141 for FullName in EccGlobalData.gCFileList:\r
142 EdkLogger.quiet("[PROTOTYPE]" + FullName)\r
143 c.CheckFuncLayoutPrototype(FullName)\r
30fdf114
LG
144\r
145 # Check whether the body of a function is contained by open and close braces that must be in the first column\r
146 def FunctionLayoutCheckBody(self):\r
147 if EccGlobalData.gConfig.CFunctionLayoutCheckFunctionBody == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
148 EdkLogger.quiet("Checking function layout function body ...")\r
149\r
e56468c0 150# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
151# for F in Filenames:\r
152# if os.path.splitext(F)[1] in ('.c'):\r
153# FullName = os.path.join(Dirpath, F)\r
154# c.CheckFuncLayoutBody(FullName)\r
155 for FullName in EccGlobalData.gCFileList:\r
156 c.CheckFuncLayoutBody(FullName)\r
30fdf114
LG
157\r
158 # Check whether the data declarations is the first code in a module.\r
159 # self.CFunctionLayoutCheckDataDeclaration = 1\r
160 # Check whether no initialization of a variable as part of its declaration\r
161 def FunctionLayoutCheckLocalVariable(self):\r
162 if EccGlobalData.gConfig.CFunctionLayoutCheckNoInitOfVariable == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
163 EdkLogger.quiet("Checking function layout local variables ...")\r
164\r
e56468c0 165# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
166# for F in Filenames:\r
167# if os.path.splitext(F)[1] in ('.c'):\r
168# FullName = os.path.join(Dirpath, F)\r
169# c.CheckFuncLayoutLocalVariable(FullName)\r
170\r
171 for FullName in EccGlobalData.gCFileList:\r
172 c.CheckFuncLayoutLocalVariable(FullName)\r
30fdf114
LG
173\r
174 # Check whether no use of STATIC for functions\r
175 # self.CFunctionLayoutCheckNoStatic = 1\r
176\r
177 # Declarations and Data Types Checking\r
178 def DeclAndDataTypeCheck(self):\r
179 self.DeclCheckNoUseCType()\r
180 self.DeclCheckInOutModifier()\r
181 self.DeclCheckEFIAPIModifier()\r
182 self.DeclCheckEnumeratedType()\r
183 self.DeclCheckStructureDeclaration()\r
184 self.DeclCheckSameStructure()\r
185 self.DeclCheckUnionType()\r
186\r
187\r
188 # Check whether no use of int, unsigned, char, void, static, long in any .c, .h or .asl files.\r
189 def DeclCheckNoUseCType(self):\r
190 if EccGlobalData.gConfig.DeclarationDataTypeCheckNoUseCType == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
191 EdkLogger.quiet("Checking Declaration No use C type ...")\r
192\r
e56468c0 193# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
194# for F in Filenames:\r
195# if os.path.splitext(F)[1] in ('.h', '.c'):\r
196# FullName = os.path.join(Dirpath, F)\r
197# c.CheckDeclNoUseCType(FullName)\r
198 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
199 c.CheckDeclNoUseCType(FullName)\r
30fdf114
LG
200\r
201 # 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
202 def DeclCheckInOutModifier(self):\r
203 if EccGlobalData.gConfig.DeclarationDataTypeCheckInOutModifier == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
204 EdkLogger.quiet("Checking Declaration argument modifier ...")\r
205\r
e56468c0 206# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
207# for F in Filenames:\r
208# if os.path.splitext(F)[1] in ('.h', '.c'):\r
209# FullName = os.path.join(Dirpath, F)\r
210# c.CheckDeclArgModifier(FullName)\r
211 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
212 c.CheckDeclArgModifier(FullName)\r
30fdf114
LG
213\r
214 # Check whether the EFIAPI modifier should be used at the entry of drivers, events, and member functions of protocols\r
215 def DeclCheckEFIAPIModifier(self):\r
216 if EccGlobalData.gConfig.DeclarationDataTypeCheckEFIAPIModifier == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
217 pass\r
218\r
219 # Check whether Enumerated Type has a 'typedef' and the name is capital\r
220 def DeclCheckEnumeratedType(self):\r
221 if EccGlobalData.gConfig.DeclarationDataTypeCheckEnumeratedType == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
222 EdkLogger.quiet("Checking Declaration enum typedef ...")\r
223\r
e56468c0 224# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
225# for F in Filenames:\r
226# if os.path.splitext(F)[1] in ('.h', '.c'):\r
227# FullName = os.path.join(Dirpath, F)\r
228# EdkLogger.quiet("[ENUM]" + FullName)\r
229# c.CheckDeclEnumTypedef(FullName)\r
230 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
231 EdkLogger.quiet("[ENUM]" + FullName)\r
232 c.CheckDeclEnumTypedef(FullName)\r
30fdf114
LG
233\r
234 # Check whether Structure Type has a 'typedef' and the name is capital\r
235 def DeclCheckStructureDeclaration(self):\r
236 if EccGlobalData.gConfig.DeclarationDataTypeCheckStructureDeclaration == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
237 EdkLogger.quiet("Checking Declaration struct typedef ...")\r
238\r
e56468c0 239# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
240# for F in Filenames:\r
241# if os.path.splitext(F)[1] in ('.h', '.c'):\r
242# FullName = os.path.join(Dirpath, F)\r
243# EdkLogger.quiet("[STRUCT]" + FullName)\r
244# c.CheckDeclStructTypedef(FullName)\r
245 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
246 EdkLogger.quiet("[STRUCT]" + FullName)\r
247 c.CheckDeclStructTypedef(FullName)\r
30fdf114
LG
248\r
249 # Check whether having same Structure\r
250 def DeclCheckSameStructure(self):\r
251 if EccGlobalData.gConfig.DeclarationDataTypeCheckSameStructure == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
252 EdkLogger.quiet("Checking same struct ...")\r
253 AllStructure = {}\r
254 for IdentifierTable in EccGlobalData.gIdentifierTableList:\r
d40b2ee6 255 SqlCommand = """select ID, Name, BelongsToFile from %s where Model = %s""" % (IdentifierTable, MODEL_IDENTIFIER_STRUCTURE)\r
30fdf114
LG
256 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
257 for Record in RecordSet:\r
258 if Record[1] != '':\r
259 if Record[1] not in AllStructure.keys():\r
260 AllStructure[Record[1]] = Record[2]\r
261 else:\r
262 ID = AllStructure[Record[1]]\r
263 SqlCommand = """select FullPath from File where ID = %s """ % ID\r
264 NewRecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
265 OtherMsg = "The structure name '%s' is duplicate" % Record[1]\r
266 if NewRecordSet != []:\r
267 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
268 if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE, Record[1]):\r
d40b2ee6 269 EccGlobalData.gDb.TblReport.Insert(ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE, OtherMsg=OtherMsg, BelongsToTable=IdentifierTable, BelongsToItem=Record[0])\r
30fdf114
LG
270\r
271 # Check whether Union Type has a 'typedef' and the name is capital\r
272 def DeclCheckUnionType(self):\r
273 if EccGlobalData.gConfig.DeclarationDataTypeCheckUnionType == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
274 EdkLogger.quiet("Checking Declaration union typedef ...")\r
275\r
e56468c0 276# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
277# for F in Filenames:\r
278# if os.path.splitext(F)[1] in ('.h', '.c'):\r
279# FullName = os.path.join(Dirpath, F)\r
280# EdkLogger.quiet("[UNION]" + FullName)\r
281# c.CheckDeclUnionTypedef(FullName)\r
282 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
283 EdkLogger.quiet("[UNION]" + FullName)\r
284 c.CheckDeclUnionTypedef(FullName)\r
30fdf114
LG
285\r
286 # Predicate Expression Checking\r
287 def PredicateExpressionCheck(self):\r
288 self.PredicateExpressionCheckBooleanValue()\r
289 self.PredicateExpressionCheckNonBooleanOperator()\r
290 self.PredicateExpressionCheckComparisonNullType()\r
291\r
292 # Check whether Boolean values, variable type BOOLEAN not use explicit comparisons to TRUE or FALSE\r
293 def PredicateExpressionCheckBooleanValue(self):\r
294 if EccGlobalData.gConfig.PredicateExpressionCheckBooleanValue == '1' or EccGlobalData.gConfig.PredicateExpressionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
295 EdkLogger.quiet("Checking predicate expression Boolean value ...")\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# EdkLogger.quiet("[BOOLEAN]" + FullName)\r
302# c.CheckBooleanValueComparison(FullName)\r
303 for FullName in EccGlobalData.gCFileList:\r
304 EdkLogger.quiet("[BOOLEAN]" + FullName)\r
305 c.CheckBooleanValueComparison(FullName)\r
30fdf114
LG
306\r
307 # Check whether Non-Boolean comparisons use a compare operator (==, !=, >, < >=, <=).\r
308 def PredicateExpressionCheckNonBooleanOperator(self):\r
309 if EccGlobalData.gConfig.PredicateExpressionCheckNonBooleanOperator == '1' or EccGlobalData.gConfig.PredicateExpressionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
310 EdkLogger.quiet("Checking predicate expression Non-Boolean variable...")\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# EdkLogger.quiet("[NON-BOOLEAN]" + FullName)\r
317# c.CheckNonBooleanValueComparison(FullName)\r
318 for FullName in EccGlobalData.gCFileList:\r
319 EdkLogger.quiet("[NON-BOOLEAN]" + FullName)\r
320 c.CheckNonBooleanValueComparison(FullName)\r
321\r
30fdf114
LG
322 # Check whether a comparison of any pointer to zero must be done via the NULL type\r
323 def PredicateExpressionCheckComparisonNullType(self):\r
324 if EccGlobalData.gConfig.PredicateExpressionCheckComparisonNullType == '1' or EccGlobalData.gConfig.PredicateExpressionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
325 EdkLogger.quiet("Checking predicate expression NULL pointer ...")\r
326\r
e56468c0 327# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
328# for F in Filenames:\r
329# if os.path.splitext(F)[1] in ('.c'):\r
330# FullName = os.path.join(Dirpath, F)\r
331# EdkLogger.quiet("[POINTER]" + FullName)\r
332# c.CheckPointerNullComparison(FullName)\r
333 for FullName in EccGlobalData.gCFileList:\r
334 EdkLogger.quiet("[POINTER]" + FullName)\r
335 c.CheckPointerNullComparison(FullName)\r
336\r
30fdf114
LG
337 # Include file checking\r
338 def IncludeFileCheck(self):\r
339 self.IncludeFileCheckIfndef()\r
340 self.IncludeFileCheckData()\r
341 self.IncludeFileCheckSameName()\r
342\r
343 # Check whether having include files with same name\r
344 def IncludeFileCheckSameName(self):\r
345 if EccGlobalData.gConfig.IncludeFileCheckSameName == '1' or EccGlobalData.gConfig.IncludeFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
346 EdkLogger.quiet("Checking same header file name ...")\r
347 SqlCommand = """select ID, FullPath from File\r
348 where Model = 1002 order by Name """\r
349 RecordDict = {}\r
350 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
351 for Record in RecordSet:\r
352 List = Record[1].replace('/', '\\').split('\\')\r
353 if len(List) >= 2:\r
354 Key = List[-2] + '\\' + List[-1]\r
355 else:\r
356 Key = List[0]\r
357 if Key not in RecordDict:\r
358 RecordDict[Key] = [Record]\r
359 else:\r
360 RecordDict[Key].append(Record)\r
361\r
362 for Key in RecordDict:\r
363 if len(RecordDict[Key]) > 1:\r
364 for Item in RecordDict[Key]:\r
52302d4d
LG
365 Path = Item[1].replace(EccGlobalData.gWorkspace, '')\r
366 if Path.startswith('\\') or Path.startswith('/'):\r
367 Path = Path[1:]\r
368 if not EccGlobalData.gException.IsException(ERROR_INCLUDE_FILE_CHECK_NAME, Path):\r
d40b2ee6 369 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
370\r
371 # Check whether all include file contents is guarded by a #ifndef statement.\r
372 def IncludeFileCheckIfndef(self):\r
373 if EccGlobalData.gConfig.IncludeFileCheckIfndefStatement == '1' or EccGlobalData.gConfig.IncludeFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
374 EdkLogger.quiet("Checking header file ifndef ...")\r
375\r
e56468c0 376# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
377# for F in Filenames:\r
378# if os.path.splitext(F)[1] in ('.h'):\r
379# FullName = os.path.join(Dirpath, F)\r
380# MsgList = c.CheckHeaderFileIfndef(FullName)\r
381 for FullName in EccGlobalData.gHFileList:\r
382 MsgList = c.CheckHeaderFileIfndef(FullName)\r
30fdf114
LG
383\r
384 # Check whether include files NOT contain code or define data variables\r
385 def IncludeFileCheckData(self):\r
386 if EccGlobalData.gConfig.IncludeFileCheckData == '1' or EccGlobalData.gConfig.IncludeFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
387 EdkLogger.quiet("Checking header file data ...")\r
388\r
e56468c0 389# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
390# for F in Filenames:\r
391# if os.path.splitext(F)[1] in ('.h'):\r
392# FullName = os.path.join(Dirpath, F)\r
393# MsgList = c.CheckHeaderFileData(FullName)\r
394 for FullName in EccGlobalData.gHFileList:\r
395 MsgList = c.CheckHeaderFileData(FullName)\r
30fdf114
LG
396\r
397 # Doxygen document checking\r
398 def DoxygenCheck(self):\r
399 self.DoxygenCheckFileHeader()\r
400 self.DoxygenCheckFunctionHeader()\r
401 self.DoxygenCheckCommentDescription()\r
402 self.DoxygenCheckCommentFormat()\r
403 self.DoxygenCheckCommand()\r
404\r
405 # Check whether the file headers are followed Doxygen special documentation blocks in section 2.3.5\r
406 def DoxygenCheckFileHeader(self):\r
407 if EccGlobalData.gConfig.DoxygenCheckFileHeader == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
408 EdkLogger.quiet("Checking Doxygen file header ...")\r
409\r
410 for Dirpath, Dirnames, Filenames in self.WalkTree():\r
411 for F in Filenames:\r
40d841f6
LG
412 Ext = os.path.splitext(F)[1]\r
413 if Ext in ('.h', '.c'):\r
30fdf114
LG
414 FullName = os.path.join(Dirpath, F)\r
415 MsgList = c.CheckFileHeaderDoxygenComments(FullName)\r
40d841f6
LG
416 elif Ext in ('.inf', '.dec', '.dsc', '.fdf'):\r
417 FullName = os.path.join(Dirpath, F)\r
e56468c0 418 op = open(FullName).readlines()\r
d0acc87a
LG
419 FileLinesList = op\r
420 LineNo = 0\r
421 CurrentSection = MODEL_UNKNOWN \r
422 HeaderSectionLines = []\r
423 HeaderCommentStart = False \r
424 HeaderCommentEnd = False\r
425 \r
426 for Line in FileLinesList:\r
427 LineNo = LineNo + 1\r
428 Line = Line.strip()\r
429 if (LineNo < len(FileLinesList) - 1):\r
430 NextLine = FileLinesList[LineNo].strip()\r
431 \r
432 #\r
433 # blank line\r
434 #\r
435 if (Line == '' or not Line) and LineNo == len(FileLinesList):\r
436 LastSectionFalg = True\r
437\r
438 #\r
439 # check whether file header comment section started\r
440 #\r
441 if Line.startswith('#') and \\r
442 (Line.find('@file') > -1) and \\r
443 not HeaderCommentStart:\r
444 if CurrentSection != MODEL_UNKNOWN:\r
445 SqlStatement = """ select ID from File where FullPath like '%s'""" % FullName\r
446 ResultSet = EccGlobalData.gDb.TblFile.Exec(SqlStatement)\r
447 for Result in ResultSet:\r
448 Msg = 'INF/DEC/DSC/FDF file header comment should begin with ""## @file"" or ""# @file""at the very top file'\r
449 EccGlobalData.gDb.TblReport.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER, Msg, "File", Result[0])\r
450\r
451 else:\r
452 CurrentSection = MODEL_IDENTIFIER_FILE_HEADER\r
453 #\r
454 # Append the first line to section lines.\r
455 #\r
456 HeaderSectionLines.append((Line, LineNo))\r
457 HeaderCommentStart = True\r
458 continue \r
459 \r
460 #\r
461 # Collect Header content.\r
462 #\r
463 if (Line.startswith('#') and CurrentSection == MODEL_IDENTIFIER_FILE_HEADER) and\\r
464 HeaderCommentStart and not Line.startswith('##') and not\\r
465 HeaderCommentEnd and NextLine != '':\r
466 HeaderSectionLines.append((Line, LineNo))\r
467 continue\r
468 #\r
469 # Header content end\r
470 #\r
471 if (Line.startswith('##') or not Line.strip().startswith("#")) and HeaderCommentStart \\r
472 and not HeaderCommentEnd:\r
473 if Line.startswith('##'):\r
474 HeaderCommentEnd = True\r
475 HeaderSectionLines.append((Line, LineNo))\r
476 ParseHeaderCommentSection(HeaderSectionLines, FullName)\r
477 break\r
478 if HeaderCommentStart == False:\r
40d841f6
LG
479 SqlStatement = """ select ID from File where FullPath like '%s'""" % FullName\r
480 ResultSet = EccGlobalData.gDb.TblFile.Exec(SqlStatement)\r
481 for Result in ResultSet:\r
d0acc87a 482 Msg = 'INF/DEC/DSC/FDF file header comment should begin with ""## @file"" or ""# @file"" at the very top file'\r
40d841f6 483 EccGlobalData.gDb.TblReport.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER, Msg, "File", Result[0])\r
d0acc87a
LG
484 if HeaderCommentEnd == False:\r
485 SqlStatement = """ select ID from File where FullPath like '%s'""" % FullName\r
486 ResultSet = EccGlobalData.gDb.TblFile.Exec(SqlStatement)\r
487 for Result in ResultSet:\r
488 Msg = 'INF/DEC/DSC/FDF file header comment should end with ""##"" at the end of file header comment block'\r
489 # Check whether File header Comment End with '##'\r
490 if EccGlobalData.gConfig.HeaderCheckFileCommentEnd == '1' or EccGlobalData.gConfig.HeaderCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
491 EccGlobalData.gDb.TblReport.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER, Msg, "File", Result[0])\r
e56468c0 492\r
d0acc87a 493 \r
30fdf114
LG
494\r
495 # Check whether the function headers are followed Doxygen special documentation blocks in section 2.3.5\r
496 def DoxygenCheckFunctionHeader(self):\r
497 if EccGlobalData.gConfig.DoxygenCheckFunctionHeader == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
498 EdkLogger.quiet("Checking Doxygen function header ...")\r
499\r
e56468c0 500# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
501# for F in Filenames:\r
502# if os.path.splitext(F)[1] in ('.h', '.c'):\r
503# FullName = os.path.join(Dirpath, F)\r
504# MsgList = c.CheckFuncHeaderDoxygenComments(FullName)\r
505 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
506 MsgList = c.CheckFuncHeaderDoxygenComments(FullName)\r
507\r
30fdf114
LG
508\r
509 # Check whether the first line of text in a comment block is a brief description of the element being documented.\r
510 # The brief description must end with a period.\r
511 def DoxygenCheckCommentDescription(self):\r
512 if EccGlobalData.gConfig.DoxygenCheckCommentDescription == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
513 pass\r
514\r
515 # Check whether comment lines with '///< ... text ...' format, if it is used, it should be after the code section.\r
516 def DoxygenCheckCommentFormat(self):\r
517 if EccGlobalData.gConfig.DoxygenCheckCommentFormat == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
518 EdkLogger.quiet("Checking Doxygen comment ///< ...")\r
519\r
e56468c0 520# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
521# for F in Filenames:\r
522# if os.path.splitext(F)[1] in ('.h', '.c'):\r
523# FullName = os.path.join(Dirpath, F)\r
524# MsgList = c.CheckDoxygenTripleForwardSlash(FullName)\r
525 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
526 MsgList = c.CheckDoxygenTripleForwardSlash(FullName)\r
30fdf114
LG
527\r
528 # Check whether only Doxygen commands allowed to mark the code are @bug and @todo.\r
529 def DoxygenCheckCommand(self):\r
530 if EccGlobalData.gConfig.DoxygenCheckCommand == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
531 EdkLogger.quiet("Checking Doxygen command ...")\r
532\r
e56468c0 533# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
534# for F in Filenames:\r
535# if os.path.splitext(F)[1] in ('.h', '.c'):\r
536# FullName = os.path.join(Dirpath, F)\r
537# MsgList = c.CheckDoxygenCommand(FullName)\r
538 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
539 MsgList = c.CheckDoxygenCommand(FullName)\r
30fdf114
LG
540\r
541 # Meta-Data File Processing Checking\r
542 def MetaDataFileCheck(self):\r
543 self.MetaDataFileCheckPathName()\r
544 self.MetaDataFileCheckGenerateFileList()\r
545 self.MetaDataFileCheckLibraryInstance()\r
546 self.MetaDataFileCheckLibraryInstanceDependent()\r
547 self.MetaDataFileCheckLibraryInstanceOrder()\r
548 self.MetaDataFileCheckLibraryNoUse()\r
549 self.MetaDataFileCheckBinaryInfInFdf()\r
550 self.MetaDataFileCheckPcdDuplicate()\r
551 self.MetaDataFileCheckPcdFlash()\r
552 self.MetaDataFileCheckPcdNoUse()\r
553 self.MetaDataFileCheckGuidDuplicate()\r
554 self.MetaDataFileCheckModuleFileNoUse()\r
555 self.MetaDataFileCheckPcdType()\r
40d841f6 556 self.MetaDataFileCheckModuleFileGuidDuplication()\r
30fdf114
LG
557\r
558 # Check whether each file defined in meta-data exists\r
559 def MetaDataFileCheckPathName(self):\r
560 if EccGlobalData.gConfig.MetaDataFileCheckPathName == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
561 # This item is covered when parsing Inf/Dec/Dsc files\r
562 pass\r
563\r
564 # Generate a list for all files defined in meta-data files\r
565 def MetaDataFileCheckGenerateFileList(self):\r
566 if EccGlobalData.gConfig.MetaDataFileCheckGenerateFileList == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
567 # This item is covered when parsing Inf/Dec/Dsc files\r
568 pass\r
569\r
570 # Check whether all Library Instances defined for a given module (or dependent library instance) match the module's type.\r
571 # Each Library Instance must specify the Supported Module Types in its Inf file,\r
572 # and any module specifying the library instance must be one of the supported types.\r
573 def MetaDataFileCheckLibraryInstance(self):\r
574 if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstance == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
575 EdkLogger.quiet("Checking for library instance type issue ...")\r
d0acc87a
LG
576 SqlCommand = """select A.ID, A.Value3, B.Value3 from Inf as A left join Inf as B\r
577 where A.Value2 = 'LIBRARY_CLASS' and A.Model = %s\r
578 and B.Value2 = 'MODULE_TYPE' and B.Model = %s and A.BelongsToFile = B.BelongsToFile\r
30fdf114
LG
579 group by A.BelongsToFile""" % (MODEL_META_DATA_HEADER, MODEL_META_DATA_HEADER)\r
580 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
581 LibraryClasses = {}\r
582 for Record in RecordSet:\r
583 List = Record[1].split('|', 1)\r
584 SupModType = []\r
585 if len(List) == 1:\r
586 SupModType = SUP_MODULE_LIST_STRING.split(TAB_VALUE_SPLIT)\r
587 elif len(List) == 2:\r
588 SupModType = List[1].split()\r
589\r
590 if List[0] not in LibraryClasses:\r
591 LibraryClasses[List[0]] = SupModType\r
592 else:\r
593 for Item in SupModType:\r
594 if Item not in LibraryClasses[List[0]]:\r
595 LibraryClasses[List[0]].append(Item)\r
596\r
597 if Record[2] != 'BASE' and Record[2] not in SupModType:\r
d40b2ee6 598 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 599\r
d0acc87a
LG
600 SqlCommand = """select A.ID, A.Value1, B.Value3 from Inf as A left join Inf as B\r
601 where A.Model = %s and B.Value2 = '%s' and B.Model = %s\r
30fdf114
LG
602 and B.BelongsToFile = A.BelongsToFile""" \\r
603 % (MODEL_EFI_LIBRARY_CLASS, 'MODULE_TYPE', MODEL_META_DATA_HEADER)\r
604 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
605 # Merge all LibraryClasses' supmodlist\r
606 RecordDict = {}\r
607 for Record in RecordSet:\r
608 if Record[1] not in RecordDict:\r
609 RecordDict[Record[1]] = [str(Record[2])]\r
610 else:\r
611 if Record[2] not in RecordDict[Record[1]]:\r
612 RecordDict[Record[1]].append(Record[2])\r
613\r
614 for Record in RecordSet:\r
615 if Record[1] in LibraryClasses:\r
616 if Record[2] not in LibraryClasses[Record[1]] and 'BASE' not in RecordDict[Record[1]]:\r
617 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1, Record[1]):\r
d40b2ee6 618 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
619 else:\r
620 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1, Record[1]):\r
d40b2ee6 621 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
622\r
623 # Check whether a Library Instance has been defined for all dependent library classes\r
624 def MetaDataFileCheckLibraryInstanceDependent(self):\r
625 if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstanceDependent == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
626 EdkLogger.quiet("Checking for library instance dependent issue ...")\r
627 SqlCommand = """select ID, Value1, Value2 from Dsc where Model = %s""" % MODEL_EFI_LIBRARY_CLASS\r
628 LibraryClasses = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)\r
629 for LibraryClass in LibraryClasses:\r
d0acc87a
LG
630 if LibraryClass[1].upper() == 'NULL' or LibraryClass[1].startswith('!ifdef') or LibraryClass[1].startswith('!ifndef') or LibraryClass[1].endswith('!endif'):\r
631 continue\r
632 else:\r
30fdf114 633 LibraryIns = os.path.normpath(os.path.join(EccGlobalData.gWorkspace, LibraryClass[2]))\r
d0acc87a 634 SqlCommand = """select Value3 from Inf where BelongsToFile =\r
30fdf114 635 (select ID from File where lower(FullPath) = lower('%s'))\r
d0acc87a 636 and Value2 = '%s'""" % (LibraryIns, 'LIBRARY_CLASS')\r
30fdf114
LG
637 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
638 IsFound = False\r
639 for Record in RecordSet:\r
640 LibName = Record[0].split('|', 1)[0]\r
641 if LibraryClass[1] == LibName:\r
642 IsFound = True\r
643 if not IsFound:\r
644 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_DEPENDENT, LibraryClass[1]):\r
d40b2ee6 645 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
646\r
647 # Check whether the Library Instances specified by the LibraryClasses sections are listed in order of dependencies\r
648 def MetaDataFileCheckLibraryInstanceOrder(self):\r
649 if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstanceOrder == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
650 # This checkpoint is not necessary for Ecc check\r
651 pass\r
652\r
653 # Check whether the unnecessary inclusion of library classes in the Inf file\r
2bcc713e 654 # Check whether the unnecessary duplication of library classe names in the DSC file\r
30fdf114
LG
655 def MetaDataFileCheckLibraryNoUse(self):\r
656 if EccGlobalData.gConfig.MetaDataFileCheckLibraryNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
657 EdkLogger.quiet("Checking for library instance not used ...")\r
658 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
659 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
660 for Record in RecordSet:\r
661 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_NO_USE, Record[1]):\r
d40b2ee6 662 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
663 SqlCommand = """\r
664 select A.ID, A.Value1, A.BelongsToFile, A.StartLine, B.StartLine from Dsc as A left join Dsc as B\r
d0acc87a
LG
665 where A.Model = %s and B.Model = %s and A.Scope1 = B.Scope1 and A.Scope2 = B.Scope2 and A.ID <> B.ID\r
666 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
667 % (MODEL_EFI_LIBRARY_CLASS, MODEL_EFI_LIBRARY_CLASS)\r
668 RecordSet = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)\r
669 for Record in RecordSet:\r
670 if Record[3] and Record[4] and Record[3] != Record[4]:\r
671 SqlCommand = """select FullPath from File where ID = %s""" % (Record[2])\r
672 FilePathList = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
673 for FilePath in FilePathList:\r
674 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_NAME_DUPLICATE, Record[1]):\r
675 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
676 \r
30fdf114
LG
677 # 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
678 def MetaDataFileCheckBinaryInfInFdf(self):\r
679 if EccGlobalData.gConfig.MetaDataFileCheckBinaryInfInFdf == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
680 EdkLogger.quiet("Checking for non-binary modules defined in FDF files ...")\r
681 SqlCommand = """select A.ID, A.Value1 from Fdf as A\r
682 where A.Model = %s\r
683 and A.Enabled > -1\r
684 and A.Value1 not in\r
685 (select B.Value1 from Dsc as B\r
686 where B.Model = %s\r
687 and B.Enabled > -1)""" % (MODEL_META_DATA_COMPONENT, MODEL_META_DATA_COMPONENT)\r
688 RecordSet = EccGlobalData.gDb.TblFdf.Exec(SqlCommand)\r
689 for Record in RecordSet:\r
690 FdfID = Record[0]\r
691 FilePath = Record[1]\r
692 FilePath = os.path.normpath(os.path.join(EccGlobalData.gWorkspace, FilePath))\r
693 SqlCommand = """select ID from Inf where Model = %s and BelongsToFile = (select ID from File where FullPath like '%s')\r
694 """ % (MODEL_EFI_SOURCE_FILE, FilePath)\r
695 NewRecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
d40b2ee6 696 if NewRecordSet != []:\r
30fdf114 697 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_BINARY_INF_IN_FDF, FilePath):\r
d40b2ee6 698 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
699\r
700 # Check whether a PCD is set in a Dsc file or the FDF file, but not in both.\r
701 def MetaDataFileCheckPcdDuplicate(self):\r
702 if EccGlobalData.gConfig.MetaDataFileCheckPcdDuplicate == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
703 EdkLogger.quiet("Checking for duplicate PCDs defined in both DSC and FDF files ...")\r
704 SqlCommand = """\r
d0acc87a 705 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
706 where A.Model >= %s and A.Model < %s\r
707 and B.Model >= %s and B.Model < %s\r
d0acc87a 708 and A.Value1 = B.Value1\r
30fdf114
LG
709 and A.Value2 = B.Value2\r
710 and A.Enabled > -1\r
711 and B.Enabled > -1\r
712 group by A.ID\r
d40b2ee6 713 """ % (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER)\r
30fdf114
LG
714 RecordSet = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)\r
715 for Record in RecordSet:\r
d0acc87a
LG
716 SqlCommand1 = """select Name from File where ID = %s""" % Record[3]\r
717 SqlCommand2 = """select Name from File where ID = %s""" % Record[7]\r
52302d4d
LG
718 DscFileName = os.path.splitext(EccGlobalData.gDb.TblDsc.Exec(SqlCommand1)[0][0])[0]\r
719 FdfFileName = os.path.splitext(EccGlobalData.gDb.TblDsc.Exec(SqlCommand2)[0][0])[0]\r
52302d4d
LG
720 if DscFileName != FdfFileName:\r
721 continue\r
d0acc87a
LG
722 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, Record[1] + '.' + Record[2]):\r
723 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
724 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, Record[5] + '.' + Record[6]):\r
725 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
726\r
727 EdkLogger.quiet("Checking for duplicate PCDs defined in DEC files ...")\r
728 SqlCommand = """\r
d0acc87a 729 select A.ID, A.Value1, A.Value2, A.Model, B.Model from Dec as A left join Dec as B\r
30fdf114
LG
730 where A.Model >= %s and A.Model < %s\r
731 and B.Model >= %s and B.Model < %s\r
d0acc87a 732 and A.Value1 = B.Value1\r
30fdf114 733 and A.Value2 = B.Value2\r
d0acc87a
LG
734 and A.Scope1 = B.Scope1\r
735 and A.ID <> B.ID\r
736 and A.Model = B.Model\r
30fdf114
LG
737 and A.Enabled > -1\r
738 and B.Enabled > -1\r
739 and A.BelongsToFile = B.BelongsToFile\r
740 group by A.ID\r
d40b2ee6 741 """ % (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER)\r
d0acc87a 742 RecordSet = EccGlobalData.gDb.TblDec.Exec(SqlCommand)\r
30fdf114 743 for Record in RecordSet:\r
d0acc87a
LG
744 RecordCat = Record[1] + '.' + Record[2]\r
745 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, RecordCat):\r
746 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
747\r
748 # Check whether PCD settings in the FDF file can only be related to flash.\r
749 def MetaDataFileCheckPcdFlash(self):\r
750 if EccGlobalData.gConfig.MetaDataFileCheckPcdFlash == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
751 EdkLogger.quiet("Checking only Flash related PCDs are used in FDF ...")\r
752 SqlCommand = """\r
d0acc87a 753 select ID, Value1, Value2, BelongsToFile from Fdf as A\r
30fdf114
LG
754 where A.Model >= %s and Model < %s\r
755 and A.Enabled > -1\r
756 and A.Value2 not like '%%Flash%%'\r
d40b2ee6 757 """ % (MODEL_PCD, MODEL_META_DATA_HEADER)\r
30fdf114
LG
758 RecordSet = EccGlobalData.gDb.TblFdf.Exec(SqlCommand)\r
759 for Record in RecordSet:\r
d0acc87a
LG
760 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_FLASH, Record[1] + '.' + Record[2]):\r
761 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
762\r
763 # Check whether PCDs used in Inf files but not specified in Dsc or FDF files\r
764 def MetaDataFileCheckPcdNoUse(self):\r
765 if EccGlobalData.gConfig.MetaDataFileCheckPcdNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
766 EdkLogger.quiet("Checking for non-specified PCDs ...")\r
767 SqlCommand = """\r
d0acc87a 768 select ID, Value1, Value2, BelongsToFile from Inf as A\r
30fdf114
LG
769 where A.Model >= %s and Model < %s\r
770 and A.Enabled > -1\r
d0acc87a
LG
771 and (A.Value1, A.Value2) not in\r
772 (select Value1, Value2 from Dsc as B\r
30fdf114
LG
773 where B.Model >= %s and B.Model < %s\r
774 and B.Enabled > -1)\r
d0acc87a
LG
775 and (A.Value1, A.Value2) not in\r
776 (select Value1, Value2 from Fdf as C\r
30fdf114
LG
777 where C.Model >= %s and C.Model < %s\r
778 and C.Enabled > -1)\r
d40b2ee6 779 """ % (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER)\r
30fdf114
LG
780 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
781 for Record in RecordSet:\r
d0acc87a
LG
782 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_NO_USE, Record[1] + '.' + Record[2]):\r
783 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
784\r
785 # Check whether having duplicate guids defined for Guid/Protocol/Ppi\r
786 def MetaDataFileCheckGuidDuplicate(self):\r
787 if EccGlobalData.gConfig.MetaDataFileCheckGuidDuplicate == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
788 EdkLogger.quiet("Checking for duplicate GUID/PPI/PROTOCOL ...")\r
789 # Check Guid\r
790 self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID, EccGlobalData.gDb.TblDec)\r
791 self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID, EccGlobalData.gDb.TblDsc)\r
792 self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID)\r
793 # Check protocol\r
794 self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL, EccGlobalData.gDb.TblDec)\r
795 self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL, EccGlobalData.gDb.TblDsc)\r
796 self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL)\r
797 # Check ppi\r
798 self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI, EccGlobalData.gDb.TblDec)\r
799 self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI, EccGlobalData.gDb.TblDsc)\r
800 self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI)\r
801\r
802 # Check whether all files under module directory are described in INF files\r
803 def MetaDataFileCheckModuleFileNoUse(self):\r
804 if EccGlobalData.gConfig.MetaDataFileCheckModuleFileNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
805 EdkLogger.quiet("Checking for no used module files ...")\r
806 SqlCommand = """\r
d0acc87a 807 select upper(Path) from File where ID in (select BelongsToFile from Inf where BelongsToFile != -1)\r
30fdf114
LG
808 """\r
809 InfPathSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
810 InfPathList = []\r
811 for Item in InfPathSet:\r
812 if Item[0] not in InfPathList:\r
813 InfPathList.append(Item[0])\r
814 SqlCommand = """\r
815 select ID, Path, FullPath from File where upper(FullPath) not in\r
816 (select upper(A.Path) || '\\' || upper(B.Value1) from File as A, INF as B\r
817 where A.ID in (select BelongsToFile from INF where Model = %s group by BelongsToFile) and\r
818 B.BelongsToFile = A.ID and B.Model = %s)\r
819 and (Model = %s or Model = %s)\r
820 """ % (MODEL_EFI_SOURCE_FILE, MODEL_EFI_SOURCE_FILE, MODEL_FILE_C, MODEL_FILE_H)\r
821 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
822 for Record in RecordSet:\r
823 Path = Record[1]\r
824 Path = Path.upper().replace('\X64', '').replace('\IA32', '').replace('\EBC', '').replace('\IPF', '').replace('\ARM', '')\r
825 if Path in InfPathList:\r
826 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_NO_USE, Record[2]):\r
d40b2ee6 827 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
828\r
829 # Check whether the PCD is correctly used in C function via its type\r
830 def MetaDataFileCheckPcdType(self):\r
831 if EccGlobalData.gConfig.MetaDataFileCheckPcdType == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
832 EdkLogger.quiet("Checking for pcd type in c code function usage ...")\r
833 SqlCommand = """\r
d0acc87a 834 select ID, Model, Value1, Value2, BelongsToFile from INF where Model > %s and Model < %s\r
30fdf114
LG
835 """ % (MODEL_PCD, MODEL_META_DATA_HEADER)\r
836 PcdSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
837 for Pcd in PcdSet:\r
838 Model = Pcd[1]\r
839 PcdName = Pcd[2]\r
d0acc87a
LG
840 if Pcd[3]:\r
841 PcdName = Pcd[3]\r
842 BelongsToFile = Pcd[4]\r
30fdf114
LG
843 SqlCommand = """\r
844 select ID from File where FullPath in\r
845 (select B.Path || '\\' || A.Value1 from INF as A, File as B where A.Model = %s and A.BelongsToFile = %s\r
e56468c0 846 and B.ID = %s and (B.Model = %s or B.Model = %s))\r
d40b2ee6 847 """ % (MODEL_EFI_SOURCE_FILE, BelongsToFile, BelongsToFile, MODEL_FILE_C, MODEL_FILE_H)\r
30fdf114
LG
848 TableSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
849 for Tbl in TableSet:\r
850 TblName = 'Identifier' + str(Tbl[0])\r
851 SqlCommand = """\r
52302d4d 852 select Name, ID from %s where value like '%s' and Model = %s\r
30fdf114
LG
853 """ % (TblName, PcdName, MODEL_IDENTIFIER_FUNCTION_CALLING)\r
854 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
855 TblNumber = TblName.replace('Identifier', '')\r
856 for Record in RecordSet:\r
857 FunName = Record[0]\r
858 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_TYPE, FunName):\r
859 if Model in [MODEL_PCD_FIXED_AT_BUILD] and not FunName.startswith('FixedPcdGet'):\r
d40b2ee6 860 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 861 if Model in [MODEL_PCD_FEATURE_FLAG] and (not FunName.startswith('FeaturePcdGet') and not FunName.startswith('FeaturePcdSet')):\r
d40b2ee6 862 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 863 if Model in [MODEL_PCD_PATCHABLE_IN_MODULE] and (not FunName.startswith('PatchablePcdGet') and not FunName.startswith('PatchablePcdSet')):\r
d40b2ee6 864 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
865\r
866 #ERROR_META_DATA_FILE_CHECK_PCD_TYPE\r
867 pass\r
868\r
40d841f6
LG
869 # Internal worker function to get the INF workspace relative path from FileID\r
870 def GetInfFilePathFromID(self, FileID):\r
871 Table = EccGlobalData.gDb.TblFile\r
872 SqlCommand = """select A.FullPath from %s as A where A.ID = %s""" % (Table.Table, FileID)\r
873 RecordSet = Table.Exec(SqlCommand)\r
874 Path = ""\r
875 for Record in RecordSet:\r
876 Path = Record[0].replace(EccGlobalData.gWorkspace, '')\r
877 if Path.startswith('\\') or Path.startswith('/'):\r
878 Path = Path[1:]\r
879 return Path\r
e56468c0 880\r
40d841f6
LG
881 # Check whether two module INFs under one workspace has the same FILE_GUID value\r
882 def MetaDataFileCheckModuleFileGuidDuplication(self):\r
883 if EccGlobalData.gConfig.MetaDataFileCheckModuleFileGuidDuplication == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
884 EdkLogger.quiet("Checking for pcd type in c code function usage ...")\r
885 Table = EccGlobalData.gDb.TblInf\r
886 SqlCommand = """\r
d0acc87a
LG
887 select A.ID, A.Value3, A.BelongsToFile, B.BelongsToFile from %s as A, %s as B\r
888 where A.Value2 = 'FILE_GUID' and B.Value2 = 'FILE_GUID' and\r
889 A.Value3 = B.Value3 and A.ID <> B.ID group by A.ID\r
40d841f6
LG
890 """ % (Table.Table, Table.Table)\r
891 RecordSet = Table.Exec(SqlCommand)\r
892 for Record in RecordSet:\r
893 InfPath1 = self.GetInfFilePathFromID(Record[2])\r
894 InfPath2 = self.GetInfFilePathFromID(Record[3])\r
895 if InfPath1 and InfPath2:\r
896 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_GUID_DUPLICATION, InfPath1):\r
897 Msg = "The FILE_GUID of INF file [%s] is duplicated with that of %s" % (InfPath1, InfPath2)\r
d40b2ee6 898 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_GUID_DUPLICATION, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])\r
e56468c0 899\r
40d841f6 900\r
30fdf114
LG
901 # Check whether these is duplicate Guid/Ppi/Protocol name\r
902 def CheckGuidProtocolPpi(self, ErrorID, Model, Table):\r
903 Name = ''\r
904 if Model == MODEL_EFI_GUID:\r
905 Name = 'guid'\r
906 if Model == MODEL_EFI_PROTOCOL:\r
907 Name = 'protocol'\r
908 if Model == MODEL_EFI_PPI:\r
909 Name = 'ppi'\r
910 SqlCommand = """\r
911 select A.ID, A.Value1 from %s as A, %s as B\r
912 where A.Model = %s and B.Model = %s\r
913 and A.Value1 = B.Value1 and A.ID <> B.ID\r
d0acc87a 914 and A.Scope1 = B.Scope1\r
30fdf114
LG
915 and A.Enabled > -1\r
916 and B.Enabled > -1\r
917 group by A.ID\r
918 """ % (Table.Table, Table.Table, Model, Model)\r
919 RecordSet = Table.Exec(SqlCommand)\r
920 for Record in RecordSet:\r
921 if not EccGlobalData.gException.IsException(ErrorID, Record[1]):\r
d40b2ee6 922 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
923\r
924 # Check whether these is duplicate Guid/Ppi/Protocol value\r
925 def CheckGuidProtocolPpiValue(self, ErrorID, Model):\r
926 Name = ''\r
927 Table = EccGlobalData.gDb.TblDec\r
928 if Model == MODEL_EFI_GUID:\r
929 Name = 'guid'\r
930 if Model == MODEL_EFI_PROTOCOL:\r
931 Name = 'protocol'\r
932 if Model == MODEL_EFI_PPI:\r
933 Name = 'ppi'\r
934 SqlCommand = """\r
d0acc87a 935 select A.ID, A.Value1, A.Value2 from %s as A, %s as B\r
30fdf114
LG
936 where A.Model = %s and B.Model = %s\r
937 and A.Value2 = B.Value2 and A.ID <> B.ID\r
d0acc87a 938 and A.Scope1 = B.Scope1 and A.Value1 <> B.Value1\r
30fdf114
LG
939 group by A.ID\r
940 """ % (Table.Table, Table.Table, Model, Model)\r
941 RecordSet = Table.Exec(SqlCommand)\r
d0acc87a
LG
942 for Record in RecordSet: \r
943 if not EccGlobalData.gException.IsException(ErrorID, Record[1] + ':' + Record[2]):\r
944 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
945\r
946 # Naming Convention Check\r
947 def NamingConventionCheck(self):\r
52302d4d
LG
948 if EccGlobalData.gConfig.NamingConventionCheckDefineStatement == '1' \\r
949 or EccGlobalData.gConfig.NamingConventionCheckTypedefStatement == '1' \\r
950 or EccGlobalData.gConfig.NamingConventionCheckIfndefStatement == '1' \\r
951 or EccGlobalData.gConfig.NamingConventionCheckVariableName == '1' \\r
952 or EccGlobalData.gConfig.NamingConventionCheckSingleCharacterVariable == '1' \\r
953 or EccGlobalData.gConfig.NamingConventionCheckAll == '1'\\r
954 or EccGlobalData.gConfig.CheckAll == '1':\r
955 for Dirpath, Dirnames, Filenames in self.WalkTree():\r
956 for F in Filenames:\r
957 if os.path.splitext(F)[1] in ('.h', '.c'):\r
958 FullName = os.path.join(Dirpath, F)\r
959 Id = c.GetTableID(FullName)\r
960 if Id < 0:\r
961 continue\r
962 FileTable = 'Identifier' + str(Id)\r
963 self.NamingConventionCheckDefineStatement(FileTable)\r
964 self.NamingConventionCheckTypedefStatement(FileTable)\r
965 self.NamingConventionCheckIfndefStatement(FileTable)\r
966 self.NamingConventionCheckVariableName(FileTable)\r
967 self.NamingConventionCheckSingleCharacterVariable(FileTable)\r
30fdf114
LG
968\r
969 self.NamingConventionCheckPathName()\r
970 self.NamingConventionCheckFunctionName()\r
52302d4d 971\r
30fdf114
LG
972 # Check whether only capital letters are used for #define declarations\r
973 def NamingConventionCheckDefineStatement(self, FileTable):\r
974 if EccGlobalData.gConfig.NamingConventionCheckDefineStatement == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
975 EdkLogger.quiet("Checking naming covention of #define statement ...")\r
52302d4d 976\r
d40b2ee6 977 SqlCommand = """select ID, Value from %s where Model = %s""" % (FileTable, MODEL_IDENTIFIER_MACRO_DEFINE)\r
30fdf114
LG
978 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
979 for Record in RecordSet:\r
980 Name = Record[1].strip().split()[1]\r
981 if Name.find('(') != -1:\r
982 Name = Name[0:Name.find('(')]\r
983 if Name.upper() != Name:\r
984 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_DEFINE_STATEMENT, Name):\r
d40b2ee6 985 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
986\r
987 # Check whether only capital letters are used for typedef declarations\r
988 def NamingConventionCheckTypedefStatement(self, FileTable):\r
989 if EccGlobalData.gConfig.NamingConventionCheckTypedefStatement == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
990 EdkLogger.quiet("Checking naming covention of #typedef statement ...")\r
52302d4d 991\r
d40b2ee6 992 SqlCommand = """select ID, Name from %s where Model = %s""" % (FileTable, MODEL_IDENTIFIER_TYPEDEF)\r
30fdf114
LG
993 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
994 for Record in RecordSet:\r
995 Name = Record[1].strip()\r
996 if Name != '' and Name != None:\r
997 if Name[0] == '(':\r
998 Name = Name[1:Name.find(')')]\r
999 if Name.find('(') > -1:\r
1000 Name = Name[Name.find('(') + 1 : Name.find(')')]\r
1001 Name = Name.replace('WINAPI', '')\r
1002 Name = Name.replace('*', '').strip()\r
1003 if Name.upper() != Name:\r
1004 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_TYPEDEF_STATEMENT, Name):\r
d40b2ee6 1005 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
1006\r
1007 # Check whether the #ifndef at the start of an include file uses both prefix and postfix underscore characters, '_'.\r
1008 def NamingConventionCheckIfndefStatement(self, FileTable):\r
1009 if EccGlobalData.gConfig.NamingConventionCheckTypedefStatement == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
1010 EdkLogger.quiet("Checking naming covention of #ifndef statement ...")\r
52302d4d 1011\r
d40b2ee6 1012 SqlCommand = """select ID, Value from %s where Model = %s""" % (FileTable, MODEL_IDENTIFIER_MACRO_IFNDEF)\r
30fdf114
LG
1013 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
1014 for Record in RecordSet:\r
1015 Name = Record[1].replace('#ifndef', '').strip()\r
1016 if Name[0] != '_' or Name[-1] != '_':\r
1017 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_IFNDEF_STATEMENT, Name):\r
d40b2ee6 1018 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
1019\r
1020 # Rule for path name, variable name and function name\r
1021 # 1. First character should be upper case\r
1022 # 2. Existing lower case in a word\r
1023 # 3. No space existence\r
1024 # Check whether the path name followed the rule\r
1025 def NamingConventionCheckPathName(self):\r
1026 if EccGlobalData.gConfig.NamingConventionCheckPathName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
1027 EdkLogger.quiet("Checking naming covention of file path name ...")\r
1028 Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$')\r
1029 SqlCommand = """select ID, Name from File"""\r
1030 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
1031 for Record in RecordSet:\r
1032 if not Pattern.match(Record[1]):\r
1033 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_PATH_NAME, Record[1]):\r
d40b2ee6 1034 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
1035\r
1036 # Rule for path name, variable name and function name\r
1037 # 1. First character should be upper case\r
1038 # 2. Existing lower case in a word\r
1039 # 3. No space existence\r
1040 # 4. Global variable name must start with a 'g'\r
1041 # Check whether the variable name followed the rule\r
1042 def NamingConventionCheckVariableName(self, FileTable):\r
1043 if EccGlobalData.gConfig.NamingConventionCheckVariableName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
1044 EdkLogger.quiet("Checking naming covention of variable name ...")\r
1045 Pattern = re.compile(r'^[A-Zgm]+\S*[a-z]\S*$')\r
52302d4d 1046\r
d40b2ee6 1047 SqlCommand = """select ID, Name from %s where Model = %s""" % (FileTable, MODEL_IDENTIFIER_VARIABLE)\r
30fdf114
LG
1048 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
1049 for Record in RecordSet:\r
1050 if not Pattern.match(Record[1]):\r
1051 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Record[1]):\r
d40b2ee6 1052 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
1053\r
1054 # Rule for path name, variable name and function name\r
1055 # 1. First character should be upper case\r
1056 # 2. Existing lower case in a word\r
1057 # 3. No space existence\r
1058 # Check whether the function name followed the rule\r
1059 def NamingConventionCheckFunctionName(self):\r
1060 if EccGlobalData.gConfig.NamingConventionCheckFunctionName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
1061 EdkLogger.quiet("Checking naming covention of function name ...")\r
1062 Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$')\r
1063 SqlCommand = """select ID, Name from Function"""\r
1064 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
1065 for Record in RecordSet:\r
1066 if not Pattern.match(Record[1]):\r
1067 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_FUNCTION_NAME, Record[1]):\r
d40b2ee6 1068 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
1069\r
1070 # Check whether NO use short variable name with single character\r
1071 def NamingConventionCheckSingleCharacterVariable(self, FileTable):\r
1072 if EccGlobalData.gConfig.NamingConventionCheckSingleCharacterVariable == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
1073 EdkLogger.quiet("Checking naming covention of single character variable name ...")\r
52302d4d 1074\r
d40b2ee6 1075 SqlCommand = """select ID, Name from %s where Model = %s""" % (FileTable, MODEL_IDENTIFIER_VARIABLE)\r
30fdf114
LG
1076 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
1077 for Record in RecordSet:\r
1078 Variable = Record[1].replace('*', '')\r
1079 if len(Variable) == 1:\r
1080 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_SINGLE_CHARACTER_VARIABLE, Record[1]):\r
d40b2ee6 1081 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
LG
1082\r
1083##\r
1084#\r
1085# This acts like the main() function for the script, unless it is 'import'ed into another\r
1086# script.\r
1087#\r
1088if __name__ == '__main__':\r
1089 Check = Check()\r
1090 Check.Check()\r