]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Ecc/c.py
There is a limitation on WINDOWS OS for the length of entire file path can’t be large...
[mirror_edk2.git] / BaseTools / Source / Python / Ecc / c.py
CommitLineData
52302d4d
LG
1## @file\r
2# This file is used to be the c coding style checking of ECC tool\r
3#\r
1be2ed90 4# Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>\r
40d841f6 5# This program and the accompanying materials\r
52302d4d
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
13\r
30fdf114 14import sys\r
1be2ed90 15import Common.LongFilePathOs as os\r
30fdf114
LG
16import re\r
17import string\r
18import CodeFragmentCollector\r
19import FileProfile\r
20from CommonDataClass import DataClass\r
21import Database\r
22from Common import EdkLogger\r
23from EccToolError import *\r
24import EccGlobalData\r
25import MetaDataParser\r
26\r
27IncludeFileListDict = {}\r
28AllIncludeFileListDict = {}\r
29IncludePathListDict = {}\r
30ComplexTypeDict = {}\r
31SUDict = {}\r
32IgnoredKeywordList = ['EFI_ERROR']\r
33\r
34def GetIgnoredDirListPattern():\r
35 skipList = list(EccGlobalData.gConfig.SkipDirList) + ['.svn']\r
36 DirString = string.join(skipList, '|')\r
37 p = re.compile(r'.*[\\/](?:%s)[\\/]?.*' % DirString)\r
38 return p\r
39\r
40def GetFuncDeclPattern():\r
41 p = re.compile(r'(?:EFIAPI|EFI_BOOT_SERVICE|EFI_RUNTIME_SERVICE)?\s*[_\w]+\s*\(.*\)$', re.DOTALL)\r
42 return p\r
43\r
44def GetArrayPattern():\r
45 p = re.compile(r'[_\w]*\s*[\[.*\]]+')\r
46 return p\r
47\r
48def GetTypedefFuncPointerPattern():\r
49 p = re.compile('[_\w\s]*\([\w\s]*\*+\s*[_\w]+\s*\)\s*\(.*\)', re.DOTALL)\r
50 return p\r
51\r
52def GetDB():\r
53 return EccGlobalData.gDb\r
54\r
55def GetConfig():\r
56 return EccGlobalData.gConfig\r
57\r
58def PrintErrorMsg(ErrorType, Msg, TableName, ItemId):\r
59 Msg = Msg.replace('\n', '').replace('\r', '')\r
60 MsgPartList = Msg.split()\r
61 Msg = ''\r
62 for Part in MsgPartList:\r
63 Msg += Part\r
64 Msg += ' '\r
79b74a03 65 GetDB().TblReport.Insert(ErrorType, OtherMsg=Msg, BelongsToTable=TableName, BelongsToItem=ItemId)\r
30fdf114
LG
66\r
67def GetIdType(Str):\r
68 Type = DataClass.MODEL_UNKNOWN\r
69 Str = Str.replace('#', '# ')\r
70 List = Str.split()\r
71 if List[1] == 'include':\r
72 Type = DataClass.MODEL_IDENTIFIER_INCLUDE\r
73 elif List[1] == 'define':\r
74 Type = DataClass.MODEL_IDENTIFIER_MACRO_DEFINE\r
75 elif List[1] == 'ifdef':\r
76 Type = DataClass.MODEL_IDENTIFIER_MACRO_IFDEF\r
77 elif List[1] == 'ifndef':\r
78 Type = DataClass.MODEL_IDENTIFIER_MACRO_IFNDEF\r
79 elif List[1] == 'endif':\r
80 Type = DataClass.MODEL_IDENTIFIER_MACRO_ENDIF\r
81 elif List[1] == 'pragma':\r
82 Type = DataClass.MODEL_IDENTIFIER_MACRO_PROGMA\r
83 else:\r
84 Type = DataClass.MODEL_UNKNOWN\r
85 return Type\r
86\r
87def SuOccurInTypedef (Su, TdList):\r
88 for Td in TdList:\r
89 if Su.StartPos[0] == Td.StartPos[0] and Su.EndPos[0] == Td.EndPos[0]:\r
90 return True\r
91 return False\r
92\r
93def GetIdentifierList():\r
94 IdList = []\r
95 for comment in FileProfile.CommentList:\r
79b74a03 96 IdComment = DataClass.IdentifierClass(-1, '', '', '', comment.Content, DataClass.MODEL_IDENTIFIER_COMMENT, -1, -1, comment.StartPos[0], comment.StartPos[1], comment.EndPos[0], comment.EndPos[1])\r
30fdf114 97 IdList.append(IdComment)\r
52302d4d 98\r
30fdf114
LG
99 for pp in FileProfile.PPDirectiveList:\r
100 Type = GetIdType(pp.Content)\r
79b74a03 101 IdPP = DataClass.IdentifierClass(-1, '', '', '', pp.Content, Type, -1, -1, pp.StartPos[0], pp.StartPos[1], pp.EndPos[0], pp.EndPos[1])\r
30fdf114 102 IdList.append(IdPP)\r
52302d4d 103\r
30fdf114 104 for pe in FileProfile.PredicateExpressionList:\r
79b74a03 105 IdPE = DataClass.IdentifierClass(-1, '', '', '', pe.Content, DataClass.MODEL_IDENTIFIER_PREDICATE_EXPRESSION, -1, -1, pe.StartPos[0], pe.StartPos[1], pe.EndPos[0], pe.EndPos[1])\r
30fdf114 106 IdList.append(IdPE)\r
52302d4d 107\r
30fdf114
LG
108 FuncDeclPattern = GetFuncDeclPattern()\r
109 ArrayPattern = GetArrayPattern()\r
110 for var in FileProfile.VariableDeclarationList:\r
111 DeclText = var.Declarator.lstrip()\r
112 FuncPointerPattern = GetTypedefFuncPointerPattern()\r
113 if FuncPointerPattern.match(DeclText):\r
114 continue\r
115 VarNameStartLine = var.NameStartPos[0]\r
116 VarNameStartColumn = var.NameStartPos[1]\r
117 FirstChar = DeclText[0]\r
118 while not FirstChar.isalpha() and FirstChar != '_':\r
119 if FirstChar == '*':\r
120 var.Modifier += '*'\r
121 VarNameStartColumn += 1\r
122 DeclText = DeclText.lstrip('*')\r
123 elif FirstChar == '\r':\r
124 DeclText = DeclText.lstrip('\r\n').lstrip('\r')\r
125 VarNameStartLine += 1\r
126 VarNameStartColumn = 0\r
127 elif FirstChar == '\n':\r
128 DeclText = DeclText.lstrip('\n')\r
129 VarNameStartLine += 1\r
130 VarNameStartColumn = 0\r
131 elif FirstChar == ' ':\r
132 DeclText = DeclText.lstrip(' ')\r
133 VarNameStartColumn += 1\r
134 elif FirstChar == '\t':\r
135 DeclText = DeclText.lstrip('\t')\r
136 VarNameStartColumn += 8\r
137 else:\r
138 DeclText = DeclText[1:]\r
139 VarNameStartColumn += 1\r
140 FirstChar = DeclText[0]\r
52302d4d 141\r
30fdf114
LG
142 var.Declarator = DeclText\r
143 if FuncDeclPattern.match(var.Declarator):\r
52302d4d 144 DeclSplitList = var.Declarator.split('(')\r
30fdf114
LG
145 FuncName = DeclSplitList[0].strip()\r
146 FuncNamePartList = FuncName.split()\r
147 if len(FuncNamePartList) > 1:\r
148 FuncName = FuncNamePartList[-1].strip()\r
149 NameStart = DeclSplitList[0].rfind(FuncName)\r
150 var.Declarator = var.Declarator[NameStart:]\r
151 if NameStart > 0:\r
152 var.Modifier += ' ' + DeclSplitList[0][0:NameStart]\r
153 Index = 0\r
154 PreChar = ''\r
155 while Index < NameStart:\r
156 FirstChar = DeclSplitList[0][Index]\r
157 if DeclSplitList[0][Index:].startswith('EFIAPI'):\r
158 Index += 6\r
159 VarNameStartColumn += 6\r
160 PreChar = ''\r
161 continue\r
162 elif FirstChar == '\r':\r
163 Index += 1\r
164 VarNameStartLine += 1\r
165 VarNameStartColumn = 0\r
166 elif FirstChar == '\n':\r
167 Index += 1\r
168 if PreChar != '\r':\r
169 VarNameStartLine += 1\r
170 VarNameStartColumn = 0\r
171 elif FirstChar == ' ':\r
172 Index += 1\r
173 VarNameStartColumn += 1\r
174 elif FirstChar == '\t':\r
175 Index += 1\r
176 VarNameStartColumn += 8\r
177 else:\r
178 Index += 1\r
179 VarNameStartColumn += 1\r
180 PreChar = FirstChar\r
181 IdVar = DataClass.IdentifierClass(-1, var.Modifier, '', var.Declarator, FuncName, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION, -1, -1, var.StartPos[0], var.StartPos[1], VarNameStartLine, VarNameStartColumn)\r
182 IdList.append(IdVar)\r
183 continue\r
52302d4d
LG
184\r
185 if var.Declarator.find('{') == -1:\r
30fdf114
LG
186 for decl in var.Declarator.split(','):\r
187 DeclList = decl.split('=')\r
188 Name = DeclList[0].strip()\r
189 if ArrayPattern.match(Name):\r
190 LSBPos = var.Declarator.find('[')\r
191 var.Modifier += ' ' + Name[LSBPos:]\r
192 Name = Name[0:LSBPos]\r
52302d4d 193\r
79b74a03 194 IdVar = DataClass.IdentifierClass(-1, var.Modifier, '', Name, (len(DeclList) > 1 and [DeclList[1]]or [''])[0], DataClass.MODEL_IDENTIFIER_VARIABLE, -1, -1, var.StartPos[0], var.StartPos[1], VarNameStartLine, VarNameStartColumn)\r
30fdf114
LG
195 IdList.append(IdVar)\r
196 else:\r
197 DeclList = var.Declarator.split('=')\r
198 Name = DeclList[0].strip()\r
199 if ArrayPattern.match(Name):\r
200 LSBPos = var.Declarator.find('[')\r
201 var.Modifier += ' ' + Name[LSBPos:]\r
202 Name = Name[0:LSBPos]\r
79b74a03 203 IdVar = DataClass.IdentifierClass(-1, var.Modifier, '', Name, (len(DeclList) > 1 and [DeclList[1]]or [''])[0], DataClass.MODEL_IDENTIFIER_VARIABLE, -1, -1, var.StartPos[0], var.StartPos[1], VarNameStartLine, VarNameStartColumn)\r
30fdf114 204 IdList.append(IdVar)\r
52302d4d 205\r
30fdf114
LG
206 for enum in FileProfile.EnumerationDefinitionList:\r
207 LBPos = enum.Content.find('{')\r
208 RBPos = enum.Content.find('}')\r
209 Name = enum.Content[4:LBPos].strip()\r
79b74a03
LG
210 Value = enum.Content[LBPos + 1:RBPos]\r
211 IdEnum = DataClass.IdentifierClass(-1, '', '', Name, Value, DataClass.MODEL_IDENTIFIER_ENUMERATE, -1, -1, enum.StartPos[0], enum.StartPos[1], enum.EndPos[0], enum.EndPos[1])\r
30fdf114 212 IdList.append(IdEnum)\r
52302d4d 213\r
30fdf114
LG
214 for su in FileProfile.StructUnionDefinitionList:\r
215 if SuOccurInTypedef(su, FileProfile.TypedefDefinitionList):\r
216 continue\r
217 Type = DataClass.MODEL_IDENTIFIER_STRUCTURE\r
218 SkipLen = 6\r
219 if su.Content.startswith('union'):\r
220 Type = DataClass.MODEL_IDENTIFIER_UNION\r
221 SkipLen = 5\r
222 LBPos = su.Content.find('{')\r
223 RBPos = su.Content.find('}')\r
224 if LBPos == -1 or RBPos == -1:\r
225 Name = su.Content[SkipLen:].strip()\r
226 Value = ''\r
227 else:\r
228 Name = su.Content[SkipLen:LBPos].strip()\r
79b74a03
LG
229 Value = su.Content[LBPos:RBPos + 1]\r
230 IdPE = DataClass.IdentifierClass(-1, '', '', Name, Value, Type, -1, -1, su.StartPos[0], su.StartPos[1], su.EndPos[0], su.EndPos[1])\r
30fdf114 231 IdList.append(IdPE)\r
52302d4d
LG
232\r
233 TdFuncPointerPattern = GetTypedefFuncPointerPattern()\r
30fdf114
LG
234 for td in FileProfile.TypedefDefinitionList:\r
235 Modifier = ''\r
236 Name = td.ToType\r
237 Value = td.FromType\r
238 if TdFuncPointerPattern.match(td.ToType):\r
239 Modifier = td.FromType\r
240 LBPos = td.ToType.find('(')\r
79b74a03 241 TmpStr = td.ToType[LBPos + 1:].strip()\r
30fdf114
LG
242 StarPos = TmpStr.find('*')\r
243 if StarPos != -1:\r
244 Modifier += ' ' + TmpStr[0:StarPos]\r
245 while TmpStr[StarPos] == '*':\r
246# Modifier += ' ' + '*'\r
247 StarPos += 1\r
248 TmpStr = TmpStr[StarPos:].strip()\r
249 RBPos = TmpStr.find(')')\r
250 Name = TmpStr[0:RBPos]\r
251 Value = 'FP' + TmpStr[RBPos + 1:]\r
252 else:\r
253 while Name.startswith('*'):\r
254 Value += ' ' + '*'\r
255 Name = Name.lstrip('*').strip()\r
52302d4d 256\r
30fdf114
LG
257 if Name.find('[') != -1:\r
258 LBPos = Name.find('[')\r
259 RBPos = Name.rfind(']')\r
260 Value += Name[LBPos : RBPos + 1]\r
261 Name = Name[0 : LBPos]\r
52302d4d 262\r
79b74a03 263 IdTd = DataClass.IdentifierClass(-1, Modifier, '', Name, Value, DataClass.MODEL_IDENTIFIER_TYPEDEF, -1, -1, td.StartPos[0], td.StartPos[1], td.EndPos[0], td.EndPos[1])\r
30fdf114 264 IdList.append(IdTd)\r
52302d4d 265\r
30fdf114 266 for funcCall in FileProfile.FunctionCallingList:\r
79b74a03 267 IdFC = DataClass.IdentifierClass(-1, '', '', funcCall.FuncName, funcCall.ParamList, DataClass.MODEL_IDENTIFIER_FUNCTION_CALLING, -1, -1, funcCall.StartPos[0], funcCall.StartPos[1], funcCall.EndPos[0], funcCall.EndPos[1])\r
30fdf114
LG
268 IdList.append(IdFC)\r
269 return IdList\r
270\r
271def StripNonAlnumChars(Str):\r
272 StrippedStr = ''\r
273 for Char in Str:\r
274 if Char.isalnum():\r
275 StrippedStr += Char\r
276 return StrippedStr\r
277\r
79b74a03 278def GetParamList(FuncDeclarator, FuncNameLine=0, FuncNameOffset=0):\r
30fdf114
LG
279 FuncDeclarator = StripComments(FuncDeclarator)\r
280 ParamIdList = []\r
281 #DeclSplitList = FuncDeclarator.split('(')\r
282 LBPos = FuncDeclarator.find('(')\r
283 #if len(DeclSplitList) < 2:\r
284 if LBPos == -1:\r
285 return ParamIdList\r
286 #FuncName = DeclSplitList[0]\r
287 FuncName = FuncDeclarator[0:LBPos]\r
288 #ParamStr = DeclSplitList[1].rstrip(')')\r
289 ParamStr = FuncDeclarator[LBPos + 1:].rstrip(')')\r
290 LineSkipped = 0\r
291 OffsetSkipped = 0\r
292 TailChar = FuncName[-1]\r
293 while not TailChar.isalpha() and TailChar != '_':\r
52302d4d 294\r
30fdf114
LG
295 if TailChar == '\n':\r
296 FuncName = FuncName.rstrip('\r\n').rstrip('\n')\r
297 LineSkipped += 1\r
298 OffsetSkipped = 0\r
299 elif TailChar == '\r':\r
300 FuncName = FuncName.rstrip('\r')\r
301 LineSkipped += 1\r
302 OffsetSkipped = 0\r
303 elif TailChar == ' ':\r
304 FuncName = FuncName.rstrip(' ')\r
305 OffsetSkipped += 1\r
306 elif TailChar == '\t':\r
307 FuncName = FuncName.rstrip('\t')\r
308 OffsetSkipped += 8\r
309 else:\r
310 FuncName = FuncName[:-1]\r
311 TailChar = FuncName[-1]\r
52302d4d 312\r
30fdf114 313 OffsetSkipped += 1 #skip '('\r
52302d4d 314\r
30fdf114
LG
315 for p in ParamStr.split(','):\r
316 ListP = p.split()\r
317 if len(ListP) == 0:\r
318 continue\r
319 ParamName = ListP[-1]\r
320 DeclText = ParamName.strip()\r
321 RightSpacePos = p.rfind(ParamName)\r
322 ParamModifier = p[0:RightSpacePos]\r
323 if ParamName == 'OPTIONAL':\r
324 if ParamModifier == '':\r
325 ParamModifier += ' ' + 'OPTIONAL'\r
326 DeclText = ''\r
327 else:\r
328 ParamName = ListP[-2]\r
329 DeclText = ParamName.strip()\r
330 RightSpacePos = p.rfind(ParamName)\r
331 ParamModifier = p[0:RightSpacePos]\r
332 ParamModifier += 'OPTIONAL'\r
333 while DeclText.startswith('*'):\r
334 ParamModifier += ' ' + '*'\r
335 DeclText = DeclText.lstrip('*').strip()\r
336 ParamName = DeclText\r
337 # ignore array length if exists.\r
338 LBIndex = ParamName.find('[')\r
339 if LBIndex != -1:\r
340 ParamName = ParamName[0:LBIndex]\r
52302d4d 341\r
30fdf114
LG
342 Start = RightSpacePos\r
343 Index = 0\r
344 PreChar = ''\r
345 while Index < Start:\r
346 FirstChar = p[Index]\r
52302d4d 347\r
30fdf114
LG
348 if FirstChar == '\r':\r
349 Index += 1\r
350 LineSkipped += 1\r
351 OffsetSkipped = 0\r
352 elif FirstChar == '\n':\r
353 Index += 1\r
354 if PreChar != '\r':\r
355 LineSkipped += 1\r
356 OffsetSkipped = 0\r
357 elif FirstChar == ' ':\r
358 Index += 1\r
359 OffsetSkipped += 1\r
360 elif FirstChar == '\t':\r
361 Index += 1\r
362 OffsetSkipped += 8\r
363 else:\r
364 Index += 1\r
365 OffsetSkipped += 1\r
366 PreChar = FirstChar\r
52302d4d 367\r
30fdf114
LG
368 ParamBeginLine = FuncNameLine + LineSkipped\r
369 ParamBeginOffset = FuncNameOffset + OffsetSkipped\r
52302d4d 370\r
30fdf114
LG
371 Index = Start + len(ParamName)\r
372 PreChar = ''\r
373 while Index < len(p):\r
374 FirstChar = p[Index]\r
52302d4d 375\r
30fdf114
LG
376 if FirstChar == '\r':\r
377 Index += 1\r
378 LineSkipped += 1\r
379 OffsetSkipped = 0\r
380 elif FirstChar == '\n':\r
381 Index += 1\r
382 if PreChar != '\r':\r
383 LineSkipped += 1\r
384 OffsetSkipped = 0\r
385 elif FirstChar == ' ':\r
386 Index += 1\r
387 OffsetSkipped += 1\r
388 elif FirstChar == '\t':\r
389 Index += 1\r
390 OffsetSkipped += 8\r
391 else:\r
392 Index += 1\r
393 OffsetSkipped += 1\r
394 PreChar = FirstChar\r
52302d4d 395\r
30fdf114
LG
396 ParamEndLine = FuncNameLine + LineSkipped\r
397 ParamEndOffset = FuncNameOffset + OffsetSkipped\r
398 if ParamName != '...':\r
399 ParamName = StripNonAlnumChars(ParamName)\r
400 IdParam = DataClass.IdentifierClass(-1, ParamModifier, '', ParamName, '', DataClass.MODEL_IDENTIFIER_PARAMETER, -1, -1, ParamBeginLine, ParamBeginOffset, ParamEndLine, ParamEndOffset)\r
401 ParamIdList.append(IdParam)\r
52302d4d 402\r
30fdf114 403 OffsetSkipped += 1 #skip ','\r
52302d4d 404\r
30fdf114 405 return ParamIdList\r
52302d4d 406\r
30fdf114
LG
407def GetFunctionList():\r
408 FuncObjList = []\r
409 for FuncDef in FileProfile.FunctionDefinitionList:\r
410 ParamIdList = []\r
411 DeclText = FuncDef.Declarator.lstrip()\r
412 FuncNameStartLine = FuncDef.NamePos[0]\r
413 FuncNameStartColumn = FuncDef.NamePos[1]\r
414 FirstChar = DeclText[0]\r
415 while not FirstChar.isalpha() and FirstChar != '_':\r
416 if FirstChar == '*':\r
417 FuncDef.Modifier += '*'\r
418 FuncNameStartColumn += 1\r
419 DeclText = DeclText.lstrip('*')\r
420 elif FirstChar == '\r':\r
421 DeclText = DeclText.lstrip('\r\n').lstrip('\r')\r
422 FuncNameStartLine += 1\r
423 FuncNameStartColumn = 0\r
424 elif FirstChar == '\n':\r
425 DeclText = DeclText.lstrip('\n')\r
426 FuncNameStartLine += 1\r
427 FuncNameStartColumn = 0\r
428 elif FirstChar == ' ':\r
429 DeclText = DeclText.lstrip(' ')\r
430 FuncNameStartColumn += 1\r
431 elif FirstChar == '\t':\r
432 DeclText = DeclText.lstrip('\t')\r
433 FuncNameStartColumn += 8\r
434 else:\r
435 DeclText = DeclText[1:]\r
436 FuncNameStartColumn += 1\r
437 FirstChar = DeclText[0]\r
52302d4d 438\r
30fdf114
LG
439 FuncDef.Declarator = DeclText\r
440 DeclSplitList = FuncDef.Declarator.split('(')\r
441 if len(DeclSplitList) < 2:\r
442 continue\r
52302d4d 443\r
30fdf114
LG
444 FuncName = DeclSplitList[0]\r
445 FuncNamePartList = FuncName.split()\r
446 if len(FuncNamePartList) > 1:\r
447 FuncName = FuncNamePartList[-1]\r
448 NameStart = DeclSplitList[0].rfind(FuncName)\r
449 if NameStart > 0:\r
450 FuncDef.Modifier += ' ' + DeclSplitList[0][0:NameStart]\r
451 Index = 0\r
452 PreChar = ''\r
453 while Index < NameStart:\r
454 FirstChar = DeclSplitList[0][Index]\r
455 if DeclSplitList[0][Index:].startswith('EFIAPI'):\r
456 Index += 6\r
457 FuncNameStartColumn += 6\r
458 PreChar = ''\r
459 continue\r
460 elif FirstChar == '\r':\r
461 Index += 1\r
462 FuncNameStartLine += 1\r
463 FuncNameStartColumn = 0\r
464 elif FirstChar == '\n':\r
465 Index += 1\r
466 if PreChar != '\r':\r
467 FuncNameStartLine += 1\r
468 FuncNameStartColumn = 0\r
469 elif FirstChar == ' ':\r
470 Index += 1\r
471 FuncNameStartColumn += 1\r
472 elif FirstChar == '\t':\r
473 Index += 1\r
474 FuncNameStartColumn += 8\r
475 else:\r
476 Index += 1\r
477 FuncNameStartColumn += 1\r
478 PreChar = FirstChar\r
52302d4d 479\r
79b74a03 480 FuncObj = DataClass.FunctionClass(-1, FuncDef.Declarator, FuncDef.Modifier, FuncName.strip(), '', FuncDef.StartPos[0], FuncDef.StartPos[1], FuncDef.EndPos[0], FuncDef.EndPos[1], FuncDef.LeftBracePos[0], FuncDef.LeftBracePos[1], -1, ParamIdList, [], FuncNameStartLine, FuncNameStartColumn)\r
30fdf114 481 FuncObjList.append(FuncObj)\r
52302d4d 482\r
30fdf114
LG
483 return FuncObjList\r
484\r
485def GetFileModificationTimeFromDB(FullFileName):\r
486 TimeValue = 0.0\r
487 Db = GetDB()\r
488 SqlStatement = """ select TimeStamp\r
489 from File\r
490 where FullPath = \'%s\'\r
491 """ % (FullFileName)\r
492 ResultSet = Db.TblFile.Exec(SqlStatement)\r
493 for Result in ResultSet:\r
494 TimeValue = Result[0]\r
495 return TimeValue\r
496\r
497def CollectSourceCodeDataIntoDB(RootDir):\r
498 FileObjList = []\r
499 tuple = os.walk(RootDir)\r
500 IgnoredPattern = GetIgnoredDirListPattern()\r
501 ParseErrorFileList = []\r
502\r
503 for dirpath, dirnames, filenames in tuple:\r
504 if IgnoredPattern.match(dirpath.upper()):\r
505 continue\r
506\r
507 for Dir in dirnames:\r
508 Dirname = os.path.join(dirpath, Dir)\r
509 if os.path.islink(Dirname):\r
510 Dirname = os.path.realpath(Dirname)\r
511 if os.path.isdir(Dirname):\r
512 # symlinks to directories are treated as directories\r
513 dirnames.remove(Dir)\r
514 dirnames.append(Dirname)\r
515\r
516 for f in filenames:\r
e56468c0 517 collector = None\r
30fdf114 518 FullName = os.path.normpath(os.path.join(dirpath, f))\r
e56468c0 519 model = DataClass.MODEL_FILE_OTHERS\r
30fdf114
LG
520 if os.path.splitext(f)[1] in ('.h', '.c'):\r
521 EdkLogger.info("Parsing " + FullName)\r
522 model = f.endswith('c') and DataClass.MODEL_FILE_C or DataClass.MODEL_FILE_H\r
523 collector = CodeFragmentCollector.CodeFragmentCollector(FullName)\r
524 try:\r
525 collector.ParseFile()\r
526 except UnicodeError:\r
527 ParseErrorFileList.append(FullName)\r
528 collector.CleanFileProfileBuffer()\r
529 collector.ParseFileWithClearedPPDirective()\r
530# collector.PrintFragments()\r
e56468c0 531 BaseName = os.path.basename(f)\r
532 DirName = os.path.dirname(FullName)\r
533 Ext = os.path.splitext(f)[1].lstrip('.')\r
534 ModifiedTime = os.path.getmtime(FullName)\r
535 FileObj = DataClass.FileClass(-1, BaseName, Ext, DirName, FullName, model, ModifiedTime, GetFunctionList(), GetIdentifierList(), [])\r
536 FileObjList.append(FileObj)\r
537 if collector:\r
52302d4d
LG
538 collector.CleanFileProfileBuffer()\r
539\r
30fdf114
LG
540 if len(ParseErrorFileList) > 0:\r
541 EdkLogger.info("Found unrecoverable error during parsing:\n\t%s\n" % "\n\t".join(ParseErrorFileList))\r
52302d4d
LG
542\r
543 Db = GetDB()\r
544 for file in FileObjList:\r
e56468c0 545 if file.ExtName.upper() not in ['INF', 'DEC', 'DSC', 'FDF']:\r
546 Db.InsertOneFile(file)\r
30fdf114
LG
547\r
548 Db.UpdateIdentifierBelongsToFunction()\r
549\r
79b74a03 550def GetTableID(FullFileName, ErrorMsgList=None):\r
30fdf114
LG
551 if ErrorMsgList == None:\r
552 ErrorMsgList = []\r
52302d4d 553\r
30fdf114
LG
554 Db = GetDB()\r
555 SqlStatement = """ select ID\r
556 from File\r
557 where FullPath like '%s'\r
558 """ % FullFileName\r
30fdf114
LG
559 ResultSet = Db.TblFile.Exec(SqlStatement)\r
560\r
561 FileID = -1\r
562 for Result in ResultSet:\r
563 if FileID != -1:\r
564 ErrorMsgList.append('Duplicate file ID found in DB for file %s' % FullFileName)\r
79b74a03 565 return - 2\r
30fdf114
LG
566 FileID = Result[0]\r
567 if FileID == -1:\r
568 ErrorMsgList.append('NO file ID found in DB for file %s' % FullFileName)\r
79b74a03 569 return - 1\r
30fdf114
LG
570 return FileID\r
571\r
572def GetIncludeFileList(FullFileName):\r
e56468c0 573 if os.path.splitext(FullFileName)[1].upper() not in ('.H'):\r
574 return []\r
30fdf114
LG
575 IFList = IncludeFileListDict.get(FullFileName)\r
576 if IFList != None:\r
577 return IFList\r
52302d4d 578\r
30fdf114
LG
579 FileID = GetTableID(FullFileName)\r
580 if FileID < 0:\r
581 return []\r
52302d4d 582\r
30fdf114
LG
583 Db = GetDB()\r
584 FileTable = 'Identifier' + str(FileID)\r
585 SqlStatement = """ select Value\r
586 from %s\r
587 where Model = %d\r
588 """ % (FileTable, DataClass.MODEL_IDENTIFIER_INCLUDE)\r
589 ResultSet = Db.TblFile.Exec(SqlStatement)\r
590 IncludeFileListDict[FullFileName] = ResultSet\r
591 return ResultSet\r
592\r
593def GetFullPathOfIncludeFile(Str, IncludePathList):\r
594 for IncludePath in IncludePathList:\r
595 FullPath = os.path.join(IncludePath, Str)\r
596 FullPath = os.path.normpath(FullPath)\r
597 if os.path.exists(FullPath):\r
598 return FullPath\r
599 return None\r
600\r
601def GetAllIncludeFiles(FullFileName):\r
602 if AllIncludeFileListDict.get(FullFileName) != None:\r
603 return AllIncludeFileListDict.get(FullFileName)\r
52302d4d 604\r
30fdf114
LG
605 FileDirName = os.path.dirname(FullFileName)\r
606 IncludePathList = IncludePathListDict.get(FileDirName)\r
607 if IncludePathList == None:\r
608 IncludePathList = MetaDataParser.GetIncludeListOfFile(EccGlobalData.gWorkspace, FullFileName, GetDB())\r
609 if FileDirName not in IncludePathList:\r
610 IncludePathList.insert(0, FileDirName)\r
611 IncludePathListDict[FileDirName] = IncludePathList\r
612 IncludeFileQueue = []\r
613 for IncludeFile in GetIncludeFileList(FullFileName):\r
614 FileName = IncludeFile[0].lstrip('#').strip()\r
615 FileName = FileName.lstrip('include').strip()\r
616 FileName = FileName.strip('\"')\r
617 FileName = FileName.lstrip('<').rstrip('>').strip()\r
618 FullPath = GetFullPathOfIncludeFile(FileName, IncludePathList)\r
619 if FullPath != None:\r
620 IncludeFileQueue.append(FullPath)\r
52302d4d 621\r
30fdf114
LG
622 i = 0\r
623 while i < len(IncludeFileQueue):\r
624 for IncludeFile in GetIncludeFileList(IncludeFileQueue[i]):\r
625 FileName = IncludeFile[0].lstrip('#').strip()\r
626 FileName = FileName.lstrip('include').strip()\r
627 FileName = FileName.strip('\"')\r
628 FileName = FileName.lstrip('<').rstrip('>').strip()\r
629 FullPath = GetFullPathOfIncludeFile(FileName, IncludePathList)\r
630 if FullPath != None and FullPath not in IncludeFileQueue:\r
631 IncludeFileQueue.insert(i + 1, FullPath)\r
632 i += 1\r
52302d4d 633\r
30fdf114
LG
634 AllIncludeFileListDict[FullFileName] = IncludeFileQueue\r
635 return IncludeFileQueue\r
636\r
637def GetPredicateListFromPredicateExpStr(PES):\r
638\r
639 PredicateList = []\r
640 i = 0\r
641 PredicateBegin = 0\r
642 #PredicateEnd = 0\r
643 LogicOpPos = -1\r
644 p = GetFuncDeclPattern()\r
645 while i < len(PES) - 1:\r
646 if (PES[i].isalnum() or PES[i] == '_' or PES[i] == '*') and LogicOpPos > PredicateBegin:\r
647 PredicateBegin = i\r
79b74a03 648 if (PES[i] == '&' and PES[i + 1] == '&') or (PES[i] == '|' and PES[i + 1] == '|'):\r
30fdf114
LG
649 LogicOpPos = i\r
650 Exp = PES[PredicateBegin:i].strip()\r
651 # Exp may contain '.' or '->'\r
652 TmpExp = Exp.replace('.', '').replace('->', '')\r
653 if p.match(TmpExp):\r
654 PredicateList.append(Exp)\r
655 else:\r
656 PredicateList.append(Exp.rstrip(';').rstrip(')').strip())\r
657 i += 1\r
52302d4d 658\r
30fdf114
LG
659 if PredicateBegin > LogicOpPos:\r
660 while PredicateBegin < len(PES):\r
661 if PES[PredicateBegin].isalnum() or PES[PredicateBegin] == '_' or PES[PredicateBegin] == '*':\r
662 break\r
663 PredicateBegin += 1\r
664 Exp = PES[PredicateBegin:len(PES)].strip()\r
665 # Exp may contain '.' or '->'\r
666 TmpExp = Exp.replace('.', '').replace('->', '')\r
667 if p.match(TmpExp):\r
668 PredicateList.append(Exp)\r
669 else:\r
670 PredicateList.append(Exp.rstrip(';').rstrip(')').strip())\r
671 return PredicateList\r
52302d4d 672\r
79b74a03 673def GetCNameList(Lvalue, StarList=[]):\r
30fdf114
LG
674 Lvalue += ' '\r
675 i = 0\r
676 SearchBegin = 0\r
677 VarStart = -1\r
678 VarEnd = -1\r
679 VarList = []\r
52302d4d 680\r
30fdf114
LG
681 while SearchBegin < len(Lvalue):\r
682 while i < len(Lvalue):\r
683 if Lvalue[i].isalnum() or Lvalue[i] == '_':\r
684 if VarStart == -1:\r
685 VarStart = i\r
686 VarEnd = i\r
687 i += 1\r
688 elif VarEnd != -1:\r
79b74a03 689 VarList.append(Lvalue[VarStart:VarEnd + 1])\r
30fdf114
LG
690 i += 1\r
691 break\r
692 else:\r
693 if VarStart == -1 and Lvalue[i] == '*':\r
694 StarList.append('*')\r
695 i += 1\r
696 if VarEnd == -1:\r
697 break\r
52302d4d
LG
698\r
699\r
30fdf114
LG
700 DotIndex = Lvalue[VarEnd:].find('.')\r
701 ArrowIndex = Lvalue[VarEnd:].find('->')\r
702 if DotIndex == -1 and ArrowIndex == -1:\r
703 break\r
704 elif DotIndex == -1 and ArrowIndex != -1:\r
705 SearchBegin = VarEnd + ArrowIndex\r
706 elif ArrowIndex == -1 and DotIndex != -1:\r
707 SearchBegin = VarEnd + DotIndex\r
708 else:\r
52302d4d
LG
709 SearchBegin = VarEnd + ((DotIndex < ArrowIndex) and DotIndex or ArrowIndex)\r
710\r
30fdf114
LG
711 i = SearchBegin\r
712 VarStart = -1\r
713 VarEnd = -1\r
52302d4d
LG
714\r
715 return VarList\r
30fdf114 716\r
79b74a03 717def SplitPredicateByOp(Str, Op, IsFuncCalling=False):\r
30fdf114
LG
718\r
719 Name = Str.strip()\r
720 Value = None\r
52302d4d 721\r
30fdf114
LG
722 if IsFuncCalling:\r
723 Index = 0\r
724 LBFound = False\r
725 UnmatchedLBCount = 0\r
726 while Index < len(Str):\r
727 while not LBFound and Str[Index] != '_' and not Str[Index].isalnum():\r
728 Index += 1\r
52302d4d 729\r
30fdf114
LG
730 while not LBFound and (Str[Index].isalnum() or Str[Index] == '_'):\r
731 Index += 1\r
732 # maybe type-cast at the begining, skip it.\r
733 RemainingStr = Str[Index:].lstrip()\r
734 if RemainingStr.startswith(')') and not LBFound:\r
735 Index += 1\r
736 continue\r
52302d4d 737\r
30fdf114
LG
738 if RemainingStr.startswith('(') and not LBFound:\r
739 LBFound = True\r
52302d4d 740\r
30fdf114
LG
741 if Str[Index] == '(':\r
742 UnmatchedLBCount += 1\r
743 Index += 1\r
744 continue\r
52302d4d 745\r
30fdf114
LG
746 if Str[Index] == ')':\r
747 UnmatchedLBCount -= 1\r
748 Index += 1\r
749 if UnmatchedLBCount == 0:\r
750 break\r
751 continue\r
52302d4d 752\r
30fdf114 753 Index += 1\r
52302d4d 754\r
30fdf114
LG
755 if UnmatchedLBCount > 0:\r
756 return [Name]\r
52302d4d 757\r
30fdf114
LG
758 IndexInRemainingStr = Str[Index:].find(Op)\r
759 if IndexInRemainingStr == -1:\r
760 return [Name]\r
52302d4d 761\r
30fdf114 762 Name = Str[0:Index + IndexInRemainingStr].strip()\r
79b74a03 763 Value = Str[Index + IndexInRemainingStr + len(Op):].strip().strip(')')\r
30fdf114 764 return [Name, Value]\r
52302d4d 765\r
30fdf114
LG
766 TmpStr = Str.rstrip(';').rstrip(')')\r
767 while True:\r
768 Index = TmpStr.rfind(Op)\r
769 if Index == -1:\r
770 return [Name]\r
52302d4d 771\r
79b74a03 772 if Str[Index - 1].isalnum() or Str[Index - 1].isspace() or Str[Index - 1] == ')' or Str[Index - 1] == ']':\r
30fdf114
LG
773 Name = Str[0:Index].strip()\r
774 Value = Str[Index + len(Op):].strip()\r
52302d4d
LG
775 return [Name, Value]\r
776\r
30fdf114
LG
777 TmpStr = Str[0:Index - 1]\r
778\r
779def SplitPredicateStr(Str):\r
52302d4d
LG
780\r
781 Str = Str.lstrip('(')\r
30fdf114
LG
782 IsFuncCalling = False\r
783 p = GetFuncDeclPattern()\r
784 TmpStr = Str.replace('.', '').replace('->', '')\r
785 if p.match(TmpStr):\r
786 IsFuncCalling = True\r
52302d4d 787\r
30fdf114
LG
788 PredPartList = SplitPredicateByOp(Str, '==', IsFuncCalling)\r
789 if len(PredPartList) > 1:\r
790 return [PredPartList, '==']\r
52302d4d 791\r
30fdf114
LG
792 PredPartList = SplitPredicateByOp(Str, '!=', IsFuncCalling)\r
793 if len(PredPartList) > 1:\r
794 return [PredPartList, '!=']\r
52302d4d 795\r
30fdf114
LG
796 PredPartList = SplitPredicateByOp(Str, '>=', IsFuncCalling)\r
797 if len(PredPartList) > 1:\r
798 return [PredPartList, '>=']\r
52302d4d 799\r
30fdf114
LG
800 PredPartList = SplitPredicateByOp(Str, '<=', IsFuncCalling)\r
801 if len(PredPartList) > 1:\r
802 return [PredPartList, '<=']\r
52302d4d 803\r
30fdf114
LG
804 PredPartList = SplitPredicateByOp(Str, '>', IsFuncCalling)\r
805 if len(PredPartList) > 1:\r
806 return [PredPartList, '>']\r
52302d4d 807\r
30fdf114
LG
808 PredPartList = SplitPredicateByOp(Str, '<', IsFuncCalling)\r
809 if len(PredPartList) > 1:\r
810 return [PredPartList, '<']\r
52302d4d 811\r
30fdf114
LG
812 return [[Str, None], None]\r
813\r
814def GetFuncContainsPE(ExpLine, ResultSet):\r
815 for Result in ResultSet:\r
816 if Result[0] < ExpLine and Result[1] > ExpLine:\r
817 return Result\r
818 return None\r
819\r
820def PatternInModifier(Modifier, SubStr):\r
821 PartList = Modifier.split()\r
822 for Part in PartList:\r
823 if Part == SubStr:\r
824 return True\r
825 return False\r
826\r
827def GetDataTypeFromModifier(ModifierStr):\r
828 MList = ModifierStr.split()\r
79b74a03 829 ReturnType = ''\r
30fdf114
LG
830 for M in MList:\r
831 if M in EccGlobalData.gConfig.ModifierList:\r
79b74a03 832 continue\r
30fdf114 833 # remove array sufix\r
79b74a03
LG
834 if M.startswith('[') or M.endswith(']'):\r
835 continue\r
30fdf114 836 ReturnType += M + ' '\r
52302d4d 837\r
30fdf114
LG
838 ReturnType = ReturnType.strip()\r
839 if len(ReturnType) == 0:\r
840 ReturnType = 'VOID'\r
841 return ReturnType\r
842\r
843def DiffModifier(Str1, Str2):\r
844 PartList1 = Str1.split()\r
845 PartList2 = Str2.split()\r
846 if PartList1 == PartList2:\r
847 return False\r
848 else:\r
849 return True\r
52302d4d 850\r
30fdf114 851def GetTypedefDict(FullFileName):\r
52302d4d 852\r
30fdf114
LG
853 Dict = ComplexTypeDict.get(FullFileName)\r
854 if Dict != None:\r
855 return Dict\r
52302d4d 856\r
30fdf114
LG
857 FileID = GetTableID(FullFileName)\r
858 FileTable = 'Identifier' + str(FileID)\r
859 Db = GetDB()\r
860 SqlStatement = """ select Modifier, Name, Value, ID\r
861 from %s\r
862 where Model = %d\r
863 """ % (FileTable, DataClass.MODEL_IDENTIFIER_TYPEDEF)\r
864 ResultSet = Db.TblFile.Exec(SqlStatement)\r
52302d4d 865\r
30fdf114
LG
866 Dict = {}\r
867 for Result in ResultSet:\r
868 if len(Result[0]) == 0:\r
869 Dict[Result[1]] = Result[2]\r
52302d4d 870\r
30fdf114
LG
871 IncludeFileList = GetAllIncludeFiles(FullFileName)\r
872 for F in IncludeFileList:\r
873 FileID = GetTableID(F)\r
874 if FileID < 0:\r
875 continue\r
52302d4d 876\r
30fdf114
LG
877 FileTable = 'Identifier' + str(FileID)\r
878 SqlStatement = """ select Modifier, Name, Value, ID\r
879 from %s\r
880 where Model = %d\r
881 """ % (FileTable, DataClass.MODEL_IDENTIFIER_TYPEDEF)\r
882 ResultSet = Db.TblFile.Exec(SqlStatement)\r
52302d4d 883\r
30fdf114
LG
884 for Result in ResultSet:\r
885 if not Result[2].startswith('FP ('):\r
886 Dict[Result[1]] = Result[2]\r
887 else:\r
888 if len(Result[0]) == 0:\r
889 Dict[Result[1]] = 'VOID'\r
890 else:\r
891 Dict[Result[1]] = GetDataTypeFromModifier(Result[0])\r
52302d4d 892\r
30fdf114
LG
893 ComplexTypeDict[FullFileName] = Dict\r
894 return Dict\r
895\r
896def GetSUDict(FullFileName):\r
52302d4d 897\r
30fdf114
LG
898 Dict = SUDict.get(FullFileName)\r
899 if Dict != None:\r
900 return Dict\r
52302d4d 901\r
30fdf114
LG
902 FileID = GetTableID(FullFileName)\r
903 FileTable = 'Identifier' + str(FileID)\r
904 Db = GetDB()\r
905 SqlStatement = """ select Name, Value, ID\r
906 from %s\r
907 where Model = %d or Model = %d\r
908 """ % (FileTable, DataClass.MODEL_IDENTIFIER_STRUCTURE, DataClass.MODEL_IDENTIFIER_UNION)\r
909 ResultSet = Db.TblFile.Exec(SqlStatement)\r
52302d4d 910\r
30fdf114
LG
911 Dict = {}\r
912 for Result in ResultSet:\r
913 if len(Result[1]) > 0:\r
914 Dict[Result[0]] = Result[1]\r
52302d4d 915\r
30fdf114
LG
916 IncludeFileList = GetAllIncludeFiles(FullFileName)\r
917 for F in IncludeFileList:\r
918 FileID = GetTableID(F)\r
919 if FileID < 0:\r
920 continue\r
52302d4d 921\r
30fdf114
LG
922 FileTable = 'Identifier' + str(FileID)\r
923 SqlStatement = """ select Name, Value, ID\r
924 from %s\r
925 where Model = %d or Model = %d\r
926 """ % (FileTable, DataClass.MODEL_IDENTIFIER_STRUCTURE, DataClass.MODEL_IDENTIFIER_UNION)\r
927 ResultSet = Db.TblFile.Exec(SqlStatement)\r
52302d4d 928\r
30fdf114
LG
929 for Result in ResultSet:\r
930 if len(Result[1]) > 0:\r
931 Dict[Result[0]] = Result[1]\r
52302d4d 932\r
30fdf114
LG
933 SUDict[FullFileName] = Dict\r
934 return Dict\r
935\r
936def StripComments(Str):\r
937 Str += ' '\r
938 ListFromStr = list(Str)\r
52302d4d 939\r
30fdf114
LG
940 InComment = False\r
941 DoubleSlashComment = False\r
942 Index = 0\r
943 while Index < len(ListFromStr):\r
944 # meet new line, then no longer in a comment for //\r
945 if ListFromStr[Index] == '\n':\r
946 if InComment and DoubleSlashComment:\r
947 InComment = False\r
948 DoubleSlashComment = False\r
949 Index += 1\r
950 # check for */ comment end\r
79b74a03 951 elif InComment and not DoubleSlashComment and ListFromStr[Index] == '*' and ListFromStr[Index + 1] == '/':\r
30fdf114
LG
952 ListFromStr[Index] = ' '\r
953 Index += 1\r
954 ListFromStr[Index] = ' '\r
955 Index += 1\r
956 InComment = False\r
957 # set comments to spaces\r
958 elif InComment:\r
959 ListFromStr[Index] = ' '\r
960 Index += 1\r
961 # check for // comment\r
79b74a03 962 elif ListFromStr[Index] == '/' and ListFromStr[Index + 1] == '/' and ListFromStr[Index + 2] != '\n':\r
30fdf114
LG
963 InComment = True\r
964 DoubleSlashComment = True\r
52302d4d 965\r
30fdf114 966 # check for /* comment start\r
79b74a03 967 elif ListFromStr[Index] == '/' and ListFromStr[Index + 1] == '*':\r
30fdf114
LG
968 ListFromStr[Index] = ' '\r
969 Index += 1\r
970 ListFromStr[Index] = ' '\r
971 Index += 1\r
972 InComment = True\r
973 else:\r
974 Index += 1\r
975\r
976 # restore from List to String\r
977 Str = "".join(ListFromStr)\r
978 Str = Str.rstrip(' ')\r
52302d4d 979\r
30fdf114
LG
980 return Str\r
981\r
982def GetFinalTypeValue(Type, FieldName, TypedefDict, SUDict):\r
983 Value = TypedefDict.get(Type)\r
984 if Value == None:\r
985 Value = SUDict.get(Type)\r
986 if Value == None:\r
987 return None\r
52302d4d 988\r
30fdf114
LG
989 LBPos = Value.find('{')\r
990 while LBPos == -1:\r
991 FTList = Value.split()\r
992 for FT in FTList:\r
993 if FT not in ('struct', 'union'):\r
994 Value = TypedefDict.get(FT)\r
995 if Value == None:\r
996 Value = SUDict.get(FT)\r
997 break\r
52302d4d 998\r
30fdf114
LG
999 if Value == None:\r
1000 return None\r
52302d4d 1001\r
30fdf114 1002 LBPos = Value.find('{')\r
52302d4d 1003\r
30fdf114
LG
1004# RBPos = Value.find('}')\r
1005 Fields = Value[LBPos + 1:]\r
1006 Fields = StripComments(Fields)\r
1007 FieldsList = Fields.split(';')\r
1008 for Field in FieldsList:\r
1009 Field = Field.strip()\r
1010 Index = Field.rfind(FieldName)\r
1011 if Index < 1:\r
1012 continue\r
1013 if not Field[Index - 1].isalnum():\r
1014 if Index + len(FieldName) == len(Field):\r
1015 Type = GetDataTypeFromModifier(Field[0:Index])\r
1016 return Type.strip()\r
1017 else:\r
52302d4d 1018 # For the condition that the field in struct is an array with [] sufixes...\r
30fdf114
LG
1019 if not Field[Index + len(FieldName)].isalnum():\r
1020 Type = GetDataTypeFromModifier(Field[0:Index])\r
1021 return Type.strip()\r
52302d4d 1022\r
30fdf114 1023 return None\r
52302d4d 1024\r
79b74a03 1025def GetRealType(Type, TypedefDict, TargetType=None):\r
30fdf114
LG
1026 if TargetType != None and Type == TargetType:\r
1027 return Type\r
1028 while TypedefDict.get(Type):\r
1029 Type = TypedefDict.get(Type)\r
1030 if TargetType != None and Type == TargetType:\r
1031 return Type\r
1032 return Type\r
1033\r
79b74a03 1034def GetTypeInfo(RefList, Modifier, FullFileName, TargetType=None):\r
30fdf114
LG
1035 TypedefDict = GetTypedefDict(FullFileName)\r
1036 SUDict = GetSUDict(FullFileName)\r
1037 Type = GetDataTypeFromModifier(Modifier).replace('*', '').strip()\r
52302d4d 1038\r
30fdf114
LG
1039 Type = Type.split()[-1]\r
1040 Index = 0\r
1041 while Index < len(RefList):\r
1042 FieldName = RefList[Index]\r
1043 FromType = GetFinalTypeValue(Type, FieldName, TypedefDict, SUDict)\r
1044 if FromType == None:\r
1045 return None\r
1046 # we want to determine the exact type.\r
1047 if TargetType != None:\r
1048 Type = FromType.split()[0]\r
1049 # we only want to check if it is a pointer\r
1050 else:\r
1051 Type = FromType\r
79b74a03 1052 if Type.find('*') != -1 and Index == len(RefList) - 1:\r
30fdf114
LG
1053 return Type\r
1054 Type = FromType.split()[0]\r
52302d4d 1055\r
30fdf114
LG
1056 Index += 1\r
1057\r
1058 Type = GetRealType(Type, TypedefDict, TargetType)\r
1059\r
1060 return Type\r
1061\r
79b74a03 1062def GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall=False, TargetType=None, StarList=None):\r
52302d4d 1063\r
30fdf114
LG
1064 PredVar = PredVarList[0]\r
1065 FileID = GetTableID(FullFileName)\r
52302d4d 1066\r
30fdf114
LG
1067 Db = GetDB()\r
1068 FileTable = 'Identifier' + str(FileID)\r
1069 # search variable in include files\r
52302d4d 1070\r
30fdf114
LG
1071 # it is a function call, search function declarations and definitions\r
1072 if IsFuncCall:\r
1073 SqlStatement = """ select Modifier, ID\r
1074 from %s\r
1075 where Model = %d and Value = \'%s\'\r
1076 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION, PredVar)\r
1077 ResultSet = Db.TblFile.Exec(SqlStatement)\r
52302d4d
LG
1078\r
1079 for Result in ResultSet:\r
30fdf114
LG
1080 Type = GetDataTypeFromModifier(Result[0]).split()[-1]\r
1081 TypedefDict = GetTypedefDict(FullFileName)\r
1082 Type = GetRealType(Type, TypedefDict, TargetType)\r
1083 return Type\r
52302d4d 1084\r
30fdf114
LG
1085 IncludeFileList = GetAllIncludeFiles(FullFileName)\r
1086 for F in IncludeFileList:\r
1087 FileID = GetTableID(F)\r
1088 if FileID < 0:\r
1089 continue\r
52302d4d 1090\r
30fdf114
LG
1091 FileTable = 'Identifier' + str(FileID)\r
1092 SqlStatement = """ select Modifier, ID\r
1093 from %s\r
1094 where Model = %d and Value = \'%s\'\r
1095 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION, PredVar)\r
1096 ResultSet = Db.TblFile.Exec(SqlStatement)\r
52302d4d 1097\r
30fdf114
LG
1098 for Result in ResultSet:\r
1099 Type = GetDataTypeFromModifier(Result[0]).split()[-1]\r
1100 TypedefDict = GetTypedefDict(FullFileName)\r
1101 Type = GetRealType(Type, TypedefDict, TargetType)\r
1102 return Type\r
52302d4d 1103\r
30fdf114
LG
1104 FileID = GetTableID(FullFileName)\r
1105 SqlStatement = """ select Modifier, ID\r
1106 from Function\r
1107 where BelongsToFile = %d and Name = \'%s\'\r
1108 """ % (FileID, PredVar)\r
1109 ResultSet = Db.TblFile.Exec(SqlStatement)\r
52302d4d
LG
1110\r
1111 for Result in ResultSet:\r
30fdf114
LG
1112 Type = GetDataTypeFromModifier(Result[0]).split()[-1]\r
1113 TypedefDict = GetTypedefDict(FullFileName)\r
1114 Type = GetRealType(Type, TypedefDict, TargetType)\r
1115 return Type\r
52302d4d 1116\r
30fdf114
LG
1117 for F in IncludeFileList:\r
1118 FileID = GetTableID(F)\r
1119 if FileID < 0:\r
1120 continue\r
52302d4d 1121\r
30fdf114
LG
1122 FileTable = 'Identifier' + str(FileID)\r
1123 SqlStatement = """ select Modifier, ID\r
1124 from Function\r
1125 where BelongsToFile = %d and Name = \'%s\'\r
1126 """ % (FileID, PredVar)\r
1127 ResultSet = Db.TblFile.Exec(SqlStatement)\r
52302d4d 1128\r
30fdf114
LG
1129 for Result in ResultSet:\r
1130 Type = GetDataTypeFromModifier(Result[0]).split()[-1]\r
1131 TypedefDict = GetTypedefDict(FullFileName)\r
1132 Type = GetRealType(Type, TypedefDict, TargetType)\r
1133 return Type\r
52302d4d 1134\r
30fdf114 1135 return None\r
52302d4d 1136\r
30fdf114
LG
1137 # really variable, search local variable first\r
1138 SqlStatement = """ select Modifier, ID\r
1139 from %s\r
1140 where Model = %d and Name = \'%s\' and StartLine >= %d and StartLine <= %d\r
1141 """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE, PredVar, FuncRecord[0], FuncRecord[1])\r
1142 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1143 VarFound = False\r
1144 for Result in ResultSet:\r
1145 if len(PredVarList) > 1:\r
1146 Type = GetTypeInfo(PredVarList[1:], Result[0], FullFileName, TargetType)\r
1147 return Type\r
1148 else:\r
1149# Type = GetDataTypeFromModifier(Result[0]).split()[-1]\r
1150 TypeList = GetDataTypeFromModifier(Result[0]).split()\r
1151 Type = TypeList[-1]\r
1152 if len(TypeList) > 1 and StarList != None:\r
1153 for Star in StarList:\r
1154 Type = Type.strip()\r
1155 Type = Type.rstrip(Star)\r
1156 # Get real type after de-reference pointers.\r
1157 if len(Type.strip()) == 0:\r
1158 Type = TypeList[-2]\r
1159 TypedefDict = GetTypedefDict(FullFileName)\r
1160 Type = GetRealType(Type, TypedefDict, TargetType)\r
1161 return Type\r
52302d4d 1162\r
30fdf114
LG
1163 # search function parameters second\r
1164 ParamList = GetParamList(FuncRecord[2])\r
1165 for Param in ParamList:\r
1166 if Param.Name.strip() == PredVar:\r
1167 if len(PredVarList) > 1:\r
1168 Type = GetTypeInfo(PredVarList[1:], Param.Modifier, FullFileName, TargetType)\r
1169 return Type\r
1170 else:\r
1171 TypeList = GetDataTypeFromModifier(Param.Modifier).split()\r
1172 Type = TypeList[-1]\r
1173 if len(TypeList) > 1 and StarList != None:\r
1174 for Star in StarList:\r
1175 Type = Type.strip()\r
1176 Type = Type.rstrip(Star)\r
1177 # Get real type after de-reference pointers.\r
1178 if len(Type.strip()) == 0:\r
1179 Type = TypeList[-2]\r
1180 TypedefDict = GetTypedefDict(FullFileName)\r
1181 Type = GetRealType(Type, TypedefDict, TargetType)\r
1182 return Type\r
52302d4d 1183\r
30fdf114
LG
1184 # search global variable next\r
1185 SqlStatement = """ select Modifier, ID\r
1186 from %s\r
1187 where Model = %d and Name = \'%s\' and BelongsToFunction = -1\r
1188 """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE, PredVar)\r
1189 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1190\r
1191 for Result in ResultSet:\r
1192 if len(PredVarList) > 1:\r
1193 Type = GetTypeInfo(PredVarList[1:], Result[0], FullFileName, TargetType)\r
1194 return Type\r
1195 else:\r
1196 TypeList = GetDataTypeFromModifier(Result[0]).split()\r
1197 Type = TypeList[-1]\r
1198 if len(TypeList) > 1 and StarList != None:\r
1199 for Star in StarList:\r
1200 Type = Type.strip()\r
1201 Type = Type.rstrip(Star)\r
1202 # Get real type after de-reference pointers.\r
1203 if len(Type.strip()) == 0:\r
1204 Type = TypeList[-2]\r
1205 TypedefDict = GetTypedefDict(FullFileName)\r
1206 Type = GetRealType(Type, TypedefDict, TargetType)\r
1207 return Type\r
52302d4d 1208\r
30fdf114
LG
1209 IncludeFileList = GetAllIncludeFiles(FullFileName)\r
1210 for F in IncludeFileList:\r
1211 FileID = GetTableID(F)\r
1212 if FileID < 0:\r
1213 continue\r
52302d4d 1214\r
30fdf114
LG
1215 FileTable = 'Identifier' + str(FileID)\r
1216 SqlStatement = """ select Modifier, ID\r
1217 from %s\r
1218 where Model = %d and BelongsToFunction = -1 and Name = \'%s\'\r
1219 """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE, PredVar)\r
1220 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1221\r
1222 for Result in ResultSet:\r
1223 if len(PredVarList) > 1:\r
1224 Type = GetTypeInfo(PredVarList[1:], Result[0], FullFileName, TargetType)\r
1225 return Type\r
1226 else:\r
1227 TypeList = GetDataTypeFromModifier(Result[0]).split()\r
1228 Type = TypeList[-1]\r
1229 if len(TypeList) > 1 and StarList != None:\r
1230 for Star in StarList:\r
1231 Type = Type.strip()\r
1232 Type = Type.rstrip(Star)\r
1233 # Get real type after de-reference pointers.\r
1234 if len(Type.strip()) == 0:\r
1235 Type = TypeList[-2]\r
1236 TypedefDict = GetTypedefDict(FullFileName)\r
1237 Type = GetRealType(Type, TypedefDict, TargetType)\r
1238 return Type\r
1239\r
52302d4d
LG
1240def GetTypeFromArray(Type, Var):\r
1241 Count = Var.count('[')\r
1242\r
1243 while Count > 0:\r
1244 Type = Type.strip()\r
1245 Type = Type.rstrip('*')\r
1246 Count = Count - 1\r
1247\r
1248 return Type\r
1249\r
30fdf114
LG
1250def CheckFuncLayoutReturnType(FullFileName):\r
1251 ErrorMsgList = []\r
52302d4d 1252\r
30fdf114
LG
1253 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1254 if FileID < 0:\r
1255 return ErrorMsgList\r
52302d4d 1256\r
30fdf114
LG
1257 Db = GetDB()\r
1258 FileTable = 'Identifier' + str(FileID)\r
52302d4d 1259 SqlStatement = """ select Modifier, ID, StartLine, StartColumn, EndLine, Value\r
30fdf114
LG
1260 from %s\r
1261 where Model = %d\r
1262 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
1263 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1264 for Result in ResultSet:\r
1265 ReturnType = GetDataTypeFromModifier(Result[0])\r
1266 TypeStart = ReturnType.split()[0]\r
1267 FuncName = Result[5]\r
1268 if EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, FuncName):\r
1269 continue\r
1270 Index = Result[0].find(TypeStart)\r
1271 if Index != 0 or Result[3] != 0:\r
1272 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '[%s] Return Type should appear at the start of line' % FuncName, FileTable, Result[1])\r
52302d4d 1273\r
30fdf114
LG
1274 if Result[2] == Result[4]:\r
1275 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '[%s] Return Type should appear on its own line' % FuncName, FileTable, Result[1])\r
52302d4d 1276\r
30fdf114
LG
1277 SqlStatement = """ select Modifier, ID, StartLine, StartColumn, FunNameStartLine, Name\r
1278 from Function\r
1279 where BelongsToFile = %d\r
1280 """ % (FileID)\r
1281 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1282 for Result in ResultSet:\r
1283 ReturnType = GetDataTypeFromModifier(Result[0])\r
1284 TypeStart = ReturnType.split()[0]\r
1285 FuncName = Result[5]\r
1286 if EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, FuncName):\r
1287 continue\r
1288 Index = Result[0].find(ReturnType)\r
1289 if Index != 0 or Result[3] != 0:\r
1290 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '[%s] Return Type should appear at the start of line' % FuncName, 'Function', Result[1])\r
52302d4d 1291\r
30fdf114
LG
1292 if Result[2] == Result[4]:\r
1293 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '[%s] Return Type should appear on its own line' % FuncName, 'Function', Result[1])\r
52302d4d 1294\r
30fdf114
LG
1295def CheckFuncLayoutModifier(FullFileName):\r
1296 ErrorMsgList = []\r
52302d4d 1297\r
30fdf114
LG
1298 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1299 if FileID < 0:\r
1300 return ErrorMsgList\r
52302d4d 1301\r
30fdf114
LG
1302 Db = GetDB()\r
1303 FileTable = 'Identifier' + str(FileID)\r
1304 SqlStatement = """ select Modifier, ID\r
1305 from %s\r
1306 where Model = %d\r
1307 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
1308 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1309 for Result in ResultSet:\r
1310 ReturnType = GetDataTypeFromModifier(Result[0])\r
1311 TypeStart = ReturnType.split()[0]\r
1312# if len(ReturnType) == 0:\r
1313# continue\r
1314 Index = Result[0].find(TypeStart)\r
1315 if Index != 0:\r
1316 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_OPTIONAL_FUNCTIONAL_MODIFIER, '', FileTable, Result[1])\r
52302d4d 1317\r
30fdf114
LG
1318 SqlStatement = """ select Modifier, ID\r
1319 from Function\r
1320 where BelongsToFile = %d\r
1321 """ % (FileID)\r
1322 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1323 for Result in ResultSet:\r
1324 ReturnType = GetDataTypeFromModifier(Result[0])\r
1325 TypeStart = ReturnType.split()[0]\r
1326# if len(ReturnType) == 0:\r
1327# continue\r
1328 Index = Result[0].find(TypeStart)\r
1329 if Index != 0:\r
1330 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_OPTIONAL_FUNCTIONAL_MODIFIER, '', 'Function', Result[1])\r
1331\r
1332def CheckFuncLayoutName(FullFileName):\r
1333 ErrorMsgList = []\r
1334 # Parameter variable format pattern.\r
1335 Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$')\r
1336 ParamIgnoreList = ('VOID', '...')\r
1337 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1338 if FileID < 0:\r
1339 return ErrorMsgList\r
52302d4d 1340\r
30fdf114
LG
1341 Db = GetDB()\r
1342 FileTable = 'Identifier' + str(FileID)\r
1343 SqlStatement = """ select Name, ID, EndColumn, Value\r
1344 from %s\r
1345 where Model = %d\r
1346 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
1347 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1348 for Result in ResultSet:\r
1349 FuncName = Result[3]\r
1350 if EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, FuncName):\r
1351 continue\r
1352 if Result[2] != 0:\r
1353 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Function name [%s] should appear at the start of a line' % FuncName, FileTable, Result[1])\r
1354 ParamList = GetParamList(Result[0])\r
1355 if len(ParamList) == 0:\r
1356 continue\r
1357 StartLine = 0\r
1358 for Param in ParamList:\r
1359 if Param.StartLine <= StartLine:\r
1360 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Parameter %s should be in its own line.' % Param.Name, FileTable, Result[1])\r
1361 if Param.StartLine - StartLine > 1:\r
52302d4d 1362 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Empty line appears before Parameter %s.' % Param.Name, FileTable, Result[1])\r
30fdf114
LG
1363 if not Pattern.match(Param.Name) and not Param.Name in ParamIgnoreList and not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Param.Name):\r
1364 PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Parameter [%s] NOT follow naming convention.' % Param.Name, FileTable, Result[1])\r
1365 StartLine = Param.StartLine\r
52302d4d 1366\r
30fdf114
LG
1367 if not Result[0].endswith('\n )') and not Result[0].endswith('\r )'):\r
1368 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, '\')\' should be on a new line and indented two spaces', FileTable, Result[1])\r
52302d4d 1369\r
30fdf114
LG
1370 SqlStatement = """ select Modifier, ID, FunNameStartColumn, Name\r
1371 from Function\r
1372 where BelongsToFile = %d\r
1373 """ % (FileID)\r
1374 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1375 for Result in ResultSet:\r
1376 FuncName = Result[3]\r
1377 if EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, FuncName):\r
1378 continue\r
1379 if Result[2] != 0:\r
1380 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Function name [%s] should appear at the start of a line' % FuncName, 'Function', Result[1])\r
1381 ParamList = GetParamList(Result[0])\r
1382 if len(ParamList) == 0:\r
1383 continue\r
1384 StartLine = 0\r
1385 for Param in ParamList:\r
1386 if Param.StartLine <= StartLine:\r
1387 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Parameter %s should be in its own line.' % Param.Name, 'Function', Result[1])\r
1388 if Param.StartLine - StartLine > 1:\r
1389 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Empty line appears before Parameter %s.' % Param.Name, 'Function', Result[1])\r
1390 if not Pattern.match(Param.Name) and not Param.Name in ParamIgnoreList and not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Param.Name):\r
1391 PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Parameter [%s] NOT follow naming convention.' % Param.Name, FileTable, Result[1])\r
1392 StartLine = Param.StartLine\r
1393 if not Result[0].endswith('\n )') and not Result[0].endswith('\r )'):\r
1394 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, '\')\' should be on a new line and indented two spaces', 'Function', Result[1])\r
1395\r
1396def CheckFuncLayoutPrototype(FullFileName):\r
1397 ErrorMsgList = []\r
52302d4d 1398\r
30fdf114
LG
1399 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1400 if FileID < 0:\r
1401 return ErrorMsgList\r
52302d4d 1402\r
30fdf114
LG
1403 FileTable = 'Identifier' + str(FileID)\r
1404 Db = GetDB()\r
1405 SqlStatement = """ select Modifier, Header, Name, ID\r
1406 from Function\r
1407 where BelongsToFile = %d\r
1408 """ % (FileID)\r
1409 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1410 if len(ResultSet) == 0:\r
1411 return ErrorMsgList\r
52302d4d 1412\r
30fdf114
LG
1413 FuncDefList = []\r
1414 for Result in ResultSet:\r
1415 FuncDefList.append(Result)\r
52302d4d 1416\r
30fdf114
LG
1417 SqlStatement = """ select Modifier, Name, ID\r
1418 from %s\r
1419 where Model = %d\r
1420 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
1421 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1422 FuncDeclList = []\r
1423 for Result in ResultSet:\r
1424 FuncDeclList.append(Result)\r
52302d4d 1425\r
30fdf114
LG
1426 UndeclFuncList = []\r
1427 for FuncDef in FuncDefList:\r
1428 FuncName = FuncDef[2].strip()\r
1429 FuncModifier = FuncDef[0]\r
1430 FuncDefHeader = FuncDef[1]\r
1431 for FuncDecl in FuncDeclList:\r
1432 LBPos = FuncDecl[1].find('(')\r
1433 DeclName = FuncDecl[1][0:LBPos].strip()\r
1434 DeclModifier = FuncDecl[0]\r
1435 if DeclName == FuncName:\r
1436 if DiffModifier(FuncModifier, DeclModifier) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, FuncName):\r
1437 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, 'Function [%s] modifier different with prototype.' % FuncName, 'Function', FuncDef[3])\r
1438 ParamListOfDef = GetParamList(FuncDefHeader)\r
1439 ParamListOfDecl = GetParamList(FuncDecl[1])\r
52302d4d
LG
1440 if len(ParamListOfDef) != len(ParamListOfDecl) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_2, FuncName):\r
1441 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_2, 'Parameter number different in function [%s].' % FuncName, 'Function', FuncDef[3])\r
30fdf114
LG
1442 break\r
1443\r
1444 Index = 0\r
1445 while Index < len(ParamListOfDef):\r
52302d4d
LG
1446 if DiffModifier(ParamListOfDef[Index].Modifier, ParamListOfDecl[Index].Modifier) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_3, FuncName):\r
1447 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_3, 'Parameter %s has different modifier with prototype in function [%s].' % (ParamListOfDef[Index].Name, FuncName), 'Function', FuncDef[3])\r
30fdf114
LG
1448 Index += 1\r
1449 break\r
1450 else:\r
1451 UndeclFuncList.append(FuncDef)\r
52302d4d 1452\r
30fdf114
LG
1453 IncludeFileList = GetAllIncludeFiles(FullFileName)\r
1454 FuncDeclList = []\r
1455 for F in IncludeFileList:\r
1456 FileID = GetTableID(F, ErrorMsgList)\r
1457 if FileID < 0:\r
1458 continue\r
52302d4d 1459\r
30fdf114
LG
1460 FileTable = 'Identifier' + str(FileID)\r
1461 SqlStatement = """ select Modifier, Name, ID\r
1462 from %s\r
1463 where Model = %d\r
1464 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
1465 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1466\r
1467 for Result in ResultSet:\r
1468 FuncDeclList.append(Result)\r
52302d4d 1469\r
30fdf114
LG
1470 for FuncDef in UndeclFuncList:\r
1471 FuncName = FuncDef[2].strip()\r
1472 FuncModifier = FuncDef[0]\r
1473 FuncDefHeader = FuncDef[1]\r
1474 for FuncDecl in FuncDeclList:\r
1475 LBPos = FuncDecl[1].find('(')\r
1476 DeclName = FuncDecl[1][0:LBPos].strip()\r
1477 DeclModifier = FuncDecl[0]\r
1478 if DeclName == FuncName:\r
1479 if DiffModifier(FuncModifier, DeclModifier) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, FuncName):\r
1480 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, 'Function [%s] modifier different with prototype.' % FuncName, 'Function', FuncDef[3])\r
1481 ParamListOfDef = GetParamList(FuncDefHeader)\r
1482 ParamListOfDecl = GetParamList(FuncDecl[1])\r
52302d4d
LG
1483 if len(ParamListOfDef) != len(ParamListOfDecl) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_2, FuncName):\r
1484 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_2, 'Parameter number different in function [%s].' % FuncName, 'Function', FuncDef[3])\r
30fdf114
LG
1485 break\r
1486\r
1487 Index = 0\r
1488 while Index < len(ParamListOfDef):\r
52302d4d
LG
1489 if DiffModifier(ParamListOfDef[Index].Modifier, ParamListOfDecl[Index].Modifier) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_3, FuncName):\r
1490 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_3, 'Parameter %s has different modifier with prototype in function [%s].' % (ParamListOfDef[Index].Name, FuncName), 'Function', FuncDef[3])\r
30fdf114
LG
1491 Index += 1\r
1492 break\r
52302d4d 1493\r
30fdf114
LG
1494def CheckFuncLayoutBody(FullFileName):\r
1495 ErrorMsgList = []\r
52302d4d 1496\r
30fdf114
LG
1497 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1498 if FileID < 0:\r
1499 return ErrorMsgList\r
52302d4d 1500\r
30fdf114
LG
1501 FileTable = 'Identifier' + str(FileID)\r
1502 Db = GetDB()\r
1503 SqlStatement = """ select BodyStartColumn, EndColumn, ID\r
1504 from Function\r
1505 where BelongsToFile = %d\r
1506 """ % (FileID)\r
1507 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1508 if len(ResultSet) == 0:\r
1509 return ErrorMsgList\r
1510 for Result in ResultSet:\r
1511 if Result[0] != 0:\r
1512 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY, 'open brace should be at the very beginning of a line.', 'Function', Result[2])\r
1513 if Result[1] != 0:\r
1514 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY, 'close brace should be at the very beginning of a line.', 'Function', Result[2])\r
1515\r
1516def CheckFuncLayoutLocalVariable(FullFileName):\r
1517 ErrorMsgList = []\r
52302d4d 1518\r
30fdf114
LG
1519 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1520 if FileID < 0:\r
1521 return ErrorMsgList\r
52302d4d 1522\r
30fdf114
LG
1523 Db = GetDB()\r
1524 FileTable = 'Identifier' + str(FileID)\r
1525 SqlStatement = """ select ID\r
1526 from Function\r
1527 where BelongsToFile = %d\r
1528 """ % (FileID)\r
1529 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1530 if len(ResultSet) == 0:\r
1531 return ErrorMsgList\r
1532 FL = []\r
1533 for Result in ResultSet:\r
1534 FL.append(Result)\r
52302d4d 1535\r
30fdf114 1536 for F in FL:\r
79b74a03 1537 SqlStatement = """ select Name, Value, ID, Modifier\r
30fdf114
LG
1538 from %s\r
1539 where Model = %d and BelongsToFunction = %d\r
1540 """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE, F[0])\r
1541 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1542 if len(ResultSet) == 0:\r
1543 continue\r
52302d4d 1544\r
30fdf114 1545 for Result in ResultSet:\r
79b74a03 1546 if len(Result[1]) > 0 and 'CONST' not in Result[3]:\r
30fdf114 1547 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_NO_INIT_OF_VARIABLE, 'Variable Name: %s' % Result[0], FileTable, Result[2])\r
52302d4d 1548\r
30fdf114
LG
1549def CheckMemberVariableFormat(Name, Value, FileTable, TdId, ModelId):\r
1550 ErrMsgList = []\r
1551 # Member variable format pattern.\r
1552 Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$')\r
52302d4d 1553\r
30fdf114
LG
1554 LBPos = Value.find('{')\r
1555 RBPos = Value.rfind('}')\r
1556 if LBPos == -1 or RBPos == -1:\r
1557 return ErrMsgList\r
52302d4d 1558\r
30fdf114
LG
1559 Fields = Value[LBPos + 1 : RBPos]\r
1560 Fields = StripComments(Fields).strip()\r
1561 NestPos = Fields.find ('struct')\r
1562 if NestPos != -1 and (NestPos + len('struct') < len(Fields)):\r
1563 if not Fields[NestPos + len('struct') + 1].isalnum():\r
1564 if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, Name):\r
1565 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, 'Nested struct in [%s].' % (Name), FileTable, TdId)\r
1566 return ErrMsgList\r
1567 NestPos = Fields.find ('union')\r
1568 if NestPos != -1 and (NestPos + len('union') < len(Fields)):\r
1569 if not Fields[NestPos + len('union') + 1].isalnum():\r
1570 if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, Name):\r
1571 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, 'Nested union in [%s].' % (Name), FileTable, TdId)\r
1572 return ErrMsgList\r
1573 NestPos = Fields.find ('enum')\r
1574 if NestPos != -1 and (NestPos + len('enum') < len(Fields)):\r
1575 if not Fields[NestPos + len('enum') + 1].isalnum():\r
1576 if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, Name):\r
1577 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, 'Nested enum in [%s].' % (Name), FileTable, TdId)\r
1578 return ErrMsgList\r
52302d4d 1579\r
30fdf114
LG
1580 if ModelId == DataClass.MODEL_IDENTIFIER_ENUMERATE:\r
1581 FieldsList = Fields.split(',')\r
1582 # deal with enum is pre-assigned a value by function call ( , , , ...)\r
1583 QuoteCount = 0\r
1584 Index = 0\r
1585 RemoveCurrentElement = False\r
1586 while Index < len(FieldsList):\r
1587 Field = FieldsList[Index]\r
52302d4d 1588\r
30fdf114
LG
1589 if Field.find('(') != -1:\r
1590 QuoteCount += 1\r
1591 RemoveCurrentElement = True\r
1592 Index += 1\r
1593 continue\r
52302d4d 1594\r
30fdf114
LG
1595 if Field.find(')') != -1 and QuoteCount > 0:\r
1596 QuoteCount -= 1\r
1597\r
52302d4d 1598 if RemoveCurrentElement:\r
30fdf114
LG
1599 FieldsList.remove(Field)\r
1600 if QuoteCount == 0:\r
1601 RemoveCurrentElement = False\r
1602 continue\r
52302d4d 1603\r
30fdf114
LG
1604 if QuoteCount == 0:\r
1605 RemoveCurrentElement = False\r
52302d4d 1606\r
30fdf114
LG
1607 Index += 1\r
1608 else:\r
1609 FieldsList = Fields.split(';')\r
52302d4d 1610\r
30fdf114
LG
1611 for Field in FieldsList:\r
1612 Field = Field.strip()\r
1613 if Field == '':\r
1614 continue\r
52302d4d 1615 # For the condition that the field in struct is an array with [] sufixes...\r
30fdf114
LG
1616 if Field[-1] == ']':\r
1617 LBPos = Field.find('[')\r
1618 Field = Field[0:LBPos]\r
1619 # For the condition that bit field ": Number"\r
1620 if Field.find(':') != -1:\r
1621 ColonPos = Field.find(':')\r
1622 Field = Field[0:ColonPos]\r
52302d4d 1623\r
30fdf114
LG
1624 Field = Field.strip()\r
1625 if Field == '':\r
1626 continue\r
1627 # Enum could directly assign value to variable\r
1628 Field = Field.split('=')[0].strip()\r
52302d4d 1629 TokenList = Field.split()\r
30fdf114
LG
1630 # Remove pointers before variable\r
1631 if not Pattern.match(TokenList[-1].lstrip('*')):\r
1632 ErrMsgList.append(TokenList[-1].lstrip('*'))\r
52302d4d 1633\r
30fdf114
LG
1634 return ErrMsgList\r
1635\r
1636def CheckDeclTypedefFormat(FullFileName, ModelId):\r
1637 ErrorMsgList = []\r
52302d4d 1638\r
30fdf114
LG
1639 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1640 if FileID < 0:\r
1641 return ErrorMsgList\r
52302d4d 1642\r
30fdf114
LG
1643 Db = GetDB()\r
1644 FileTable = 'Identifier' + str(FileID)\r
1645 SqlStatement = """ select Name, StartLine, EndLine, ID, Value\r
1646 from %s\r
1647 where Model = %d\r
1648 """ % (FileTable, ModelId)\r
1649 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1650 ResultList = []\r
1651 for Result in ResultSet:\r
1652 ResultList.append(Result)\r
52302d4d 1653\r
30fdf114
LG
1654 ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_ALL\r
1655 if ModelId == DataClass.MODEL_IDENTIFIER_STRUCTURE:\r
1656 ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_STRUCTURE_DECLARATION\r
1657 elif ModelId == DataClass.MODEL_IDENTIFIER_ENUMERATE:\r
1658 ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_ENUMERATED_TYPE\r
1659 elif ModelId == DataClass.MODEL_IDENTIFIER_UNION:\r
1660 ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_UNION_TYPE\r
52302d4d 1661\r
30fdf114
LG
1662 SqlStatement = """ select Modifier, Name, Value, StartLine, EndLine, ID\r
1663 from %s\r
1664 where Model = %d\r
1665 """ % (FileTable, DataClass.MODEL_IDENTIFIER_TYPEDEF)\r
1666 TdSet = Db.TblFile.Exec(SqlStatement)\r
1667 TdList = []\r
1668 for Td in TdSet:\r
1669 TdList.append(Td)\r
1670 # Check member variable name format that from typedefs of ONLY this file.\r
1671 for Td in TdList:\r
1672 Name = Td[1].strip()\r
1673 Value = Td[2].strip()\r
1674 if Value.startswith('enum'):\r
1675 ValueModelId = DataClass.MODEL_IDENTIFIER_ENUMERATE\r
1676 elif Value.startswith('struct'):\r
1677 ValueModelId = DataClass.MODEL_IDENTIFIER_STRUCTURE\r
1678 elif Value.startswith('union'):\r
1679 ValueModelId = DataClass.MODEL_IDENTIFIER_UNION\r
1680 else:\r
1681 continue\r
52302d4d 1682\r
30fdf114
LG
1683 if ValueModelId != ModelId:\r
1684 continue\r
1685 # Check member variable format.\r
1686 ErrMsgList = CheckMemberVariableFormat(Name, Value, FileTable, Td[5], ModelId)\r
1687 for ErrMsg in ErrMsgList:\r
79b74a03 1688 if EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Name + '.' + ErrMsg):\r
30fdf114 1689 continue\r
79b74a03 1690 PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Member variable [%s] NOT follow naming convention.' % (Name + '.' + ErrMsg), FileTable, Td[5])\r
52302d4d 1691\r
30fdf114
LG
1692 # First check in current file to see whether struct/union/enum is typedef-ed.\r
1693 UntypedefedList = []\r
1694 for Result in ResultList:\r
1695 # Check member variable format.\r
1696 Name = Result[0].strip()\r
1697 Value = Result[4].strip()\r
1698 if Value.startswith('enum'):\r
1699 ValueModelId = DataClass.MODEL_IDENTIFIER_ENUMERATE\r
1700 elif Value.startswith('struct'):\r
1701 ValueModelId = DataClass.MODEL_IDENTIFIER_STRUCTURE\r
1702 elif Value.startswith('union'):\r
1703 ValueModelId = DataClass.MODEL_IDENTIFIER_UNION\r
1704 else:\r
1705 continue\r
52302d4d 1706\r
30fdf114
LG
1707 if ValueModelId != ModelId:\r
1708 continue\r
1709 ErrMsgList = CheckMemberVariableFormat(Name, Value, FileTable, Result[3], ModelId)\r
1710 for ErrMsg in ErrMsgList:\r
79b74a03 1711 if EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Result[0] + '.' + ErrMsg):\r
30fdf114 1712 continue\r
79b74a03 1713 PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Member variable [%s] NOT follow naming convention.' % (Result[0] + '.' + ErrMsg), FileTable, Result[3])\r
30fdf114
LG
1714 # Check whether it is typedefed.\r
1715 Found = False\r
1716 for Td in TdList:\r
1717 # skip function pointer\r
1718 if len(Td[0]) > 0:\r
1719 continue\r
1720 if Result[1] >= Td[3] and Td[4] >= Result[2]:\r
1721 Found = True\r
1722 if not Td[1].isupper():\r
1723 PrintErrorMsg(ErrorType, 'Typedef should be UPPER case', FileTable, Td[5])\r
1724 if Result[0] in Td[2].split():\r
1725 Found = True\r
1726 if not Td[1].isupper():\r
1727 PrintErrorMsg(ErrorType, 'Typedef should be UPPER case', FileTable, Td[5])\r
1728 if Found:\r
1729 break\r
52302d4d 1730\r
30fdf114
LG
1731 if not Found:\r
1732 UntypedefedList.append(Result)\r
1733 continue\r
52302d4d 1734\r
30fdf114
LG
1735 if len(UntypedefedList) == 0:\r
1736 return\r
52302d4d 1737\r
30fdf114
LG
1738 IncludeFileList = GetAllIncludeFiles(FullFileName)\r
1739 TdList = []\r
1740 for F in IncludeFileList:\r
1741 FileID = GetTableID(F, ErrorMsgList)\r
1742 if FileID < 0:\r
1743 continue\r
52302d4d 1744\r
30fdf114
LG
1745 IncludeFileTable = 'Identifier' + str(FileID)\r
1746 SqlStatement = """ select Modifier, Name, Value, StartLine, EndLine, ID\r
1747 from %s\r
1748 where Model = %d\r
1749 """ % (IncludeFileTable, DataClass.MODEL_IDENTIFIER_TYPEDEF)\r
1750 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1751 TdList.extend(ResultSet)\r
52302d4d 1752\r
30fdf114 1753 for Result in UntypedefedList:\r
52302d4d 1754\r
30fdf114
LG
1755 # Check whether it is typedefed.\r
1756 Found = False\r
1757 for Td in TdList:\r
52302d4d 1758\r
30fdf114
LG
1759 if len(Td[0]) > 0:\r
1760 continue\r
1761 if Result[1] >= Td[3] and Td[4] >= Result[2]:\r
1762 Found = True\r
1763 if not Td[1].isupper():\r
1764 PrintErrorMsg(ErrorType, 'Typedef should be UPPER case', FileTable, Td[5])\r
1765 if Result[0] in Td[2].split():\r
1766 Found = True\r
1767 if not Td[1].isupper():\r
1768 PrintErrorMsg(ErrorType, 'Typedef should be UPPER case', FileTable, Td[5])\r
1769 if Found:\r
1770 break\r
52302d4d 1771\r
30fdf114
LG
1772 if not Found:\r
1773 PrintErrorMsg(ErrorType, 'No Typedef for %s' % Result[0], FileTable, Result[3])\r
1774 continue\r
52302d4d 1775\r
30fdf114
LG
1776def CheckDeclStructTypedef(FullFileName):\r
1777 CheckDeclTypedefFormat(FullFileName, DataClass.MODEL_IDENTIFIER_STRUCTURE)\r
1778\r
1779def CheckDeclEnumTypedef(FullFileName):\r
1780 CheckDeclTypedefFormat(FullFileName, DataClass.MODEL_IDENTIFIER_ENUMERATE)\r
52302d4d 1781\r
30fdf114
LG
1782def CheckDeclUnionTypedef(FullFileName):\r
1783 CheckDeclTypedefFormat(FullFileName, DataClass.MODEL_IDENTIFIER_UNION)\r
1784\r
1785def CheckDeclArgModifier(FullFileName):\r
1786 ErrorMsgList = []\r
52302d4d 1787\r
30fdf114
LG
1788 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1789 if FileID < 0:\r
1790 return ErrorMsgList\r
52302d4d 1791\r
30fdf114
LG
1792 Db = GetDB()\r
1793 FileTable = 'Identifier' + str(FileID)\r
1794 SqlStatement = """ select Modifier, Name, ID\r
1795 from %s\r
1796 where Model = %d\r
1797 """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE)\r
1798 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1799 ModifierTuple = ('IN', 'OUT', 'OPTIONAL', 'UNALIGNED')\r
1800 MAX_MODIFIER_LENGTH = 100\r
1801 for Result in ResultSet:\r
1802 for Modifier in ModifierTuple:\r
1803 if PatternInModifier(Result[0], Modifier) and len(Result[0]) < MAX_MODIFIER_LENGTH:\r
1804 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER, 'Variable Modifier %s' % Result[0], FileTable, Result[2])\r
1805 break\r
52302d4d 1806\r
30fdf114
LG
1807 SqlStatement = """ select Modifier, Name, ID\r
1808 from %s\r
1809 where Model = %d\r
1810 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
1811 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1812 for Result in ResultSet:\r
1813 for Modifier in ModifierTuple:\r
1814 if PatternInModifier(Result[0], Modifier):\r
1815 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER, 'Return Type Modifier %s' % Result[0], FileTable, Result[2])\r
1816 break\r
52302d4d 1817\r
30fdf114
LG
1818 SqlStatement = """ select Modifier, Header, ID\r
1819 from Function\r
1820 where BelongsToFile = %d\r
1821 """ % (FileID)\r
1822 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1823 for Result in ResultSet:\r
1824 for Modifier in ModifierTuple:\r
1825 if PatternInModifier(Result[0], Modifier):\r
1826 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER, 'Return Type Modifier %s' % Result[0], FileTable, Result[2])\r
1827 break\r
1828\r
1829def CheckDeclNoUseCType(FullFileName):\r
1830 ErrorMsgList = []\r
52302d4d 1831\r
30fdf114
LG
1832 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1833 if FileID < 0:\r
1834 return ErrorMsgList\r
52302d4d 1835\r
30fdf114
LG
1836 Db = GetDB()\r
1837 FileTable = 'Identifier' + str(FileID)\r
1838 SqlStatement = """ select Modifier, Name, ID\r
1839 from %s\r
1840 where Model = %d\r
1841 """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE)\r
1842 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1843 CTypeTuple = ('int', 'unsigned', 'char', 'void', 'static', 'long')\r
1844 for Result in ResultSet:\r
1845 for Type in CTypeTuple:\r
1846 if PatternInModifier(Result[0], Type):\r
1847 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, 'Variable type %s' % Type, FileTable, Result[2])\r
1848 break\r
52302d4d 1849\r
30fdf114
LG
1850 SqlStatement = """ select Modifier, Name, ID, Value\r
1851 from %s\r
1852 where Model = %d\r
1853 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
1854 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1855 for Result in ResultSet:\r
1856 ParamList = GetParamList(Result[1])\r
1857 FuncName = Result[3]\r
1858 if EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, FuncName):\r
1859 continue\r
1860 for Type in CTypeTuple:\r
1861 if PatternInModifier(Result[0], Type):\r
1862 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, '%s Return type %s' % (FuncName, Result[0]), FileTable, Result[2])\r
52302d4d 1863\r
30fdf114
LG
1864 for Param in ParamList:\r
1865 if PatternInModifier(Param.Modifier, Type):\r
1866 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, 'Parameter %s' % Param.Name, FileTable, Result[2])\r
52302d4d 1867\r
30fdf114
LG
1868 SqlStatement = """ select Modifier, Header, ID, Name\r
1869 from Function\r
1870 where BelongsToFile = %d\r
1871 """ % (FileID)\r
1872 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1873 for Result in ResultSet:\r
1874 ParamList = GetParamList(Result[1])\r
1875 FuncName = Result[3]\r
1876 if EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, FuncName):\r
1877 continue\r
1878 for Type in CTypeTuple:\r
1879 if PatternInModifier(Result[0], Type):\r
1880 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, '[%s] Return type %s' % (FuncName, Result[0]), FileTable, Result[2])\r
52302d4d 1881\r
30fdf114
LG
1882 for Param in ParamList:\r
1883 if PatternInModifier(Param.Modifier, Type):\r
1884 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, 'Parameter %s' % Param.Name, FileTable, Result[2])\r
52302d4d 1885\r
30fdf114
LG
1886\r
1887def CheckPointerNullComparison(FullFileName):\r
1888 ErrorMsgList = []\r
52302d4d 1889\r
30fdf114
LG
1890 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1891 if FileID < 0:\r
1892 return ErrorMsgList\r
52302d4d 1893\r
30fdf114
LG
1894 # cache the found function return type to accelerate later checking in this file.\r
1895 FuncReturnTypeDict = {}\r
52302d4d 1896\r
30fdf114
LG
1897 Db = GetDB()\r
1898 FileTable = 'Identifier' + str(FileID)\r
1899 SqlStatement = """ select Value, StartLine, ID\r
1900 from %s\r
1901 where Model = %d\r
1902 """ % (FileTable, DataClass.MODEL_IDENTIFIER_PREDICATE_EXPRESSION)\r
1903 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1904 if len(ResultSet) == 0:\r
1905 return\r
1906 PSL = []\r
1907 for Result in ResultSet:\r
1908 PSL.append([Result[0], Result[1], Result[2]])\r
52302d4d 1909\r
30fdf114
LG
1910 SqlStatement = """ select BodyStartLine, EndLine, Header, Modifier, ID\r
1911 from Function\r
1912 where BelongsToFile = %d\r
1913 """ % (FileID)\r
1914 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1915 FL = []\r
1916 for Result in ResultSet:\r
1917 FL.append([Result[0], Result[1], Result[2], Result[3], Result[4]])\r
52302d4d 1918\r
30fdf114
LG
1919 p = GetFuncDeclPattern()\r
1920 for Str in PSL:\r
1921 FuncRecord = GetFuncContainsPE(Str[1], FL)\r
1922 if FuncRecord == None:\r
1923 continue\r
52302d4d 1924\r
30fdf114
LG
1925 for Exp in GetPredicateListFromPredicateExpStr(Str[0]):\r
1926 PredInfo = SplitPredicateStr(Exp)\r
1927 if PredInfo[1] == None:\r
1928 PredVarStr = PredInfo[0][0].strip()\r
1929 IsFuncCall = False\r
1930 SearchInCache = False\r
1931 # PredVarStr may contain '.' or '->'\r
1932 TmpStr = PredVarStr.replace('.', '').replace('->', '')\r
1933 if p.match(TmpStr):\r
1934 PredVarStr = PredVarStr[0:PredVarStr.find('(')]\r
1935 SearchInCache = True\r
1936 # Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable.\r
52302d4d 1937 if TmpStr.startswith(PredVarStr):\r
30fdf114 1938 IsFuncCall = True\r
52302d4d 1939\r
30fdf114
LG
1940 if PredVarStr.strip() in IgnoredKeywordList:\r
1941 continue\r
1942 StarList = []\r
1943 PredVarList = GetCNameList(PredVarStr, StarList)\r
1944 # No variable found, maybe value first? like (0 == VarName)\r
1945 if len(PredVarList) == 0:\r
1946 continue\r
1947 if SearchInCache:\r
1948 Type = FuncReturnTypeDict.get(PredVarStr)\r
1949 if Type != None:\r
79b74a03 1950 if Type.find('*') != -1 and Type != 'BOOLEAN*':\r
30fdf114
LG
1951 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
1952 continue\r
52302d4d 1953\r
30fdf114
LG
1954 if PredVarStr in FuncReturnTypeDict:\r
1955 continue\r
52302d4d 1956\r
30fdf114
LG
1957 Type = GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall, None, StarList)\r
1958 if SearchInCache:\r
1959 FuncReturnTypeDict[PredVarStr] = Type\r
1960 if Type == None:\r
1961 continue\r
52302d4d 1962 Type = GetTypeFromArray(Type, PredVarStr)\r
79b74a03 1963 if Type.find('*') != -1 and Type != 'BOOLEAN*':\r
30fdf114
LG
1964 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
1965\r
1966def CheckNonBooleanValueComparison(FullFileName):\r
1967 ErrorMsgList = []\r
52302d4d 1968\r
30fdf114
LG
1969 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1970 if FileID < 0:\r
1971 return ErrorMsgList\r
52302d4d 1972\r
30fdf114
LG
1973 # cache the found function return type to accelerate later checking in this file.\r
1974 FuncReturnTypeDict = {}\r
52302d4d 1975\r
30fdf114
LG
1976 Db = GetDB()\r
1977 FileTable = 'Identifier' + str(FileID)\r
1978 SqlStatement = """ select Value, StartLine, ID\r
1979 from %s\r
1980 where Model = %d\r
1981 """ % (FileTable, DataClass.MODEL_IDENTIFIER_PREDICATE_EXPRESSION)\r
1982 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1983 if len(ResultSet) == 0:\r
1984 return\r
1985 PSL = []\r
1986 for Result in ResultSet:\r
1987 PSL.append([Result[0], Result[1], Result[2]])\r
52302d4d 1988\r
30fdf114
LG
1989 SqlStatement = """ select BodyStartLine, EndLine, Header, Modifier, ID\r
1990 from Function\r
1991 where BelongsToFile = %d\r
1992 """ % (FileID)\r
1993 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1994 FL = []\r
1995 for Result in ResultSet:\r
1996 FL.append([Result[0], Result[1], Result[2], Result[3], Result[4]])\r
52302d4d 1997\r
30fdf114
LG
1998 p = GetFuncDeclPattern()\r
1999 for Str in PSL:\r
2000 FuncRecord = GetFuncContainsPE(Str[1], FL)\r
2001 if FuncRecord == None:\r
2002 continue\r
52302d4d 2003\r
30fdf114 2004 for Exp in GetPredicateListFromPredicateExpStr(Str[0]):\r
30fdf114
LG
2005 PredInfo = SplitPredicateStr(Exp)\r
2006 if PredInfo[1] == None:\r
2007 PredVarStr = PredInfo[0][0].strip()\r
2008 IsFuncCall = False\r
2009 SearchInCache = False\r
2010 # PredVarStr may contain '.' or '->'\r
2011 TmpStr = PredVarStr.replace('.', '').replace('->', '')\r
2012 if p.match(TmpStr):\r
2013 PredVarStr = PredVarStr[0:PredVarStr.find('(')]\r
2014 SearchInCache = True\r
2015 # Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable.\r
52302d4d 2016 if TmpStr.startswith(PredVarStr):\r
30fdf114 2017 IsFuncCall = True\r
52302d4d 2018\r
30fdf114
LG
2019 if PredVarStr.strip() in IgnoredKeywordList:\r
2020 continue\r
2021 StarList = []\r
2022 PredVarList = GetCNameList(PredVarStr, StarList)\r
2023 # No variable found, maybe value first? like (0 == VarName)\r
2024 if len(PredVarList) == 0:\r
2025 continue\r
52302d4d 2026\r
30fdf114
LG
2027 if SearchInCache:\r
2028 Type = FuncReturnTypeDict.get(PredVarStr)\r
2029 if Type != None:\r
2030 if Type.find('BOOLEAN') == -1:\r
2031 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
2032 continue\r
52302d4d 2033\r
30fdf114
LG
2034 if PredVarStr in FuncReturnTypeDict:\r
2035 continue\r
30fdf114
LG
2036 Type = GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall, 'BOOLEAN', StarList)\r
2037 if SearchInCache:\r
2038 FuncReturnTypeDict[PredVarStr] = Type\r
2039 if Type == None:\r
2040 continue\r
2041 if Type.find('BOOLEAN') == -1:\r
2042 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
52302d4d 2043\r
30fdf114
LG
2044\r
2045def CheckBooleanValueComparison(FullFileName):\r
2046 ErrorMsgList = []\r
52302d4d 2047\r
30fdf114
LG
2048 FileID = GetTableID(FullFileName, ErrorMsgList)\r
2049 if FileID < 0:\r
2050 return ErrorMsgList\r
52302d4d 2051\r
30fdf114
LG
2052 # cache the found function return type to accelerate later checking in this file.\r
2053 FuncReturnTypeDict = {}\r
52302d4d 2054\r
30fdf114
LG
2055 Db = GetDB()\r
2056 FileTable = 'Identifier' + str(FileID)\r
2057 SqlStatement = """ select Value, StartLine, ID\r
2058 from %s\r
2059 where Model = %d\r
2060 """ % (FileTable, DataClass.MODEL_IDENTIFIER_PREDICATE_EXPRESSION)\r
2061 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2062 if len(ResultSet) == 0:\r
2063 return\r
2064 PSL = []\r
2065 for Result in ResultSet:\r
2066 PSL.append([Result[0], Result[1], Result[2]])\r
52302d4d 2067\r
30fdf114
LG
2068 SqlStatement = """ select BodyStartLine, EndLine, Header, Modifier, ID\r
2069 from Function\r
2070 where BelongsToFile = %d\r
2071 """ % (FileID)\r
2072 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2073 FL = []\r
2074 for Result in ResultSet:\r
2075 FL.append([Result[0], Result[1], Result[2], Result[3], Result[4]])\r
52302d4d 2076\r
30fdf114
LG
2077 p = GetFuncDeclPattern()\r
2078 for Str in PSL:\r
2079 FuncRecord = GetFuncContainsPE(Str[1], FL)\r
2080 if FuncRecord == None:\r
2081 continue\r
52302d4d 2082\r
30fdf114
LG
2083 for Exp in GetPredicateListFromPredicateExpStr(Str[0]):\r
2084 PredInfo = SplitPredicateStr(Exp)\r
2085 if PredInfo[1] in ('==', '!=') and PredInfo[0][1] in ('TRUE', 'FALSE'):\r
2086 PredVarStr = PredInfo[0][0].strip()\r
2087 IsFuncCall = False\r
2088 SearchInCache = False\r
2089 # PredVarStr may contain '.' or '->'\r
2090 TmpStr = PredVarStr.replace('.', '').replace('->', '')\r
2091 if p.match(TmpStr):\r
2092 PredVarStr = PredVarStr[0:PredVarStr.find('(')]\r
2093 SearchInCache = True\r
2094 # Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable.\r
52302d4d 2095 if TmpStr.startswith(PredVarStr):\r
30fdf114 2096 IsFuncCall = True\r
52302d4d 2097\r
30fdf114
LG
2098 if PredVarStr.strip() in IgnoredKeywordList:\r
2099 continue\r
2100 StarList = []\r
2101 PredVarList = GetCNameList(PredVarStr, StarList)\r
2102 # No variable found, maybe value first? like (0 == VarName)\r
2103 if len(PredVarList) == 0:\r
2104 continue\r
52302d4d 2105\r
30fdf114
LG
2106 if SearchInCache:\r
2107 Type = FuncReturnTypeDict.get(PredVarStr)\r
2108 if Type != None:\r
2109 if Type.find('BOOLEAN') != -1:\r
2110 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
2111 continue\r
52302d4d 2112\r
30fdf114
LG
2113 if PredVarStr in FuncReturnTypeDict:\r
2114 continue\r
52302d4d 2115\r
30fdf114
LG
2116 Type = GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall, 'BOOLEAN', StarList)\r
2117 if SearchInCache:\r
2118 FuncReturnTypeDict[PredVarStr] = Type\r
2119 if Type == None:\r
2120 continue\r
2121 if Type.find('BOOLEAN') != -1:\r
2122 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
52302d4d 2123\r
30fdf114
LG
2124\r
2125def CheckHeaderFileData(FullFileName):\r
2126 ErrorMsgList = []\r
52302d4d 2127\r
30fdf114
LG
2128 FileID = GetTableID(FullFileName, ErrorMsgList)\r
2129 if FileID < 0:\r
2130 return ErrorMsgList\r
52302d4d 2131\r
30fdf114
LG
2132 Db = GetDB()\r
2133 FileTable = 'Identifier' + str(FileID)\r
2134 SqlStatement = """ select ID, Modifier\r
2135 from %s\r
2136 where Model = %d\r
2137 """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE)\r
2138 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2139 for Result in ResultSet:\r
2140 if not Result[1].startswith('extern'):\r
2141 PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_DATA, 'Variable definition appears in header file', FileTable, Result[0])\r
52302d4d 2142\r
30fdf114
LG
2143 SqlStatement = """ select ID\r
2144 from Function\r
2145 where BelongsToFile = %d\r
2146 """ % FileID\r
2147 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2148 for Result in ResultSet:\r
2149 PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_DATA, 'Function definition appears in header file', 'Function', Result[0])\r
2150\r
2151 return ErrorMsgList\r
2152\r
2153def CheckHeaderFileIfndef(FullFileName):\r
2154 ErrorMsgList = []\r
52302d4d 2155\r
30fdf114
LG
2156 FileID = GetTableID(FullFileName, ErrorMsgList)\r
2157 if FileID < 0:\r
2158 return ErrorMsgList\r
52302d4d 2159\r
30fdf114
LG
2160 Db = GetDB()\r
2161 FileTable = 'Identifier' + str(FileID)\r
2162 SqlStatement = """ select Value, StartLine\r
2163 from %s\r
2164 where Model = %d order by StartLine\r
2165 """ % (FileTable, DataClass.MODEL_IDENTIFIER_MACRO_IFNDEF)\r
2166 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2167 if len(ResultSet) == 0:\r
2168 PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_1, '', 'File', FileID)\r
2169 return ErrorMsgList\r
2170 for Result in ResultSet:\r
2171 SqlStatement = """ select Value, EndLine\r
2172 from %s\r
2173 where EndLine < %d\r
2174 """ % (FileTable, Result[1])\r
2175 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2176 for Result in ResultSet:\r
2177 if not Result[0].startswith('/*') and not Result[0].startswith('//'):\r
2178 PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_2, '', 'File', FileID)\r
2179 break\r
52302d4d 2180\r
30fdf114
LG
2181 SqlStatement = """ select Value\r
2182 from %s\r
2183 where StartLine > (select max(EndLine) from %s where Model = %d)\r
2184 """ % (FileTable, FileTable, DataClass.MODEL_IDENTIFIER_MACRO_ENDIF)\r
2185 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2186 for Result in ResultSet:\r
2187 if not Result[0].startswith('/*') and not Result[0].startswith('//'):\r
2188 PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_3, '', 'File', FileID)\r
2189 return ErrorMsgList\r
2190\r
2191def CheckDoxygenCommand(FullFileName):\r
2192 ErrorMsgList = []\r
52302d4d 2193\r
30fdf114
LG
2194 FileID = GetTableID(FullFileName, ErrorMsgList)\r
2195 if FileID < 0:\r
2196 return ErrorMsgList\r
52302d4d 2197\r
30fdf114
LG
2198 Db = GetDB()\r
2199 FileTable = 'Identifier' + str(FileID)\r
2200 SqlStatement = """ select Value, ID\r
2201 from %s\r
2202 where Model = %d or Model = %d\r
2203 """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT, DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER)\r
2204 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2205 DoxygenCommandList = ['bug', 'todo', 'example', 'file', 'attention', 'param', 'post', 'pre', 'retval', 'return', 'sa', 'since', 'test', 'note', 'par']\r
2206 for Result in ResultSet:\r
2207 CommentStr = Result[0]\r
2208 CommentPartList = CommentStr.split()\r
2209 for Part in CommentPartList:\r
2210 if Part.upper() == 'BUGBUG':\r
2211 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Bug should be marked with doxygen tag @bug', FileTable, Result[1])\r
2212 if Part.upper() == 'TODO':\r
2213 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'ToDo should be marked with doxygen tag @todo', FileTable, Result[1])\r
2214 if Part.startswith('@'):\r
2215 if EccGlobalData.gException.IsException(ERROR_DOXYGEN_CHECK_COMMAND, Part):\r
2216 continue\r
2217 if Part.lstrip('@').isalpha():\r
2218 if Part.lstrip('@') not in DoxygenCommandList:\r
2219 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Unknown doxygen command %s' % Part, FileTable, Result[1])\r
2220 else:\r
2221 Index = Part.find('[')\r
2222 if Index == -1:\r
2223 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Unknown doxygen command %s' % Part, FileTable, Result[1])\r
2224 RealCmd = Part[1:Index]\r
2225 if RealCmd not in DoxygenCommandList:\r
2226 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Unknown doxygen command %s' % Part, FileTable, Result[1])\r
52302d4d
LG
2227\r
2228\r
30fdf114
LG
2229def CheckDoxygenTripleForwardSlash(FullFileName):\r
2230 ErrorMsgList = []\r
52302d4d 2231\r
30fdf114
LG
2232 FileID = GetTableID(FullFileName, ErrorMsgList)\r
2233 if FileID < 0:\r
2234 return ErrorMsgList\r
52302d4d 2235\r
30fdf114 2236 Db = GetDB()\r
52302d4d 2237\r
30fdf114
LG
2238 SqlStatement = """ select ID, BodyStartLine, BodyStartColumn, EndLine, EndColumn\r
2239 from Function\r
2240 where BelongsToFile = %d\r
2241 """ % (FileID)\r
2242 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2243 if len(ResultSet) == 0:\r
2244 return\r
52302d4d
LG
2245\r
2246 FuncDefSet = []\r
30fdf114
LG
2247 for Result in ResultSet:\r
2248 FuncDefSet.append(Result)\r
52302d4d
LG
2249\r
2250\r
30fdf114
LG
2251 FileTable = 'Identifier' + str(FileID)\r
2252 SqlStatement = """ select Value, ID, StartLine, StartColumn, EndLine, EndColumn\r
2253 from %s\r
52302d4d
LG
2254 where Model = %d\r
2255\r
30fdf114
LG
2256 """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT)\r
2257 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2258 CommentSet = []\r
2259 try:\r
2260 for Result in ResultSet:\r
2261 CommentSet.append(Result)\r
2262 except:\r
2263 print 'Unrecognized chars in comment of file %s', FullFileName\r
52302d4d
LG
2264\r
2265\r
30fdf114
LG
2266 for Result in CommentSet:\r
2267 CommentStr = Result[0]\r
2268 StartLine = Result[2]\r
2269 StartColumn = Result[3]\r
2270 EndLine = Result[4]\r
2271 EndColumn = Result[5]\r
2272 if not CommentStr.startswith('///<'):\r
2273 continue\r
52302d4d 2274\r
30fdf114
LG
2275 Found = False\r
2276 for FuncDef in FuncDefSet:\r
2277 if StartLine == FuncDef[1] and StartColumn > FuncDef[2] and EndLine == FuncDef[3] and EndColumn < FuncDef[4]:\r
2278 Found = True\r
2279 break\r
2280 if StartLine > FuncDef[1] and EndLine < FuncDef[3]:\r
2281 Found = True\r
2282 break\r
2283 if StartLine == FuncDef[1] and StartColumn > FuncDef[2] and EndLine < FuncDef[3]:\r
2284 Found = True\r
2285 break\r
2286 if StartLine > FuncDef[1] and EndLine == FuncDef[3] and EndColumn < FuncDef[4]:\r
2287 Found = True\r
2288 break\r
2289 if Found:\r
2290 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMENT_FORMAT, '', FileTable, Result[1])\r
2291\r
2292\r
2293def CheckFileHeaderDoxygenComments(FullFileName):\r
2294 ErrorMsgList = []\r
52302d4d 2295\r
30fdf114
LG
2296 FileID = GetTableID(FullFileName, ErrorMsgList)\r
2297 if FileID < 0:\r
2298 return ErrorMsgList\r
52302d4d 2299\r
30fdf114
LG
2300 Db = GetDB()\r
2301 FileTable = 'Identifier' + str(FileID)\r
2302 SqlStatement = """ select Value, ID\r
2303 from %s\r
e56468c0 2304 where Model = %d and (StartLine = 1 or StartLine = 7 or StartLine = 8) and StartColumn = 0\r
30fdf114
LG
2305 """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT)\r
2306 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2307 if len(ResultSet) == 0:\r
d0acc87a 2308 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'No File License header appear at the very beginning of file.', 'File', FileID)\r
30fdf114 2309 return ErrorMsgList\r
52302d4d 2310\r
d0acc87a
LG
2311 NoHeaderCommentStartFlag = True\r
2312 NoHeaderCommentEndFlag = True\r
2313 NoHeaderCommentPeriodFlag = True\r
2314 NoCopyrightFlag = True\r
2315 NoLicenseFlag = True\r
2316 NoRevReferFlag = True\r
2317 NextLineIndex = 0\r
30fdf114 2318 for Result in ResultSet:\r
d0acc87a
LG
2319 FileStartFlag = False\r
2320 CommentStrList = []\r
e56468c0 2321 CommentStr = Result[0].strip()\r
d0acc87a
LG
2322 CommentStrListTemp = CommentStr.split('\n')\r
2323 if (len(CommentStrListTemp) <= 1):\r
2324 # For Mac\r
2325 CommentStrListTemp = CommentStr.split('\r')\r
2326 # Skip the content before the file header \r
2327 for CommentLine in CommentStrListTemp:\r
2328 if CommentLine.strip().startswith('/** @file'):\r
2329 FileStartFlag = True\r
2330 if FileStartFlag == True:\r
2331 CommentStrList.append(CommentLine)\r
2332 \r
e56468c0 2333 ID = Result[1]\r
d0acc87a
LG
2334 Index = 0\r
2335 if CommentStrList and CommentStrList[0].strip().startswith('/** @file'):\r
2336 NoHeaderCommentStartFlag = False\r
2337 else:\r
2338 continue\r
2339 if CommentStrList and CommentStrList[-1].strip().endswith('**/'):\r
2340 NoHeaderCommentEndFlag = False\r
2341 else:\r
2342 continue\r
2343\r
2344 for CommentLine in CommentStrList:\r
2345 Index = Index + 1\r
2346 NextLineIndex = Index\r
2347 if CommentLine.startswith('/** @file'):\r
2348 continue\r
2349 if CommentLine.startswith('**/'):\r
2350 break\r
2351 # Check whether C File header Comment content start with two spaces.\r
2352 if EccGlobalData.gConfig.HeaderCheckCFileCommentStartSpacesNum == '1' or EccGlobalData.gConfig.HeaderCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
2353 if CommentLine.startswith('/** @file') == False and CommentLine.startswith('**/') == False and CommentLine.strip() and CommentLine.startswith(' ') == False:\r
2354 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment content should start with two spaces at each line', FileTable, ID)\r
2355 \r
2356 CommentLine = CommentLine.strip()\r
2357 if CommentLine.startswith('Copyright'):\r
2358 NoCopyrightFlag = False\r
2359 if CommentLine.find('All rights reserved') == -1:\r
2360 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, '""All rights reserved"" announcement should be following the ""Copyright"" at the same line', FileTable, ID)\r
2361 if CommentLine.endswith('<BR>') == -1:\r
2362 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'The ""<BR>"" at the end of the Copyright line is required', FileTable, ID)\r
2363 if NextLineIndex < len(CommentStrList) and CommentStrList[NextLineIndex].strip().startswith('Copyright') == False and CommentStrList[NextLineIndex].strip():\r
2364 NoLicenseFlag = False\r
2365 if CommentLine.startswith('@par Revision Reference:'):\r
2366 NoRevReferFlag = False\r
2367 RefListFlag = False\r
2368 for RefLine in CommentStrList[NextLineIndex:]:\r
2369 if RefLine.strip() and (NextLineIndex + 1) < len(CommentStrList) and CommentStrList[NextLineIndex+1].strip() and CommentStrList[NextLineIndex+1].strip().startswith('**/') == False:\r
2370 RefListFlag = True\r
2371 if RefLine.strip() == False or RefLine.strip().startswith('**/'):\r
2372 RefListFlag = False\r
2373 break\r
2374 # Check whether C File header Comment's each reference at list should begin with a bullet character.\r
2375 if EccGlobalData.gConfig.HeaderCheckCFileCommentReferenceFormat == '1' or EccGlobalData.gConfig.HeaderCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
2376 if RefListFlag == True:\r
2377 if RefLine.strip() and RefLine.strip().startswith('**/') == False and RefLine.startswith(' -') == False: \r
2378 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'Each reference on a separate line should begin with a bullet character ""-"" ', FileTable, ID) \r
2379 \r
2380 if NoHeaderCommentStartFlag:\r
e56468c0 2381 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FILE_HEADER, 'File header comment should begin with ""/** @file""', FileTable, ID)\r
d0acc87a
LG
2382 return\r
2383 if NoHeaderCommentEndFlag:\r
e56468c0 2384 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment should end with ""**/""', FileTable, ID)\r
d0acc87a
LG
2385 return\r
2386 if NoCopyrightFlag:\r
2387 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment missing the ""Copyright""', FileTable, ID)\r
2388 #Check whether C File header Comment have the License immediately after the ""Copyright"" line.\r
2389 if EccGlobalData.gConfig.HeaderCheckCFileCommentLicenseFormat == '1' or EccGlobalData.gConfig.HeaderCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
2390 if NoLicenseFlag:\r
2391 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment should have the License immediately after the ""Copyright"" line', FileTable, ID)\r
30fdf114
LG
2392\r
2393def CheckFuncHeaderDoxygenComments(FullFileName):\r
2394 ErrorMsgList = []\r
52302d4d 2395\r
30fdf114
LG
2396 FileID = GetTableID(FullFileName, ErrorMsgList)\r
2397 if FileID < 0:\r
2398 return ErrorMsgList\r
52302d4d 2399\r
30fdf114
LG
2400 Db = GetDB()\r
2401 FileTable = 'Identifier' + str(FileID)\r
2402 SqlStatement = """ select Value, StartLine, EndLine, ID\r
2403 from %s\r
2404 where Model = %d\r
2405 """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT)\r
52302d4d 2406\r
30fdf114
LG
2407 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2408 CommentSet = []\r
2409 try:\r
2410 for Result in ResultSet:\r
2411 CommentSet.append(Result)\r
2412 except:\r
2413 print 'Unrecognized chars in comment of file %s', FullFileName\r
52302d4d 2414\r
30fdf114
LG
2415 # Func Decl check\r
2416 SqlStatement = """ select Modifier, Name, StartLine, ID, Value\r
2417 from %s\r
2418 where Model = %d\r
2419 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
2420 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2421 for Result in ResultSet:\r
2422 FuncName = Result[4]\r
2423 FunctionHeaderComment = CheckCommentImmediatelyPrecedeFunctionHeader(Result[1], Result[2], CommentSet)\r
2424 if FunctionHeaderComment:\r
2425 CheckFunctionHeaderConsistentWithDoxygenComment(Result[0], Result[1], Result[2], FunctionHeaderComment[0], FunctionHeaderComment[1], ErrorMsgList, FunctionHeaderComment[3], FileTable)\r
2426 else:\r
2427 if EccGlobalData.gException.IsException(ERROR_HEADER_CHECK_FUNCTION, FuncName):\r
2428 continue\r
2429 ErrorMsgList.append('Line %d :Function %s has NO comment immediately preceding it.' % (Result[2], Result[1]))\r
2430 PrintErrorMsg(ERROR_HEADER_CHECK_FUNCTION, 'Function [%s] has NO comment immediately preceding it.' % (FuncName), FileTable, Result[3])\r
52302d4d 2431\r
30fdf114
LG
2432 # Func Def check\r
2433 SqlStatement = """ select Value, StartLine, EndLine, ID\r
2434 from %s\r
2435 where Model = %d\r
2436 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER)\r
52302d4d 2437\r
30fdf114
LG
2438 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2439 CommentSet = []\r
2440 try:\r
2441 for Result in ResultSet:\r
2442 CommentSet.append(Result)\r
2443 except:\r
2444 print 'Unrecognized chars in comment of file %s', FullFileName\r
52302d4d 2445\r
30fdf114
LG
2446 SqlStatement = """ select Modifier, Header, StartLine, ID, Name\r
2447 from Function\r
2448 where BelongsToFile = %d\r
2449 """ % (FileID)\r
2450 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2451 for Result in ResultSet:\r
2452 FuncName = Result[4]\r
2453 FunctionHeaderComment = CheckCommentImmediatelyPrecedeFunctionHeader(Result[1], Result[2], CommentSet)\r
2454 if FunctionHeaderComment:\r
2455 CheckFunctionHeaderConsistentWithDoxygenComment(Result[0], Result[1], Result[2], FunctionHeaderComment[0], FunctionHeaderComment[1], ErrorMsgList, FunctionHeaderComment[3], FileTable)\r
2456 else:\r
2457 if EccGlobalData.gException.IsException(ERROR_HEADER_CHECK_FUNCTION, FuncName):\r
2458 continue\r
2459 ErrorMsgList.append('Line %d :Function [%s] has NO comment immediately preceding it.' % (Result[2], Result[1]))\r
2460 PrintErrorMsg(ERROR_HEADER_CHECK_FUNCTION, 'Function [%s] has NO comment immediately preceding it.' % (FuncName), 'Function', Result[3])\r
2461 return ErrorMsgList\r
2462\r
2463def CheckCommentImmediatelyPrecedeFunctionHeader(FuncName, FuncStartLine, CommentSet):\r
2464\r
2465 for Comment in CommentSet:\r
2466 if Comment[2] == FuncStartLine - 1:\r
2467 return Comment\r
2468 return None\r
2469\r
2470def GetDoxygenStrFromComment(Str):\r
2471 DoxygenStrList = []\r
2472 ParamTagList = Str.split('@param')\r
2473 if len(ParamTagList) > 1:\r
2474 i = 1\r
2475 while i < len(ParamTagList):\r
2476 DoxygenStrList.append('@param' + ParamTagList[i])\r
2477 i += 1\r
52302d4d 2478\r
30fdf114 2479 Str = ParamTagList[0]\r
52302d4d 2480\r
30fdf114
LG
2481 RetvalTagList = ParamTagList[-1].split('@retval')\r
2482 if len(RetvalTagList) > 1:\r
2483 if len(ParamTagList) > 1:\r
2484 DoxygenStrList[-1] = '@param' + RetvalTagList[0]\r
2485 i = 1\r
2486 while i < len(RetvalTagList):\r
2487 DoxygenStrList.append('@retval' + RetvalTagList[i])\r
2488 i += 1\r
52302d4d 2489\r
30fdf114
LG
2490 ReturnTagList = RetvalTagList[-1].split('@return')\r
2491 if len(ReturnTagList) > 1:\r
2492 if len(RetvalTagList) > 1:\r
2493 DoxygenStrList[-1] = '@retval' + ReturnTagList[0]\r
2494 elif len(ParamTagList) > 1:\r
2495 DoxygenStrList[-1] = '@param' + ReturnTagList[0]\r
2496 i = 1\r
2497 while i < len(ReturnTagList):\r
2498 DoxygenStrList.append('@return' + ReturnTagList[i])\r
2499 i += 1\r
52302d4d 2500\r
30fdf114
LG
2501 if len(DoxygenStrList) > 0:\r
2502 DoxygenStrList[-1] = DoxygenStrList[-1].rstrip('--*/')\r
52302d4d 2503\r
30fdf114 2504 return DoxygenStrList\r
52302d4d 2505\r
79b74a03 2506def CheckGeneralDoxygenCommentLayout(Str, StartLine, ErrorMsgList, CommentId= -1, TableName=''):\r
30fdf114
LG
2507 #/** --*/ @retval after @param\r
2508 if not Str.startswith('/**'):\r
2509 ErrorMsgList.append('Line %d : Comment does NOT have prefix /** ' % StartLine)\r
2510 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'Comment does NOT have prefix /** ', TableName, CommentId)\r
2511 if not Str.endswith('**/'):\r
2512 ErrorMsgList.append('Line %d : Comment does NOT have tail **/ ' % StartLine)\r
2513 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'Comment does NOT have tail **/ ', TableName, CommentId)\r
2514 FirstRetvalIndex = Str.find('@retval')\r
2515 LastParamIndex = Str.rfind('@param')\r
2516 if (FirstRetvalIndex > 0) and (LastParamIndex > 0) and (FirstRetvalIndex < LastParamIndex):\r
2517 ErrorMsgList.append('Line %d : @retval appear before @param ' % StartLine)\r
2518 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, @retval appear before @param ', TableName, CommentId)\r
52302d4d 2519\r
79b74a03 2520def CheckFunctionHeaderConsistentWithDoxygenComment(FuncModifier, FuncHeader, FuncStartLine, CommentStr, CommentStartLine, ErrorMsgList, CommentId= -1, TableName=''):\r
52302d4d
LG
2521\r
2522 ParamList = GetParamList(FuncHeader)\r
30fdf114
LG
2523 CheckGeneralDoxygenCommentLayout(CommentStr, CommentStartLine, ErrorMsgList, CommentId, TableName)\r
2524 DescriptionStr = CommentStr\r
2525 DoxygenStrList = GetDoxygenStrFromComment(DescriptionStr)\r
2526 if DescriptionStr.find('.') == -1:\r
2527 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMENT_DESCRIPTION, 'Comment description should end with period \'.\'', TableName, CommentId)\r
2528 DoxygenTagNumber = len(DoxygenStrList)\r
2529 ParamNumber = len(ParamList)\r
2530 for Param in ParamList:\r
2531 if Param.Name.upper() == 'VOID' and ParamNumber == 1:\r
2532 ParamNumber -= 1\r
2533 Index = 0\r
2534 if ParamNumber > 0 and DoxygenTagNumber > 0:\r
2535 while Index < ParamNumber and Index < DoxygenTagNumber:\r
2536 ParamModifier = ParamList[Index].Modifier\r
2537 ParamName = ParamList[Index].Name.strip()\r
2538 Tag = DoxygenStrList[Index].strip(' ')\r
2539 if (not Tag[-1] == ('\n')) and (not Tag[-1] == ('\r')):\r
79b74a03
LG
2540 ErrorMsgList.append('Line %d : in Comment, <%s> does NOT end with new line ' % (CommentStartLine, Tag.replace('\n', '').replace('\r', '')))\r
2541 PrintErrorMsg(ERROR_HEADER_CHECK_FUNCTION, 'in Comment, <%s> does NOT end with new line ' % (Tag.replace('\n', '').replace('\r', '')), TableName, CommentId)\r
30fdf114
LG
2542 TagPartList = Tag.split()\r
2543 if len(TagPartList) < 2:\r
79b74a03
LG
2544 ErrorMsgList.append('Line %d : in Comment, <%s> does NOT contain doxygen contents ' % (CommentStartLine, Tag.replace('\n', '').replace('\r', '')))\r
2545 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, <%s> does NOT contain doxygen contents ' % (Tag.replace('\n', '').replace('\r', '')), TableName, CommentId)\r
30fdf114
LG
2546 Index += 1\r
2547 continue\r
2548 LBPos = Tag.find('[')\r
2549 RBPos = Tag.find(']')\r
2550 ParamToLBContent = Tag[len('@param'):LBPos].strip()\r
79b74a03 2551 if LBPos > 0 and len(ParamToLBContent) == 0 and RBPos > LBPos:\r
30fdf114
LG
2552 InOutStr = ''\r
2553 ModifierPartList = ParamModifier.split()\r
2554 for Part in ModifierPartList:\r
2555 if Part.strip() == 'IN':\r
2556 InOutStr += 'in'\r
2557 if Part.strip() == 'OUT':\r
52302d4d 2558 if InOutStr != '':\r
30fdf114
LG
2559 InOutStr += ', out'\r
2560 else:\r
2561 InOutStr = 'out'\r
52302d4d 2562\r
30fdf114 2563 if InOutStr != '':\r
79b74a03
LG
2564 if Tag.find('[' + InOutStr + ']') == -1:\r
2565 if InOutStr != 'in, out':\r
2566 ErrorMsgList.append('Line %d : in Comment, <%s> does NOT have %s ' % (CommentStartLine, (TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), '[' + InOutStr + ']'))\r
2567 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, <%s> does NOT have %s ' % ((TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), '[' + InOutStr + ']'), TableName, CommentId)\r
2568 else:\r
2569 if Tag.find('[in,out]') == -1:\r
2570 ErrorMsgList.append('Line %d : in Comment, <%s> does NOT have %s ' % (CommentStartLine, (TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), '[' + InOutStr + ']'))\r
2571 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, <%s> does NOT have %s ' % ((TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), '[' + InOutStr + ']'), TableName, CommentId)\r
2572\r
2573\r
30fdf114 2574 if Tag.find(ParamName) == -1 and ParamName != 'VOID' and ParamName != 'void':\r
79b74a03
LG
2575 ErrorMsgList.append('Line %d : in Comment, <%s> does NOT consistent with parameter name %s ' % (CommentStartLine, (TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), ParamName))\r
2576 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, <%s> does NOT consistent with parameter name %s ' % ((TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), ParamName), TableName, CommentId)\r
30fdf114 2577 Index += 1\r
52302d4d 2578\r
30fdf114
LG
2579 if Index < ParamNumber:\r
2580 ErrorMsgList.append('Line %d : Number of doxygen tags in comment less than number of function parameters' % CommentStartLine)\r
2581 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'Number of doxygen tags in comment less than number of function parameters ', TableName, CommentId)\r
2582 # VOID return type, NOT VOID*. VOID* should be matched with a doxygen tag.\r
2583 if (FuncModifier.find('VOID') != -1 or FuncModifier.find('void') != -1) and FuncModifier.find('*') == -1:\r
52302d4d 2584\r
30fdf114
LG
2585 # assume we allow a return description tag for void func. return. that's why 'DoxygenTagNumber - 1' is used instead of 'DoxygenTagNumber'\r
2586 if Index < DoxygenTagNumber - 1 or (Index < DoxygenTagNumber and DoxygenStrList[Index].startswith('@retval')):\r
2587 ErrorMsgList.append('Line %d : VOID return type need NO doxygen tags in comment' % CommentStartLine)\r
2588 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'VOID return type need no doxygen tags in comment ', TableName, CommentId)\r
2589 else:\r
52302d4d 2590 if Index < DoxygenTagNumber and not DoxygenStrList[Index].startswith('@retval') and not DoxygenStrList[Index].startswith('@return'):\r
30fdf114
LG
2591 ErrorMsgList.append('Line %d : Number of @param doxygen tags in comment does NOT match number of function parameters' % CommentStartLine)\r
2592 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'Number of @param doxygen tags in comment does NOT match number of function parameters ', TableName, CommentId)\r
2593 else:\r
2594 if ParamNumber == 0 and DoxygenTagNumber != 0 and ((FuncModifier.find('VOID') != -1 or FuncModifier.find('void') != -1) and FuncModifier.find('*') == -1):\r
2595 ErrorMsgList.append('Line %d : VOID return type need NO doxygen tags in comment' % CommentStartLine)\r
2596 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'VOID return type need NO doxygen tags in comment ', TableName, CommentId)\r
2597 if ParamNumber != 0 and DoxygenTagNumber == 0:\r
2598 ErrorMsgList.append('Line %d : No doxygen tags in comment' % CommentStartLine)\r
2599 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'No doxygen tags in comment ', TableName, CommentId)\r
2600\r
2601if __name__ == '__main__':\r
2602\r
2603# EdkLogger.Initialize()\r
2604# EdkLogger.SetLevel(EdkLogger.QUIET)\r
52302d4d 2605# CollectSourceCodeDataIntoDB(sys.argv[1])\r
b36d134f
LG
2606 try:\r
2607 test_file = sys.argv[1]\r
2608 except IndexError, v:\r
2609 print "Usage: %s filename" % sys.argv[0]\r
2610 sys.exit(1)\r
2611 MsgList = CheckFuncHeaderDoxygenComments(test_file)\r
30fdf114
LG
2612 for Msg in MsgList:\r
2613 print Msg\r
2614 print 'Done!'\r