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