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