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