]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Ecc/c.py
Sync EDKII BaseTools to BaseTools project r1903.
[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
4# Copyright (c) 2009 - 2010, Intel Corporation\r
5# All rights reserved. This program and the accompanying materials\r
6# are licensed and made available under the terms and conditions of the BSD License\r
7# which accompanies this distribution. The full text of the license may be found at\r
8# http://opensource.org/licenses/bsd-license.php\r
9#\r
10# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12#\r
13\r
30fdf114
LG
14import sys\r
15import os\r
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
65 GetDB().TblReport.Insert(ErrorType, OtherMsg = Msg, BelongsToTable = TableName, BelongsToItem = ItemId)\r
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
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
97 IdList.append(IdComment)\r
52302d4d 98\r
30fdf114
LG
99 for pp in FileProfile.PPDirectiveList:\r
100 Type = GetIdType(pp.Content)\r
101 IdPP = DataClass.IdentifierClass(-1, '', '', '', pp.Content, Type, -1, -1, pp.StartPos[0],pp.StartPos[1],pp.EndPos[0],pp.EndPos[1])\r
102 IdList.append(IdPP)\r
52302d4d 103\r
30fdf114
LG
104 for pe in FileProfile.PredicateExpressionList:\r
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
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
30fdf114
LG
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
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
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
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
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
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
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
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
241 TmpStr = td.ToType[LBPos+1:].strip()\r
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
30fdf114
LG
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
264 IdList.append(IdTd)\r
52302d4d 265\r
30fdf114
LG
266 for funcCall in FileProfile.FunctionCallingList:\r
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
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
278def GetParamList(FuncDeclarator, FuncNameLine = 0, FuncNameOffset = 0):\r
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
30fdf114
LG
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
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
517 FullName = os.path.normpath(os.path.join(dirpath, f))\r
518 if os.path.splitext(f)[1] in ('.h', '.c'):\r
519 EdkLogger.info("Parsing " + FullName)\r
520 model = f.endswith('c') and DataClass.MODEL_FILE_C or DataClass.MODEL_FILE_H\r
521 collector = CodeFragmentCollector.CodeFragmentCollector(FullName)\r
522 try:\r
523 collector.ParseFile()\r
524 except UnicodeError:\r
525 ParseErrorFileList.append(FullName)\r
526 collector.CleanFileProfileBuffer()\r
527 collector.ParseFileWithClearedPPDirective()\r
528# collector.PrintFragments()\r
529 BaseName = os.path.basename(f)\r
530 DirName = os.path.dirname(FullName)\r
531 Ext = os.path.splitext(f)[1].lstrip('.')\r
532 ModifiedTime = os.path.getmtime(FullName)\r
533 FileObj = DataClass.FileClass(-1, BaseName, Ext, DirName, FullName, model, ModifiedTime, GetFunctionList(), GetIdentifierList(), [])\r
534 FileObjList.append(FileObj)\r
52302d4d
LG
535 collector.CleanFileProfileBuffer()\r
536\r
30fdf114
LG
537 if len(ParseErrorFileList) > 0:\r
538 EdkLogger.info("Found unrecoverable error during parsing:\n\t%s\n" % "\n\t".join(ParseErrorFileList))\r
52302d4d
LG
539\r
540 Db = GetDB()\r
541 for file in FileObjList:\r
30fdf114
LG
542 Db.InsertOneFile(file)\r
543\r
544 Db.UpdateIdentifierBelongsToFunction()\r
545\r
546def GetTableID(FullFileName, ErrorMsgList = None):\r
547 if ErrorMsgList == None:\r
548 ErrorMsgList = []\r
52302d4d 549\r
30fdf114
LG
550 Db = GetDB()\r
551 SqlStatement = """ select ID\r
552 from File\r
553 where FullPath like '%s'\r
554 """ % FullFileName\r
52302d4d 555\r
30fdf114
LG
556 ResultSet = Db.TblFile.Exec(SqlStatement)\r
557\r
558 FileID = -1\r
559 for Result in ResultSet:\r
560 if FileID != -1:\r
561 ErrorMsgList.append('Duplicate file ID found in DB for file %s' % FullFileName)\r
562 return -2\r
563 FileID = Result[0]\r
564 if FileID == -1:\r
565 ErrorMsgList.append('NO file ID found in DB for file %s' % FullFileName)\r
566 return -1\r
567 return FileID\r
568\r
569def GetIncludeFileList(FullFileName):\r
570 IFList = IncludeFileListDict.get(FullFileName)\r
571 if IFList != None:\r
572 return IFList\r
52302d4d 573\r
30fdf114
LG
574 FileID = GetTableID(FullFileName)\r
575 if FileID < 0:\r
576 return []\r
52302d4d 577\r
30fdf114
LG
578 Db = GetDB()\r
579 FileTable = 'Identifier' + str(FileID)\r
580 SqlStatement = """ select Value\r
581 from %s\r
582 where Model = %d\r
583 """ % (FileTable, DataClass.MODEL_IDENTIFIER_INCLUDE)\r
584 ResultSet = Db.TblFile.Exec(SqlStatement)\r
585 IncludeFileListDict[FullFileName] = ResultSet\r
586 return ResultSet\r
587\r
588def GetFullPathOfIncludeFile(Str, IncludePathList):\r
589 for IncludePath in IncludePathList:\r
590 FullPath = os.path.join(IncludePath, Str)\r
591 FullPath = os.path.normpath(FullPath)\r
592 if os.path.exists(FullPath):\r
593 return FullPath\r
594 return None\r
595\r
596def GetAllIncludeFiles(FullFileName):\r
597 if AllIncludeFileListDict.get(FullFileName) != None:\r
598 return AllIncludeFileListDict.get(FullFileName)\r
52302d4d 599\r
30fdf114
LG
600 FileDirName = os.path.dirname(FullFileName)\r
601 IncludePathList = IncludePathListDict.get(FileDirName)\r
602 if IncludePathList == None:\r
603 IncludePathList = MetaDataParser.GetIncludeListOfFile(EccGlobalData.gWorkspace, FullFileName, GetDB())\r
604 if FileDirName not in IncludePathList:\r
605 IncludePathList.insert(0, FileDirName)\r
606 IncludePathListDict[FileDirName] = IncludePathList\r
607 IncludeFileQueue = []\r
608 for IncludeFile in GetIncludeFileList(FullFileName):\r
609 FileName = IncludeFile[0].lstrip('#').strip()\r
610 FileName = FileName.lstrip('include').strip()\r
611 FileName = FileName.strip('\"')\r
612 FileName = FileName.lstrip('<').rstrip('>').strip()\r
613 FullPath = GetFullPathOfIncludeFile(FileName, IncludePathList)\r
614 if FullPath != None:\r
615 IncludeFileQueue.append(FullPath)\r
52302d4d 616\r
30fdf114
LG
617 i = 0\r
618 while i < len(IncludeFileQueue):\r
619 for IncludeFile in GetIncludeFileList(IncludeFileQueue[i]):\r
620 FileName = IncludeFile[0].lstrip('#').strip()\r
621 FileName = FileName.lstrip('include').strip()\r
622 FileName = FileName.strip('\"')\r
623 FileName = FileName.lstrip('<').rstrip('>').strip()\r
624 FullPath = GetFullPathOfIncludeFile(FileName, IncludePathList)\r
625 if FullPath != None and FullPath not in IncludeFileQueue:\r
626 IncludeFileQueue.insert(i + 1, FullPath)\r
627 i += 1\r
52302d4d 628\r
30fdf114
LG
629 AllIncludeFileListDict[FullFileName] = IncludeFileQueue\r
630 return IncludeFileQueue\r
631\r
632def GetPredicateListFromPredicateExpStr(PES):\r
633\r
634 PredicateList = []\r
635 i = 0\r
636 PredicateBegin = 0\r
637 #PredicateEnd = 0\r
638 LogicOpPos = -1\r
639 p = GetFuncDeclPattern()\r
640 while i < len(PES) - 1:\r
641 if (PES[i].isalnum() or PES[i] == '_' or PES[i] == '*') and LogicOpPos > PredicateBegin:\r
642 PredicateBegin = i\r
643 if (PES[i] == '&' and PES[i+1] == '&') or (PES[i] == '|' and PES[i+1] == '|'):\r
644 LogicOpPos = i\r
645 Exp = PES[PredicateBegin:i].strip()\r
646 # Exp may contain '.' or '->'\r
647 TmpExp = Exp.replace('.', '').replace('->', '')\r
648 if p.match(TmpExp):\r
649 PredicateList.append(Exp)\r
650 else:\r
651 PredicateList.append(Exp.rstrip(';').rstrip(')').strip())\r
652 i += 1\r
52302d4d 653\r
30fdf114
LG
654 if PredicateBegin > LogicOpPos:\r
655 while PredicateBegin < len(PES):\r
656 if PES[PredicateBegin].isalnum() or PES[PredicateBegin] == '_' or PES[PredicateBegin] == '*':\r
657 break\r
658 PredicateBegin += 1\r
659 Exp = PES[PredicateBegin:len(PES)].strip()\r
660 # Exp may contain '.' or '->'\r
661 TmpExp = Exp.replace('.', '').replace('->', '')\r
662 if p.match(TmpExp):\r
663 PredicateList.append(Exp)\r
664 else:\r
665 PredicateList.append(Exp.rstrip(';').rstrip(')').strip())\r
666 return PredicateList\r
52302d4d 667\r
30fdf114
LG
668def GetCNameList(Lvalue, StarList = []):\r
669 Lvalue += ' '\r
670 i = 0\r
671 SearchBegin = 0\r
672 VarStart = -1\r
673 VarEnd = -1\r
674 VarList = []\r
52302d4d 675\r
30fdf114
LG
676 while SearchBegin < len(Lvalue):\r
677 while i < len(Lvalue):\r
678 if Lvalue[i].isalnum() or Lvalue[i] == '_':\r
679 if VarStart == -1:\r
680 VarStart = i\r
681 VarEnd = i\r
682 i += 1\r
683 elif VarEnd != -1:\r
684 VarList.append(Lvalue[VarStart:VarEnd+1])\r
685 i += 1\r
686 break\r
687 else:\r
688 if VarStart == -1 and Lvalue[i] == '*':\r
689 StarList.append('*')\r
690 i += 1\r
691 if VarEnd == -1:\r
692 break\r
52302d4d
LG
693\r
694\r
30fdf114
LG
695 DotIndex = Lvalue[VarEnd:].find('.')\r
696 ArrowIndex = Lvalue[VarEnd:].find('->')\r
697 if DotIndex == -1 and ArrowIndex == -1:\r
698 break\r
699 elif DotIndex == -1 and ArrowIndex != -1:\r
700 SearchBegin = VarEnd + ArrowIndex\r
701 elif ArrowIndex == -1 and DotIndex != -1:\r
702 SearchBegin = VarEnd + DotIndex\r
703 else:\r
52302d4d
LG
704 SearchBegin = VarEnd + ((DotIndex < ArrowIndex) and DotIndex or ArrowIndex)\r
705\r
30fdf114
LG
706 i = SearchBegin\r
707 VarStart = -1\r
708 VarEnd = -1\r
52302d4d
LG
709\r
710 return VarList\r
30fdf114
LG
711\r
712def SplitPredicateByOp(Str, Op, IsFuncCalling = False):\r
713\r
714 Name = Str.strip()\r
715 Value = None\r
52302d4d 716\r
30fdf114
LG
717 if IsFuncCalling:\r
718 Index = 0\r
719 LBFound = False\r
720 UnmatchedLBCount = 0\r
721 while Index < len(Str):\r
722 while not LBFound and Str[Index] != '_' and not Str[Index].isalnum():\r
723 Index += 1\r
52302d4d 724\r
30fdf114
LG
725 while not LBFound and (Str[Index].isalnum() or Str[Index] == '_'):\r
726 Index += 1\r
727 # maybe type-cast at the begining, skip it.\r
728 RemainingStr = Str[Index:].lstrip()\r
729 if RemainingStr.startswith(')') and not LBFound:\r
730 Index += 1\r
731 continue\r
52302d4d 732\r
30fdf114
LG
733 if RemainingStr.startswith('(') and not LBFound:\r
734 LBFound = True\r
52302d4d 735\r
30fdf114
LG
736 if Str[Index] == '(':\r
737 UnmatchedLBCount += 1\r
738 Index += 1\r
739 continue\r
52302d4d 740\r
30fdf114
LG
741 if Str[Index] == ')':\r
742 UnmatchedLBCount -= 1\r
743 Index += 1\r
744 if UnmatchedLBCount == 0:\r
745 break\r
746 continue\r
52302d4d 747\r
30fdf114 748 Index += 1\r
52302d4d 749\r
30fdf114
LG
750 if UnmatchedLBCount > 0:\r
751 return [Name]\r
52302d4d 752\r
30fdf114
LG
753 IndexInRemainingStr = Str[Index:].find(Op)\r
754 if IndexInRemainingStr == -1:\r
755 return [Name]\r
52302d4d 756\r
30fdf114 757 Name = Str[0:Index + IndexInRemainingStr].strip()\r
52302d4d 758 Value = Str[Index+IndexInRemainingStr+len(Op):].strip().strip(')')\r
30fdf114 759 return [Name, Value]\r
52302d4d 760\r
30fdf114
LG
761 TmpStr = Str.rstrip(';').rstrip(')')\r
762 while True:\r
763 Index = TmpStr.rfind(Op)\r
764 if Index == -1:\r
765 return [Name]\r
52302d4d 766\r
30fdf114
LG
767 if Str[Index - 1].isalnum() or Str[Index - 1].isspace() or Str[Index - 1] == ')':\r
768 Name = Str[0:Index].strip()\r
769 Value = Str[Index + len(Op):].strip()\r
52302d4d
LG
770 return [Name, Value]\r
771\r
30fdf114
LG
772 TmpStr = Str[0:Index - 1]\r
773\r
774def SplitPredicateStr(Str):\r
52302d4d
LG
775\r
776 Str = Str.lstrip('(')\r
30fdf114
LG
777 IsFuncCalling = False\r
778 p = GetFuncDeclPattern()\r
779 TmpStr = Str.replace('.', '').replace('->', '')\r
780 if p.match(TmpStr):\r
781 IsFuncCalling = True\r
52302d4d 782\r
30fdf114
LG
783 PredPartList = SplitPredicateByOp(Str, '==', IsFuncCalling)\r
784 if len(PredPartList) > 1:\r
785 return [PredPartList, '==']\r
52302d4d 786\r
30fdf114
LG
787 PredPartList = SplitPredicateByOp(Str, '!=', IsFuncCalling)\r
788 if len(PredPartList) > 1:\r
789 return [PredPartList, '!=']\r
52302d4d 790\r
30fdf114
LG
791 PredPartList = SplitPredicateByOp(Str, '>=', IsFuncCalling)\r
792 if len(PredPartList) > 1:\r
793 return [PredPartList, '>=']\r
52302d4d 794\r
30fdf114
LG
795 PredPartList = SplitPredicateByOp(Str, '<=', IsFuncCalling)\r
796 if len(PredPartList) > 1:\r
797 return [PredPartList, '<=']\r
52302d4d 798\r
30fdf114
LG
799 PredPartList = SplitPredicateByOp(Str, '>', IsFuncCalling)\r
800 if len(PredPartList) > 1:\r
801 return [PredPartList, '>']\r
52302d4d 802\r
30fdf114
LG
803 PredPartList = SplitPredicateByOp(Str, '<', IsFuncCalling)\r
804 if len(PredPartList) > 1:\r
805 return [PredPartList, '<']\r
52302d4d 806\r
30fdf114
LG
807 return [[Str, None], None]\r
808\r
809def GetFuncContainsPE(ExpLine, ResultSet):\r
810 for Result in ResultSet:\r
811 if Result[0] < ExpLine and Result[1] > ExpLine:\r
812 return Result\r
813 return None\r
814\r
815def PatternInModifier(Modifier, SubStr):\r
816 PartList = Modifier.split()\r
817 for Part in PartList:\r
818 if Part == SubStr:\r
819 return True\r
820 return False\r
821\r
822def GetDataTypeFromModifier(ModifierStr):\r
823 MList = ModifierStr.split()\r
824 for M in MList:\r
825 if M in EccGlobalData.gConfig.ModifierList:\r
826 MList.remove(M)\r
827 # remove array sufix\r
828 if M.startswith('['):\r
829 MList.remove(M)\r
52302d4d 830\r
30fdf114
LG
831 ReturnType = ''\r
832 for M in MList:\r
833 ReturnType += M + ' '\r
52302d4d 834\r
30fdf114
LG
835 ReturnType = ReturnType.strip()\r
836 if len(ReturnType) == 0:\r
837 ReturnType = 'VOID'\r
838 return ReturnType\r
839\r
840def DiffModifier(Str1, Str2):\r
841 PartList1 = Str1.split()\r
842 PartList2 = Str2.split()\r
843 if PartList1 == PartList2:\r
844 return False\r
845 else:\r
846 return True\r
52302d4d 847\r
30fdf114 848def GetTypedefDict(FullFileName):\r
52302d4d 849\r
30fdf114
LG
850 Dict = ComplexTypeDict.get(FullFileName)\r
851 if Dict != None:\r
852 return Dict\r
52302d4d 853\r
30fdf114
LG
854 FileID = GetTableID(FullFileName)\r
855 FileTable = 'Identifier' + str(FileID)\r
856 Db = GetDB()\r
857 SqlStatement = """ select Modifier, Name, Value, ID\r
858 from %s\r
859 where Model = %d\r
860 """ % (FileTable, DataClass.MODEL_IDENTIFIER_TYPEDEF)\r
861 ResultSet = Db.TblFile.Exec(SqlStatement)\r
52302d4d 862\r
30fdf114
LG
863 Dict = {}\r
864 for Result in ResultSet:\r
865 if len(Result[0]) == 0:\r
866 Dict[Result[1]] = Result[2]\r
52302d4d 867\r
30fdf114
LG
868 IncludeFileList = GetAllIncludeFiles(FullFileName)\r
869 for F in IncludeFileList:\r
870 FileID = GetTableID(F)\r
871 if FileID < 0:\r
872 continue\r
52302d4d 873\r
30fdf114
LG
874 FileTable = 'Identifier' + str(FileID)\r
875 SqlStatement = """ select Modifier, Name, Value, ID\r
876 from %s\r
877 where Model = %d\r
878 """ % (FileTable, DataClass.MODEL_IDENTIFIER_TYPEDEF)\r
879 ResultSet = Db.TblFile.Exec(SqlStatement)\r
52302d4d 880\r
30fdf114
LG
881 for Result in ResultSet:\r
882 if not Result[2].startswith('FP ('):\r
883 Dict[Result[1]] = Result[2]\r
884 else:\r
885 if len(Result[0]) == 0:\r
886 Dict[Result[1]] = 'VOID'\r
887 else:\r
888 Dict[Result[1]] = GetDataTypeFromModifier(Result[0])\r
52302d4d 889\r
30fdf114
LG
890 ComplexTypeDict[FullFileName] = Dict\r
891 return Dict\r
892\r
893def GetSUDict(FullFileName):\r
52302d4d 894\r
30fdf114
LG
895 Dict = SUDict.get(FullFileName)\r
896 if Dict != None:\r
897 return Dict\r
52302d4d 898\r
30fdf114
LG
899 FileID = GetTableID(FullFileName)\r
900 FileTable = 'Identifier' + str(FileID)\r
901 Db = GetDB()\r
902 SqlStatement = """ select Name, Value, ID\r
903 from %s\r
904 where Model = %d or Model = %d\r
905 """ % (FileTable, DataClass.MODEL_IDENTIFIER_STRUCTURE, DataClass.MODEL_IDENTIFIER_UNION)\r
906 ResultSet = Db.TblFile.Exec(SqlStatement)\r
52302d4d 907\r
30fdf114
LG
908 Dict = {}\r
909 for Result in ResultSet:\r
910 if len(Result[1]) > 0:\r
911 Dict[Result[0]] = Result[1]\r
52302d4d 912\r
30fdf114
LG
913 IncludeFileList = GetAllIncludeFiles(FullFileName)\r
914 for F in IncludeFileList:\r
915 FileID = GetTableID(F)\r
916 if FileID < 0:\r
917 continue\r
52302d4d 918\r
30fdf114
LG
919 FileTable = 'Identifier' + str(FileID)\r
920 SqlStatement = """ select Name, Value, ID\r
921 from %s\r
922 where Model = %d or Model = %d\r
923 """ % (FileTable, DataClass.MODEL_IDENTIFIER_STRUCTURE, DataClass.MODEL_IDENTIFIER_UNION)\r
924 ResultSet = Db.TblFile.Exec(SqlStatement)\r
52302d4d 925\r
30fdf114
LG
926 for Result in ResultSet:\r
927 if len(Result[1]) > 0:\r
928 Dict[Result[0]] = Result[1]\r
52302d4d 929\r
30fdf114
LG
930 SUDict[FullFileName] = Dict\r
931 return Dict\r
932\r
933def StripComments(Str):\r
934 Str += ' '\r
935 ListFromStr = list(Str)\r
52302d4d 936\r
30fdf114
LG
937 InComment = False\r
938 DoubleSlashComment = False\r
939 Index = 0\r
940 while Index < len(ListFromStr):\r
941 # meet new line, then no longer in a comment for //\r
942 if ListFromStr[Index] == '\n':\r
943 if InComment and DoubleSlashComment:\r
944 InComment = False\r
945 DoubleSlashComment = False\r
946 Index += 1\r
947 # check for */ comment end\r
948 elif InComment and not DoubleSlashComment and ListFromStr[Index] == '*' and ListFromStr[Index+1] == '/':\r
949 ListFromStr[Index] = ' '\r
950 Index += 1\r
951 ListFromStr[Index] = ' '\r
952 Index += 1\r
953 InComment = False\r
954 # set comments to spaces\r
955 elif InComment:\r
956 ListFromStr[Index] = ' '\r
957 Index += 1\r
958 # check for // comment\r
959 elif ListFromStr[Index] == '/' and ListFromStr[Index+1] == '/' and ListFromStr[Index+2] != '\n':\r
960 InComment = True\r
961 DoubleSlashComment = True\r
52302d4d 962\r
30fdf114
LG
963 # check for /* comment start\r
964 elif ListFromStr[Index] == '/' and ListFromStr[Index+1] == '*':\r
965 ListFromStr[Index] = ' '\r
966 Index += 1\r
967 ListFromStr[Index] = ' '\r
968 Index += 1\r
969 InComment = True\r
970 else:\r
971 Index += 1\r
972\r
973 # restore from List to String\r
974 Str = "".join(ListFromStr)\r
975 Str = Str.rstrip(' ')\r
52302d4d 976\r
30fdf114
LG
977 return Str\r
978\r
979def GetFinalTypeValue(Type, FieldName, TypedefDict, SUDict):\r
980 Value = TypedefDict.get(Type)\r
981 if Value == None:\r
982 Value = SUDict.get(Type)\r
983 if Value == None:\r
984 return None\r
52302d4d 985\r
30fdf114
LG
986 LBPos = Value.find('{')\r
987 while LBPos == -1:\r
988 FTList = Value.split()\r
989 for FT in FTList:\r
990 if FT not in ('struct', 'union'):\r
991 Value = TypedefDict.get(FT)\r
992 if Value == None:\r
993 Value = SUDict.get(FT)\r
994 break\r
52302d4d 995\r
30fdf114
LG
996 if Value == None:\r
997 return None\r
52302d4d 998\r
30fdf114 999 LBPos = Value.find('{')\r
52302d4d 1000\r
30fdf114
LG
1001# RBPos = Value.find('}')\r
1002 Fields = Value[LBPos + 1:]\r
1003 Fields = StripComments(Fields)\r
1004 FieldsList = Fields.split(';')\r
1005 for Field in FieldsList:\r
1006 Field = Field.strip()\r
1007 Index = Field.rfind(FieldName)\r
1008 if Index < 1:\r
1009 continue\r
1010 if not Field[Index - 1].isalnum():\r
1011 if Index + len(FieldName) == len(Field):\r
1012 Type = GetDataTypeFromModifier(Field[0:Index])\r
1013 return Type.strip()\r
1014 else:\r
52302d4d 1015 # For the condition that the field in struct is an array with [] sufixes...\r
30fdf114
LG
1016 if not Field[Index + len(FieldName)].isalnum():\r
1017 Type = GetDataTypeFromModifier(Field[0:Index])\r
1018 return Type.strip()\r
52302d4d 1019\r
30fdf114 1020 return None\r
52302d4d 1021\r
30fdf114
LG
1022def GetRealType(Type, TypedefDict, TargetType = None):\r
1023 if TargetType != None and Type == TargetType:\r
1024 return Type\r
1025 while TypedefDict.get(Type):\r
1026 Type = TypedefDict.get(Type)\r
1027 if TargetType != None and Type == TargetType:\r
1028 return Type\r
1029 return Type\r
1030\r
1031def GetTypeInfo(RefList, Modifier, FullFileName, TargetType = None):\r
1032 TypedefDict = GetTypedefDict(FullFileName)\r
1033 SUDict = GetSUDict(FullFileName)\r
1034 Type = GetDataTypeFromModifier(Modifier).replace('*', '').strip()\r
52302d4d 1035\r
30fdf114
LG
1036 Type = Type.split()[-1]\r
1037 Index = 0\r
1038 while Index < len(RefList):\r
1039 FieldName = RefList[Index]\r
1040 FromType = GetFinalTypeValue(Type, FieldName, TypedefDict, SUDict)\r
1041 if FromType == None:\r
1042 return None\r
1043 # we want to determine the exact type.\r
1044 if TargetType != None:\r
1045 Type = FromType.split()[0]\r
1046 # we only want to check if it is a pointer\r
1047 else:\r
1048 Type = FromType\r
1049 if Type.find('*') != -1 and Index == len(RefList)-1:\r
1050 return Type\r
1051 Type = FromType.split()[0]\r
52302d4d 1052\r
30fdf114
LG
1053 Index += 1\r
1054\r
1055 Type = GetRealType(Type, TypedefDict, TargetType)\r
1056\r
1057 return Type\r
1058\r
1059def GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall = False, TargetType = None, StarList = None):\r
52302d4d 1060\r
30fdf114
LG
1061 PredVar = PredVarList[0]\r
1062 FileID = GetTableID(FullFileName)\r
52302d4d 1063\r
30fdf114
LG
1064 Db = GetDB()\r
1065 FileTable = 'Identifier' + str(FileID)\r
1066 # search variable in include files\r
52302d4d 1067\r
30fdf114
LG
1068 # it is a function call, search function declarations and definitions\r
1069 if IsFuncCall:\r
1070 SqlStatement = """ select Modifier, ID\r
1071 from %s\r
1072 where Model = %d and Value = \'%s\'\r
1073 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION, PredVar)\r
1074 ResultSet = Db.TblFile.Exec(SqlStatement)\r
52302d4d
LG
1075\r
1076 for Result in ResultSet:\r
30fdf114
LG
1077 Type = GetDataTypeFromModifier(Result[0]).split()[-1]\r
1078 TypedefDict = GetTypedefDict(FullFileName)\r
1079 Type = GetRealType(Type, TypedefDict, TargetType)\r
1080 return Type\r
52302d4d 1081\r
30fdf114
LG
1082 IncludeFileList = GetAllIncludeFiles(FullFileName)\r
1083 for F in IncludeFileList:\r
1084 FileID = GetTableID(F)\r
1085 if FileID < 0:\r
1086 continue\r
52302d4d 1087\r
30fdf114
LG
1088 FileTable = 'Identifier' + str(FileID)\r
1089 SqlStatement = """ select Modifier, ID\r
1090 from %s\r
1091 where Model = %d and Value = \'%s\'\r
1092 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION, PredVar)\r
1093 ResultSet = Db.TblFile.Exec(SqlStatement)\r
52302d4d 1094\r
30fdf114
LG
1095 for Result in ResultSet:\r
1096 Type = GetDataTypeFromModifier(Result[0]).split()[-1]\r
1097 TypedefDict = GetTypedefDict(FullFileName)\r
1098 Type = GetRealType(Type, TypedefDict, TargetType)\r
1099 return Type\r
52302d4d 1100\r
30fdf114
LG
1101 FileID = GetTableID(FullFileName)\r
1102 SqlStatement = """ select Modifier, ID\r
1103 from Function\r
1104 where BelongsToFile = %d and Name = \'%s\'\r
1105 """ % (FileID, PredVar)\r
1106 ResultSet = Db.TblFile.Exec(SqlStatement)\r
52302d4d
LG
1107\r
1108 for Result in ResultSet:\r
30fdf114
LG
1109 Type = GetDataTypeFromModifier(Result[0]).split()[-1]\r
1110 TypedefDict = GetTypedefDict(FullFileName)\r
1111 Type = GetRealType(Type, TypedefDict, TargetType)\r
1112 return Type\r
52302d4d 1113\r
30fdf114
LG
1114 for F in IncludeFileList:\r
1115 FileID = GetTableID(F)\r
1116 if FileID < 0:\r
1117 continue\r
52302d4d 1118\r
30fdf114
LG
1119 FileTable = 'Identifier' + str(FileID)\r
1120 SqlStatement = """ select Modifier, ID\r
1121 from Function\r
1122 where BelongsToFile = %d and Name = \'%s\'\r
1123 """ % (FileID, PredVar)\r
1124 ResultSet = Db.TblFile.Exec(SqlStatement)\r
52302d4d 1125\r
30fdf114
LG
1126 for Result in ResultSet:\r
1127 Type = GetDataTypeFromModifier(Result[0]).split()[-1]\r
1128 TypedefDict = GetTypedefDict(FullFileName)\r
1129 Type = GetRealType(Type, TypedefDict, TargetType)\r
1130 return Type\r
52302d4d 1131\r
30fdf114 1132 return None\r
52302d4d 1133\r
30fdf114
LG
1134 # really variable, search local variable first\r
1135 SqlStatement = """ select Modifier, ID\r
1136 from %s\r
1137 where Model = %d and Name = \'%s\' and StartLine >= %d and StartLine <= %d\r
1138 """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE, PredVar, FuncRecord[0], FuncRecord[1])\r
1139 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1140 VarFound = False\r
1141 for Result in ResultSet:\r
1142 if len(PredVarList) > 1:\r
1143 Type = GetTypeInfo(PredVarList[1:], Result[0], FullFileName, TargetType)\r
1144 return Type\r
1145 else:\r
1146# Type = GetDataTypeFromModifier(Result[0]).split()[-1]\r
1147 TypeList = GetDataTypeFromModifier(Result[0]).split()\r
1148 Type = TypeList[-1]\r
1149 if len(TypeList) > 1 and StarList != None:\r
1150 for Star in StarList:\r
1151 Type = Type.strip()\r
1152 Type = Type.rstrip(Star)\r
1153 # Get real type after de-reference pointers.\r
1154 if len(Type.strip()) == 0:\r
1155 Type = TypeList[-2]\r
1156 TypedefDict = GetTypedefDict(FullFileName)\r
1157 Type = GetRealType(Type, TypedefDict, TargetType)\r
1158 return Type\r
52302d4d 1159\r
30fdf114
LG
1160 # search function parameters second\r
1161 ParamList = GetParamList(FuncRecord[2])\r
1162 for Param in ParamList:\r
1163 if Param.Name.strip() == PredVar:\r
1164 if len(PredVarList) > 1:\r
1165 Type = GetTypeInfo(PredVarList[1:], Param.Modifier, FullFileName, TargetType)\r
1166 return Type\r
1167 else:\r
1168 TypeList = GetDataTypeFromModifier(Param.Modifier).split()\r
1169 Type = TypeList[-1]\r
1170 if len(TypeList) > 1 and StarList != None:\r
1171 for Star in StarList:\r
1172 Type = Type.strip()\r
1173 Type = Type.rstrip(Star)\r
1174 # Get real type after de-reference pointers.\r
1175 if len(Type.strip()) == 0:\r
1176 Type = TypeList[-2]\r
1177 TypedefDict = GetTypedefDict(FullFileName)\r
1178 Type = GetRealType(Type, TypedefDict, TargetType)\r
1179 return Type\r
52302d4d 1180\r
30fdf114
LG
1181 # search global variable next\r
1182 SqlStatement = """ select Modifier, ID\r
1183 from %s\r
1184 where Model = %d and Name = \'%s\' and BelongsToFunction = -1\r
1185 """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE, PredVar)\r
1186 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1187\r
1188 for Result in ResultSet:\r
1189 if len(PredVarList) > 1:\r
1190 Type = GetTypeInfo(PredVarList[1:], Result[0], FullFileName, TargetType)\r
1191 return Type\r
1192 else:\r
1193 TypeList = GetDataTypeFromModifier(Result[0]).split()\r
1194 Type = TypeList[-1]\r
1195 if len(TypeList) > 1 and StarList != None:\r
1196 for Star in StarList:\r
1197 Type = Type.strip()\r
1198 Type = Type.rstrip(Star)\r
1199 # Get real type after de-reference pointers.\r
1200 if len(Type.strip()) == 0:\r
1201 Type = TypeList[-2]\r
1202 TypedefDict = GetTypedefDict(FullFileName)\r
1203 Type = GetRealType(Type, TypedefDict, TargetType)\r
1204 return Type\r
52302d4d 1205\r
30fdf114
LG
1206 IncludeFileList = GetAllIncludeFiles(FullFileName)\r
1207 for F in IncludeFileList:\r
1208 FileID = GetTableID(F)\r
1209 if FileID < 0:\r
1210 continue\r
52302d4d 1211\r
30fdf114
LG
1212 FileTable = 'Identifier' + str(FileID)\r
1213 SqlStatement = """ select Modifier, ID\r
1214 from %s\r
1215 where Model = %d and BelongsToFunction = -1 and Name = \'%s\'\r
1216 """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE, PredVar)\r
1217 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1218\r
1219 for Result in ResultSet:\r
1220 if len(PredVarList) > 1:\r
1221 Type = GetTypeInfo(PredVarList[1:], Result[0], FullFileName, TargetType)\r
1222 return Type\r
1223 else:\r
1224 TypeList = GetDataTypeFromModifier(Result[0]).split()\r
1225 Type = TypeList[-1]\r
1226 if len(TypeList) > 1 and StarList != None:\r
1227 for Star in StarList:\r
1228 Type = Type.strip()\r
1229 Type = Type.rstrip(Star)\r
1230 # Get real type after de-reference pointers.\r
1231 if len(Type.strip()) == 0:\r
1232 Type = TypeList[-2]\r
1233 TypedefDict = GetTypedefDict(FullFileName)\r
1234 Type = GetRealType(Type, TypedefDict, TargetType)\r
1235 return Type\r
1236\r
52302d4d
LG
1237def GetTypeFromArray(Type, Var):\r
1238 Count = Var.count('[')\r
1239\r
1240 while Count > 0:\r
1241 Type = Type.strip()\r
1242 Type = Type.rstrip('*')\r
1243 Count = Count - 1\r
1244\r
1245 return Type\r
1246\r
30fdf114
LG
1247def CheckFuncLayoutReturnType(FullFileName):\r
1248 ErrorMsgList = []\r
52302d4d 1249\r
30fdf114
LG
1250 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1251 if FileID < 0:\r
1252 return ErrorMsgList\r
52302d4d 1253\r
30fdf114
LG
1254 Db = GetDB()\r
1255 FileTable = 'Identifier' + str(FileID)\r
52302d4d 1256 SqlStatement = """ select Modifier, ID, StartLine, StartColumn, EndLine, Value\r
30fdf114
LG
1257 from %s\r
1258 where Model = %d\r
1259 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
1260 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1261 for Result in ResultSet:\r
1262 ReturnType = GetDataTypeFromModifier(Result[0])\r
1263 TypeStart = ReturnType.split()[0]\r
1264 FuncName = Result[5]\r
1265 if EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, FuncName):\r
1266 continue\r
1267 Index = Result[0].find(TypeStart)\r
1268 if Index != 0 or Result[3] != 0:\r
1269 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '[%s] Return Type should appear at the start of line' % FuncName, FileTable, Result[1])\r
52302d4d 1270\r
30fdf114
LG
1271 if Result[2] == Result[4]:\r
1272 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '[%s] Return Type should appear on its own line' % FuncName, FileTable, Result[1])\r
52302d4d 1273\r
30fdf114
LG
1274 SqlStatement = """ select Modifier, ID, StartLine, StartColumn, FunNameStartLine, Name\r
1275 from Function\r
1276 where BelongsToFile = %d\r
1277 """ % (FileID)\r
1278 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1279 for Result in ResultSet:\r
1280 ReturnType = GetDataTypeFromModifier(Result[0])\r
1281 TypeStart = ReturnType.split()[0]\r
1282 FuncName = Result[5]\r
1283 if EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, FuncName):\r
1284 continue\r
1285 Index = Result[0].find(ReturnType)\r
1286 if Index != 0 or Result[3] != 0:\r
1287 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '[%s] Return Type should appear at the start of line' % FuncName, 'Function', Result[1])\r
52302d4d 1288\r
30fdf114
LG
1289 if Result[2] == Result[4]:\r
1290 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '[%s] Return Type should appear on its own line' % FuncName, 'Function', Result[1])\r
52302d4d 1291\r
30fdf114
LG
1292def CheckFuncLayoutModifier(FullFileName):\r
1293 ErrorMsgList = []\r
52302d4d 1294\r
30fdf114
LG
1295 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1296 if FileID < 0:\r
1297 return ErrorMsgList\r
52302d4d 1298\r
30fdf114
LG
1299 Db = GetDB()\r
1300 FileTable = 'Identifier' + str(FileID)\r
1301 SqlStatement = """ select Modifier, ID\r
1302 from %s\r
1303 where Model = %d\r
1304 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
1305 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1306 for Result in ResultSet:\r
1307 ReturnType = GetDataTypeFromModifier(Result[0])\r
1308 TypeStart = ReturnType.split()[0]\r
1309# if len(ReturnType) == 0:\r
1310# continue\r
1311 Index = Result[0].find(TypeStart)\r
1312 if Index != 0:\r
1313 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_OPTIONAL_FUNCTIONAL_MODIFIER, '', FileTable, Result[1])\r
52302d4d 1314\r
30fdf114
LG
1315 SqlStatement = """ select Modifier, ID\r
1316 from Function\r
1317 where BelongsToFile = %d\r
1318 """ % (FileID)\r
1319 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1320 for Result in ResultSet:\r
1321 ReturnType = GetDataTypeFromModifier(Result[0])\r
1322 TypeStart = ReturnType.split()[0]\r
1323# if len(ReturnType) == 0:\r
1324# continue\r
1325 Index = Result[0].find(TypeStart)\r
1326 if Index != 0:\r
1327 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_OPTIONAL_FUNCTIONAL_MODIFIER, '', 'Function', Result[1])\r
1328\r
1329def CheckFuncLayoutName(FullFileName):\r
1330 ErrorMsgList = []\r
1331 # Parameter variable format pattern.\r
1332 Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$')\r
1333 ParamIgnoreList = ('VOID', '...')\r
1334 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1335 if FileID < 0:\r
1336 return ErrorMsgList\r
52302d4d 1337\r
30fdf114
LG
1338 Db = GetDB()\r
1339 FileTable = 'Identifier' + str(FileID)\r
1340 SqlStatement = """ select Name, ID, EndColumn, Value\r
1341 from %s\r
1342 where Model = %d\r
1343 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
1344 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1345 for Result in ResultSet:\r
1346 FuncName = Result[3]\r
1347 if EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, FuncName):\r
1348 continue\r
1349 if Result[2] != 0:\r
1350 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Function name [%s] should appear at the start of a line' % FuncName, FileTable, Result[1])\r
1351 ParamList = GetParamList(Result[0])\r
1352 if len(ParamList) == 0:\r
1353 continue\r
1354 StartLine = 0\r
1355 for Param in ParamList:\r
1356 if Param.StartLine <= StartLine:\r
1357 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Parameter %s should be in its own line.' % Param.Name, FileTable, Result[1])\r
1358 if Param.StartLine - StartLine > 1:\r
52302d4d 1359 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Empty line appears before Parameter %s.' % Param.Name, FileTable, Result[1])\r
30fdf114
LG
1360 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
1361 PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Parameter [%s] NOT follow naming convention.' % Param.Name, FileTable, Result[1])\r
1362 StartLine = Param.StartLine\r
52302d4d 1363\r
30fdf114
LG
1364 if not Result[0].endswith('\n )') and not Result[0].endswith('\r )'):\r
1365 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, '\')\' should be on a new line and indented two spaces', FileTable, Result[1])\r
52302d4d 1366\r
30fdf114
LG
1367 SqlStatement = """ select Modifier, ID, FunNameStartColumn, Name\r
1368 from Function\r
1369 where BelongsToFile = %d\r
1370 """ % (FileID)\r
1371 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1372 for Result in ResultSet:\r
1373 FuncName = Result[3]\r
1374 if EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, FuncName):\r
1375 continue\r
1376 if Result[2] != 0:\r
1377 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Function name [%s] should appear at the start of a line' % FuncName, 'Function', Result[1])\r
1378 ParamList = GetParamList(Result[0])\r
1379 if len(ParamList) == 0:\r
1380 continue\r
1381 StartLine = 0\r
1382 for Param in ParamList:\r
1383 if Param.StartLine <= StartLine:\r
1384 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Parameter %s should be in its own line.' % Param.Name, 'Function', Result[1])\r
1385 if Param.StartLine - StartLine > 1:\r
1386 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Empty line appears before Parameter %s.' % Param.Name, 'Function', Result[1])\r
1387 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
1388 PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Parameter [%s] NOT follow naming convention.' % Param.Name, FileTable, Result[1])\r
1389 StartLine = Param.StartLine\r
1390 if not Result[0].endswith('\n )') and not Result[0].endswith('\r )'):\r
1391 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, '\')\' should be on a new line and indented two spaces', 'Function', Result[1])\r
1392\r
1393def CheckFuncLayoutPrototype(FullFileName):\r
1394 ErrorMsgList = []\r
52302d4d 1395\r
30fdf114
LG
1396 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1397 if FileID < 0:\r
1398 return ErrorMsgList\r
52302d4d 1399\r
30fdf114
LG
1400 FileTable = 'Identifier' + str(FileID)\r
1401 Db = GetDB()\r
1402 SqlStatement = """ select Modifier, Header, Name, ID\r
1403 from Function\r
1404 where BelongsToFile = %d\r
1405 """ % (FileID)\r
1406 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1407 if len(ResultSet) == 0:\r
1408 return ErrorMsgList\r
52302d4d 1409\r
30fdf114
LG
1410 FuncDefList = []\r
1411 for Result in ResultSet:\r
1412 FuncDefList.append(Result)\r
52302d4d 1413\r
30fdf114
LG
1414 SqlStatement = """ select Modifier, Name, ID\r
1415 from %s\r
1416 where Model = %d\r
1417 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
1418 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1419 FuncDeclList = []\r
1420 for Result in ResultSet:\r
1421 FuncDeclList.append(Result)\r
52302d4d 1422\r
30fdf114
LG
1423 UndeclFuncList = []\r
1424 for FuncDef in FuncDefList:\r
1425 FuncName = FuncDef[2].strip()\r
1426 FuncModifier = FuncDef[0]\r
1427 FuncDefHeader = FuncDef[1]\r
1428 for FuncDecl in FuncDeclList:\r
1429 LBPos = FuncDecl[1].find('(')\r
1430 DeclName = FuncDecl[1][0:LBPos].strip()\r
1431 DeclModifier = FuncDecl[0]\r
1432 if DeclName == FuncName:\r
1433 if DiffModifier(FuncModifier, DeclModifier) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, FuncName):\r
1434 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, 'Function [%s] modifier different with prototype.' % FuncName, 'Function', FuncDef[3])\r
1435 ParamListOfDef = GetParamList(FuncDefHeader)\r
1436 ParamListOfDecl = GetParamList(FuncDecl[1])\r
52302d4d
LG
1437 if len(ParamListOfDef) != len(ParamListOfDecl) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_2, FuncName):\r
1438 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_2, 'Parameter number different in function [%s].' % FuncName, 'Function', FuncDef[3])\r
30fdf114
LG
1439 break\r
1440\r
1441 Index = 0\r
1442 while Index < len(ParamListOfDef):\r
52302d4d
LG
1443 if DiffModifier(ParamListOfDef[Index].Modifier, ParamListOfDecl[Index].Modifier) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_3, FuncName):\r
1444 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
1445 Index += 1\r
1446 break\r
1447 else:\r
1448 UndeclFuncList.append(FuncDef)\r
52302d4d 1449\r
30fdf114
LG
1450 IncludeFileList = GetAllIncludeFiles(FullFileName)\r
1451 FuncDeclList = []\r
1452 for F in IncludeFileList:\r
1453 FileID = GetTableID(F, ErrorMsgList)\r
1454 if FileID < 0:\r
1455 continue\r
52302d4d 1456\r
30fdf114
LG
1457 FileTable = 'Identifier' + str(FileID)\r
1458 SqlStatement = """ select Modifier, Name, ID\r
1459 from %s\r
1460 where Model = %d\r
1461 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
1462 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1463\r
1464 for Result in ResultSet:\r
1465 FuncDeclList.append(Result)\r
52302d4d 1466\r
30fdf114
LG
1467 for FuncDef in UndeclFuncList:\r
1468 FuncName = FuncDef[2].strip()\r
1469 FuncModifier = FuncDef[0]\r
1470 FuncDefHeader = FuncDef[1]\r
1471 for FuncDecl in FuncDeclList:\r
1472 LBPos = FuncDecl[1].find('(')\r
1473 DeclName = FuncDecl[1][0:LBPos].strip()\r
1474 DeclModifier = FuncDecl[0]\r
1475 if DeclName == FuncName:\r
1476 if DiffModifier(FuncModifier, DeclModifier) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, FuncName):\r
1477 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, 'Function [%s] modifier different with prototype.' % FuncName, 'Function', FuncDef[3])\r
1478 ParamListOfDef = GetParamList(FuncDefHeader)\r
1479 ParamListOfDecl = GetParamList(FuncDecl[1])\r
52302d4d
LG
1480 if len(ParamListOfDef) != len(ParamListOfDecl) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_2, FuncName):\r
1481 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_2, 'Parameter number different in function [%s].' % FuncName, 'Function', FuncDef[3])\r
30fdf114
LG
1482 break\r
1483\r
1484 Index = 0\r
1485 while Index < len(ParamListOfDef):\r
52302d4d
LG
1486 if DiffModifier(ParamListOfDef[Index].Modifier, ParamListOfDecl[Index].Modifier) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_3, FuncName):\r
1487 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
1488 Index += 1\r
1489 break\r
52302d4d 1490\r
30fdf114
LG
1491def CheckFuncLayoutBody(FullFileName):\r
1492 ErrorMsgList = []\r
52302d4d 1493\r
30fdf114
LG
1494 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1495 if FileID < 0:\r
1496 return ErrorMsgList\r
52302d4d 1497\r
30fdf114
LG
1498 FileTable = 'Identifier' + str(FileID)\r
1499 Db = GetDB()\r
1500 SqlStatement = """ select BodyStartColumn, EndColumn, ID\r
1501 from Function\r
1502 where BelongsToFile = %d\r
1503 """ % (FileID)\r
1504 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1505 if len(ResultSet) == 0:\r
1506 return ErrorMsgList\r
1507 for Result in ResultSet:\r
1508 if Result[0] != 0:\r
1509 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY, 'open brace should be at the very beginning of a line.', 'Function', Result[2])\r
1510 if Result[1] != 0:\r
1511 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY, 'close brace should be at the very beginning of a line.', 'Function', Result[2])\r
1512\r
1513def CheckFuncLayoutLocalVariable(FullFileName):\r
1514 ErrorMsgList = []\r
52302d4d 1515\r
30fdf114
LG
1516 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1517 if FileID < 0:\r
1518 return ErrorMsgList\r
52302d4d 1519\r
30fdf114
LG
1520 Db = GetDB()\r
1521 FileTable = 'Identifier' + str(FileID)\r
1522 SqlStatement = """ select ID\r
1523 from Function\r
1524 where BelongsToFile = %d\r
1525 """ % (FileID)\r
1526 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1527 if len(ResultSet) == 0:\r
1528 return ErrorMsgList\r
1529 FL = []\r
1530 for Result in ResultSet:\r
1531 FL.append(Result)\r
52302d4d 1532\r
30fdf114
LG
1533 for F in FL:\r
1534 SqlStatement = """ select Name, Value, ID\r
1535 from %s\r
1536 where Model = %d and BelongsToFunction = %d\r
1537 """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE, F[0])\r
1538 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1539 if len(ResultSet) == 0:\r
1540 continue\r
52302d4d 1541\r
30fdf114
LG
1542 for Result in ResultSet:\r
1543 if len(Result[1]) > 0:\r
1544 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_NO_INIT_OF_VARIABLE, 'Variable Name: %s' % Result[0], FileTable, Result[2])\r
52302d4d 1545\r
30fdf114
LG
1546def CheckMemberVariableFormat(Name, Value, FileTable, TdId, ModelId):\r
1547 ErrMsgList = []\r
1548 # Member variable format pattern.\r
1549 Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$')\r
52302d4d 1550\r
30fdf114
LG
1551 LBPos = Value.find('{')\r
1552 RBPos = Value.rfind('}')\r
1553 if LBPos == -1 or RBPos == -1:\r
1554 return ErrMsgList\r
52302d4d 1555\r
30fdf114
LG
1556 Fields = Value[LBPos + 1 : RBPos]\r
1557 Fields = StripComments(Fields).strip()\r
1558 NestPos = Fields.find ('struct')\r
1559 if NestPos != -1 and (NestPos + len('struct') < len(Fields)):\r
1560 if not Fields[NestPos + len('struct') + 1].isalnum():\r
1561 if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, Name):\r
1562 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, 'Nested struct in [%s].' % (Name), FileTable, TdId)\r
1563 return ErrMsgList\r
1564 NestPos = Fields.find ('union')\r
1565 if NestPos != -1 and (NestPos + len('union') < len(Fields)):\r
1566 if not Fields[NestPos + len('union') + 1].isalnum():\r
1567 if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, Name):\r
1568 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, 'Nested union in [%s].' % (Name), FileTable, TdId)\r
1569 return ErrMsgList\r
1570 NestPos = Fields.find ('enum')\r
1571 if NestPos != -1 and (NestPos + len('enum') < len(Fields)):\r
1572 if not Fields[NestPos + len('enum') + 1].isalnum():\r
1573 if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, Name):\r
1574 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, 'Nested enum in [%s].' % (Name), FileTable, TdId)\r
1575 return ErrMsgList\r
52302d4d 1576\r
30fdf114
LG
1577 if ModelId == DataClass.MODEL_IDENTIFIER_ENUMERATE:\r
1578 FieldsList = Fields.split(',')\r
1579 # deal with enum is pre-assigned a value by function call ( , , , ...)\r
1580 QuoteCount = 0\r
1581 Index = 0\r
1582 RemoveCurrentElement = False\r
1583 while Index < len(FieldsList):\r
1584 Field = FieldsList[Index]\r
52302d4d 1585\r
30fdf114
LG
1586 if Field.find('(') != -1:\r
1587 QuoteCount += 1\r
1588 RemoveCurrentElement = True\r
1589 Index += 1\r
1590 continue\r
52302d4d 1591\r
30fdf114
LG
1592 if Field.find(')') != -1 and QuoteCount > 0:\r
1593 QuoteCount -= 1\r
1594\r
52302d4d 1595 if RemoveCurrentElement:\r
30fdf114
LG
1596 FieldsList.remove(Field)\r
1597 if QuoteCount == 0:\r
1598 RemoveCurrentElement = False\r
1599 continue\r
52302d4d 1600\r
30fdf114
LG
1601 if QuoteCount == 0:\r
1602 RemoveCurrentElement = False\r
52302d4d 1603\r
30fdf114
LG
1604 Index += 1\r
1605 else:\r
1606 FieldsList = Fields.split(';')\r
52302d4d 1607\r
30fdf114
LG
1608 for Field in FieldsList:\r
1609 Field = Field.strip()\r
1610 if Field == '':\r
1611 continue\r
52302d4d 1612 # For the condition that the field in struct is an array with [] sufixes...\r
30fdf114
LG
1613 if Field[-1] == ']':\r
1614 LBPos = Field.find('[')\r
1615 Field = Field[0:LBPos]\r
1616 # For the condition that bit field ": Number"\r
1617 if Field.find(':') != -1:\r
1618 ColonPos = Field.find(':')\r
1619 Field = Field[0:ColonPos]\r
52302d4d 1620\r
30fdf114
LG
1621 Field = Field.strip()\r
1622 if Field == '':\r
1623 continue\r
1624 # Enum could directly assign value to variable\r
1625 Field = Field.split('=')[0].strip()\r
52302d4d 1626 TokenList = Field.split()\r
30fdf114
LG
1627 # Remove pointers before variable\r
1628 if not Pattern.match(TokenList[-1].lstrip('*')):\r
1629 ErrMsgList.append(TokenList[-1].lstrip('*'))\r
52302d4d 1630\r
30fdf114
LG
1631 return ErrMsgList\r
1632\r
1633def CheckDeclTypedefFormat(FullFileName, ModelId):\r
1634 ErrorMsgList = []\r
52302d4d 1635\r
30fdf114
LG
1636 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1637 if FileID < 0:\r
1638 return ErrorMsgList\r
52302d4d 1639\r
30fdf114
LG
1640 Db = GetDB()\r
1641 FileTable = 'Identifier' + str(FileID)\r
1642 SqlStatement = """ select Name, StartLine, EndLine, ID, Value\r
1643 from %s\r
1644 where Model = %d\r
1645 """ % (FileTable, ModelId)\r
1646 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1647 ResultList = []\r
1648 for Result in ResultSet:\r
1649 ResultList.append(Result)\r
52302d4d 1650\r
30fdf114
LG
1651 ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_ALL\r
1652 if ModelId == DataClass.MODEL_IDENTIFIER_STRUCTURE:\r
1653 ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_STRUCTURE_DECLARATION\r
1654 elif ModelId == DataClass.MODEL_IDENTIFIER_ENUMERATE:\r
1655 ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_ENUMERATED_TYPE\r
1656 elif ModelId == DataClass.MODEL_IDENTIFIER_UNION:\r
1657 ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_UNION_TYPE\r
52302d4d 1658\r
30fdf114
LG
1659 SqlStatement = """ select Modifier, Name, Value, StartLine, EndLine, ID\r
1660 from %s\r
1661 where Model = %d\r
1662 """ % (FileTable, DataClass.MODEL_IDENTIFIER_TYPEDEF)\r
1663 TdSet = Db.TblFile.Exec(SqlStatement)\r
1664 TdList = []\r
1665 for Td in TdSet:\r
1666 TdList.append(Td)\r
1667 # Check member variable name format that from typedefs of ONLY this file.\r
1668 for Td in TdList:\r
1669 Name = Td[1].strip()\r
1670 Value = Td[2].strip()\r
1671 if Value.startswith('enum'):\r
1672 ValueModelId = DataClass.MODEL_IDENTIFIER_ENUMERATE\r
1673 elif Value.startswith('struct'):\r
1674 ValueModelId = DataClass.MODEL_IDENTIFIER_STRUCTURE\r
1675 elif Value.startswith('union'):\r
1676 ValueModelId = DataClass.MODEL_IDENTIFIER_UNION\r
1677 else:\r
1678 continue\r
52302d4d 1679\r
30fdf114
LG
1680 if ValueModelId != ModelId:\r
1681 continue\r
1682 # Check member variable format.\r
1683 ErrMsgList = CheckMemberVariableFormat(Name, Value, FileTable, Td[5], ModelId)\r
1684 for ErrMsg in ErrMsgList:\r
1685 if EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Name+'.'+ErrMsg):\r
1686 continue\r
1687 PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Member variable [%s] NOT follow naming convention.' % (Name+'.'+ErrMsg), FileTable, Td[5])\r
52302d4d 1688\r
30fdf114
LG
1689 # First check in current file to see whether struct/union/enum is typedef-ed.\r
1690 UntypedefedList = []\r
1691 for Result in ResultList:\r
1692 # Check member variable format.\r
1693 Name = Result[0].strip()\r
1694 Value = Result[4].strip()\r
1695 if Value.startswith('enum'):\r
1696 ValueModelId = DataClass.MODEL_IDENTIFIER_ENUMERATE\r
1697 elif Value.startswith('struct'):\r
1698 ValueModelId = DataClass.MODEL_IDENTIFIER_STRUCTURE\r
1699 elif Value.startswith('union'):\r
1700 ValueModelId = DataClass.MODEL_IDENTIFIER_UNION\r
1701 else:\r
1702 continue\r
52302d4d 1703\r
30fdf114
LG
1704 if ValueModelId != ModelId:\r
1705 continue\r
1706 ErrMsgList = CheckMemberVariableFormat(Name, Value, FileTable, Result[3], ModelId)\r
1707 for ErrMsg in ErrMsgList:\r
1708 if EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Result[0]+'.'+ErrMsg):\r
1709 continue\r
1710 PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Member variable [%s] NOT follow naming convention.' % (Result[0]+'.'+ErrMsg), FileTable, Result[3])\r
1711 # Check whether it is typedefed.\r
1712 Found = False\r
1713 for Td in TdList:\r
1714 # skip function pointer\r
1715 if len(Td[0]) > 0:\r
1716 continue\r
1717 if Result[1] >= Td[3] and Td[4] >= Result[2]:\r
1718 Found = True\r
1719 if not Td[1].isupper():\r
1720 PrintErrorMsg(ErrorType, 'Typedef should be UPPER case', FileTable, Td[5])\r
1721 if Result[0] in Td[2].split():\r
1722 Found = True\r
1723 if not Td[1].isupper():\r
1724 PrintErrorMsg(ErrorType, 'Typedef should be UPPER case', FileTable, Td[5])\r
1725 if Found:\r
1726 break\r
52302d4d 1727\r
30fdf114
LG
1728 if not Found:\r
1729 UntypedefedList.append(Result)\r
1730 continue\r
52302d4d 1731\r
30fdf114
LG
1732 if len(UntypedefedList) == 0:\r
1733 return\r
52302d4d 1734\r
30fdf114
LG
1735 IncludeFileList = GetAllIncludeFiles(FullFileName)\r
1736 TdList = []\r
1737 for F in IncludeFileList:\r
1738 FileID = GetTableID(F, ErrorMsgList)\r
1739 if FileID < 0:\r
1740 continue\r
52302d4d 1741\r
30fdf114
LG
1742 IncludeFileTable = 'Identifier' + str(FileID)\r
1743 SqlStatement = """ select Modifier, Name, Value, StartLine, EndLine, ID\r
1744 from %s\r
1745 where Model = %d\r
1746 """ % (IncludeFileTable, DataClass.MODEL_IDENTIFIER_TYPEDEF)\r
1747 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1748 TdList.extend(ResultSet)\r
52302d4d 1749\r
30fdf114 1750 for Result in UntypedefedList:\r
52302d4d 1751\r
30fdf114
LG
1752 # Check whether it is typedefed.\r
1753 Found = False\r
1754 for Td in TdList:\r
52302d4d 1755\r
30fdf114
LG
1756 if len(Td[0]) > 0:\r
1757 continue\r
1758 if Result[1] >= Td[3] and Td[4] >= Result[2]:\r
1759 Found = True\r
1760 if not Td[1].isupper():\r
1761 PrintErrorMsg(ErrorType, 'Typedef should be UPPER case', FileTable, Td[5])\r
1762 if Result[0] in Td[2].split():\r
1763 Found = True\r
1764 if not Td[1].isupper():\r
1765 PrintErrorMsg(ErrorType, 'Typedef should be UPPER case', FileTable, Td[5])\r
1766 if Found:\r
1767 break\r
52302d4d 1768\r
30fdf114
LG
1769 if not Found:\r
1770 PrintErrorMsg(ErrorType, 'No Typedef for %s' % Result[0], FileTable, Result[3])\r
1771 continue\r
52302d4d 1772\r
30fdf114
LG
1773def CheckDeclStructTypedef(FullFileName):\r
1774 CheckDeclTypedefFormat(FullFileName, DataClass.MODEL_IDENTIFIER_STRUCTURE)\r
1775\r
1776def CheckDeclEnumTypedef(FullFileName):\r
1777 CheckDeclTypedefFormat(FullFileName, DataClass.MODEL_IDENTIFIER_ENUMERATE)\r
52302d4d 1778\r
30fdf114
LG
1779def CheckDeclUnionTypedef(FullFileName):\r
1780 CheckDeclTypedefFormat(FullFileName, DataClass.MODEL_IDENTIFIER_UNION)\r
1781\r
1782def CheckDeclArgModifier(FullFileName):\r
1783 ErrorMsgList = []\r
52302d4d 1784\r
30fdf114
LG
1785 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1786 if FileID < 0:\r
1787 return ErrorMsgList\r
52302d4d 1788\r
30fdf114
LG
1789 Db = GetDB()\r
1790 FileTable = 'Identifier' + str(FileID)\r
1791 SqlStatement = """ select Modifier, Name, ID\r
1792 from %s\r
1793 where Model = %d\r
1794 """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE)\r
1795 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1796 ModifierTuple = ('IN', 'OUT', 'OPTIONAL', 'UNALIGNED')\r
1797 MAX_MODIFIER_LENGTH = 100\r
1798 for Result in ResultSet:\r
1799 for Modifier in ModifierTuple:\r
1800 if PatternInModifier(Result[0], Modifier) and len(Result[0]) < MAX_MODIFIER_LENGTH:\r
1801 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER, 'Variable Modifier %s' % Result[0], FileTable, Result[2])\r
1802 break\r
52302d4d 1803\r
30fdf114
LG
1804 SqlStatement = """ select Modifier, Name, ID\r
1805 from %s\r
1806 where Model = %d\r
1807 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
1808 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1809 for Result in ResultSet:\r
1810 for Modifier in ModifierTuple:\r
1811 if PatternInModifier(Result[0], Modifier):\r
1812 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER, 'Return Type Modifier %s' % Result[0], FileTable, Result[2])\r
1813 break\r
52302d4d 1814\r
30fdf114
LG
1815 SqlStatement = """ select Modifier, Header, ID\r
1816 from Function\r
1817 where BelongsToFile = %d\r
1818 """ % (FileID)\r
1819 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1820 for Result in ResultSet:\r
1821 for Modifier in ModifierTuple:\r
1822 if PatternInModifier(Result[0], Modifier):\r
1823 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER, 'Return Type Modifier %s' % Result[0], FileTable, Result[2])\r
1824 break\r
1825\r
1826def CheckDeclNoUseCType(FullFileName):\r
1827 ErrorMsgList = []\r
52302d4d 1828\r
30fdf114
LG
1829 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1830 if FileID < 0:\r
1831 return ErrorMsgList\r
52302d4d 1832\r
30fdf114
LG
1833 Db = GetDB()\r
1834 FileTable = 'Identifier' + str(FileID)\r
1835 SqlStatement = """ select Modifier, Name, ID\r
1836 from %s\r
1837 where Model = %d\r
1838 """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE)\r
1839 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1840 CTypeTuple = ('int', 'unsigned', 'char', 'void', 'static', 'long')\r
1841 for Result in ResultSet:\r
1842 for Type in CTypeTuple:\r
1843 if PatternInModifier(Result[0], Type):\r
1844 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, 'Variable type %s' % Type, FileTable, Result[2])\r
1845 break\r
52302d4d 1846\r
30fdf114
LG
1847 SqlStatement = """ select Modifier, Name, ID, Value\r
1848 from %s\r
1849 where Model = %d\r
1850 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
1851 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1852 for Result in ResultSet:\r
1853 ParamList = GetParamList(Result[1])\r
1854 FuncName = Result[3]\r
1855 if EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, FuncName):\r
1856 continue\r
1857 for Type in CTypeTuple:\r
1858 if PatternInModifier(Result[0], Type):\r
1859 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, '%s Return type %s' % (FuncName, Result[0]), FileTable, Result[2])\r
52302d4d 1860\r
30fdf114
LG
1861 for Param in ParamList:\r
1862 if PatternInModifier(Param.Modifier, Type):\r
1863 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, 'Parameter %s' % Param.Name, FileTable, Result[2])\r
52302d4d 1864\r
30fdf114
LG
1865 SqlStatement = """ select Modifier, Header, ID, Name\r
1866 from Function\r
1867 where BelongsToFile = %d\r
1868 """ % (FileID)\r
1869 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1870 for Result in ResultSet:\r
1871 ParamList = GetParamList(Result[1])\r
1872 FuncName = Result[3]\r
1873 if EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, FuncName):\r
1874 continue\r
1875 for Type in CTypeTuple:\r
1876 if PatternInModifier(Result[0], Type):\r
1877 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, '[%s] Return type %s' % (FuncName, Result[0]), FileTable, Result[2])\r
52302d4d 1878\r
30fdf114
LG
1879 for Param in ParamList:\r
1880 if PatternInModifier(Param.Modifier, Type):\r
1881 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, 'Parameter %s' % Param.Name, FileTable, Result[2])\r
52302d4d 1882\r
30fdf114
LG
1883\r
1884def CheckPointerNullComparison(FullFileName):\r
1885 ErrorMsgList = []\r
52302d4d 1886\r
30fdf114
LG
1887 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1888 if FileID < 0:\r
1889 return ErrorMsgList\r
52302d4d 1890\r
30fdf114
LG
1891 # cache the found function return type to accelerate later checking in this file.\r
1892 FuncReturnTypeDict = {}\r
52302d4d 1893\r
30fdf114
LG
1894 Db = GetDB()\r
1895 FileTable = 'Identifier' + str(FileID)\r
1896 SqlStatement = """ select Value, StartLine, ID\r
1897 from %s\r
1898 where Model = %d\r
1899 """ % (FileTable, DataClass.MODEL_IDENTIFIER_PREDICATE_EXPRESSION)\r
1900 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1901 if len(ResultSet) == 0:\r
1902 return\r
1903 PSL = []\r
1904 for Result in ResultSet:\r
1905 PSL.append([Result[0], Result[1], Result[2]])\r
52302d4d 1906\r
30fdf114
LG
1907 SqlStatement = """ select BodyStartLine, EndLine, Header, Modifier, ID\r
1908 from Function\r
1909 where BelongsToFile = %d\r
1910 """ % (FileID)\r
1911 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1912 FL = []\r
1913 for Result in ResultSet:\r
1914 FL.append([Result[0], Result[1], Result[2], Result[3], Result[4]])\r
52302d4d 1915\r
30fdf114
LG
1916 p = GetFuncDeclPattern()\r
1917 for Str in PSL:\r
1918 FuncRecord = GetFuncContainsPE(Str[1], FL)\r
1919 if FuncRecord == None:\r
1920 continue\r
52302d4d 1921\r
30fdf114
LG
1922 for Exp in GetPredicateListFromPredicateExpStr(Str[0]):\r
1923 PredInfo = SplitPredicateStr(Exp)\r
1924 if PredInfo[1] == None:\r
1925 PredVarStr = PredInfo[0][0].strip()\r
1926 IsFuncCall = False\r
1927 SearchInCache = False\r
1928 # PredVarStr may contain '.' or '->'\r
1929 TmpStr = PredVarStr.replace('.', '').replace('->', '')\r
1930 if p.match(TmpStr):\r
1931 PredVarStr = PredVarStr[0:PredVarStr.find('(')]\r
1932 SearchInCache = True\r
1933 # Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable.\r
52302d4d 1934 if TmpStr.startswith(PredVarStr):\r
30fdf114 1935 IsFuncCall = True\r
52302d4d 1936\r
30fdf114
LG
1937 if PredVarStr.strip() in IgnoredKeywordList:\r
1938 continue\r
1939 StarList = []\r
1940 PredVarList = GetCNameList(PredVarStr, StarList)\r
1941 # No variable found, maybe value first? like (0 == VarName)\r
1942 if len(PredVarList) == 0:\r
1943 continue\r
1944 if SearchInCache:\r
1945 Type = FuncReturnTypeDict.get(PredVarStr)\r
1946 if Type != None:\r
1947 if Type.find('*') != -1:\r
1948 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
1949 continue\r
52302d4d 1950\r
30fdf114
LG
1951 if PredVarStr in FuncReturnTypeDict:\r
1952 continue\r
52302d4d 1953\r
30fdf114
LG
1954 Type = GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall, None, StarList)\r
1955 if SearchInCache:\r
1956 FuncReturnTypeDict[PredVarStr] = Type\r
1957 if Type == None:\r
1958 continue\r
52302d4d 1959 Type = GetTypeFromArray(Type, PredVarStr)\r
30fdf114
LG
1960 if Type.find('*') != -1:\r
1961 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
1962\r
1963def CheckNonBooleanValueComparison(FullFileName):\r
1964 ErrorMsgList = []\r
52302d4d 1965\r
30fdf114
LG
1966 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1967 if FileID < 0:\r
1968 return ErrorMsgList\r
52302d4d 1969\r
30fdf114
LG
1970 # cache the found function return type to accelerate later checking in this file.\r
1971 FuncReturnTypeDict = {}\r
52302d4d 1972\r
30fdf114
LG
1973 Db = GetDB()\r
1974 FileTable = 'Identifier' + str(FileID)\r
1975 SqlStatement = """ select Value, StartLine, ID\r
1976 from %s\r
1977 where Model = %d\r
1978 """ % (FileTable, DataClass.MODEL_IDENTIFIER_PREDICATE_EXPRESSION)\r
1979 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1980 if len(ResultSet) == 0:\r
1981 return\r
1982 PSL = []\r
1983 for Result in ResultSet:\r
1984 PSL.append([Result[0], Result[1], Result[2]])\r
52302d4d 1985\r
30fdf114
LG
1986 SqlStatement = """ select BodyStartLine, EndLine, Header, Modifier, ID\r
1987 from Function\r
1988 where BelongsToFile = %d\r
1989 """ % (FileID)\r
1990 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1991 FL = []\r
1992 for Result in ResultSet:\r
1993 FL.append([Result[0], Result[1], Result[2], Result[3], Result[4]])\r
52302d4d 1994\r
30fdf114
LG
1995 p = GetFuncDeclPattern()\r
1996 for Str in PSL:\r
1997 FuncRecord = GetFuncContainsPE(Str[1], FL)\r
1998 if FuncRecord == None:\r
1999 continue\r
52302d4d 2000\r
30fdf114
LG
2001 for Exp in GetPredicateListFromPredicateExpStr(Str[0]):\r
2002# if p.match(Exp):\r
2003# continue\r
2004 PredInfo = SplitPredicateStr(Exp)\r
2005 if PredInfo[1] == None:\r
2006 PredVarStr = PredInfo[0][0].strip()\r
2007 IsFuncCall = False\r
2008 SearchInCache = False\r
2009 # PredVarStr may contain '.' or '->'\r
2010 TmpStr = PredVarStr.replace('.', '').replace('->', '')\r
2011 if p.match(TmpStr):\r
2012 PredVarStr = PredVarStr[0:PredVarStr.find('(')]\r
2013 SearchInCache = True\r
2014 # Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable.\r
52302d4d 2015 if TmpStr.startswith(PredVarStr):\r
30fdf114 2016 IsFuncCall = True\r
52302d4d 2017\r
30fdf114
LG
2018 if PredVarStr.strip() in IgnoredKeywordList:\r
2019 continue\r
2020 StarList = []\r
2021 PredVarList = GetCNameList(PredVarStr, StarList)\r
2022 # No variable found, maybe value first? like (0 == VarName)\r
2023 if len(PredVarList) == 0:\r
2024 continue\r
52302d4d 2025\r
30fdf114
LG
2026 if SearchInCache:\r
2027 Type = FuncReturnTypeDict.get(PredVarStr)\r
2028 if Type != None:\r
2029 if Type.find('BOOLEAN') == -1:\r
2030 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
2031 continue\r
52302d4d 2032\r
30fdf114
LG
2033 if PredVarStr in FuncReturnTypeDict:\r
2034 continue\r
52302d4d 2035\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
2304 where Model = %d and StartLine = 1 and StartColumn = 0\r
2305 """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT)\r
2306 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2307 if len(ResultSet) == 0:\r
2308 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'No Comment appear at the very beginning of file.', 'File', FileID)\r
2309 return ErrorMsgList\r
52302d4d 2310\r
30fdf114
LG
2311 for Result in ResultSet:\r
2312 CommentStr = Result[0]\r
2313 if not CommentStr.startswith('/** @file'):\r
2314 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FILE_HEADER, 'File header comment should begin with ""/** @file""', FileTable, Result[1])\r
2315 if not CommentStr.endswith('**/'):\r
2316 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment should end with **/', FileTable, Result[1])\r
2317 if CommentStr.find('.') == -1:\r
2318 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMENT_DESCRIPTION, 'Comment description should end with period \'.\'', FileTable, Result[1])\r
2319\r
2320def CheckFuncHeaderDoxygenComments(FullFileName):\r
2321 ErrorMsgList = []\r
52302d4d 2322\r
30fdf114
LG
2323 FileID = GetTableID(FullFileName, ErrorMsgList)\r
2324 if FileID < 0:\r
2325 return ErrorMsgList\r
52302d4d 2326\r
30fdf114
LG
2327 Db = GetDB()\r
2328 FileTable = 'Identifier' + str(FileID)\r
2329 SqlStatement = """ select Value, StartLine, EndLine, ID\r
2330 from %s\r
2331 where Model = %d\r
2332 """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT)\r
52302d4d 2333\r
30fdf114
LG
2334 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2335 CommentSet = []\r
2336 try:\r
2337 for Result in ResultSet:\r
2338 CommentSet.append(Result)\r
2339 except:\r
2340 print 'Unrecognized chars in comment of file %s', FullFileName\r
52302d4d 2341\r
30fdf114
LG
2342 # Func Decl check\r
2343 SqlStatement = """ select Modifier, Name, StartLine, ID, Value\r
2344 from %s\r
2345 where Model = %d\r
2346 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
2347 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2348 for Result in ResultSet:\r
2349 FuncName = Result[4]\r
2350 FunctionHeaderComment = CheckCommentImmediatelyPrecedeFunctionHeader(Result[1], Result[2], CommentSet)\r
2351 if FunctionHeaderComment:\r
2352 CheckFunctionHeaderConsistentWithDoxygenComment(Result[0], Result[1], Result[2], FunctionHeaderComment[0], FunctionHeaderComment[1], ErrorMsgList, FunctionHeaderComment[3], FileTable)\r
2353 else:\r
2354 if EccGlobalData.gException.IsException(ERROR_HEADER_CHECK_FUNCTION, FuncName):\r
2355 continue\r
2356 ErrorMsgList.append('Line %d :Function %s has NO comment immediately preceding it.' % (Result[2], Result[1]))\r
2357 PrintErrorMsg(ERROR_HEADER_CHECK_FUNCTION, 'Function [%s] has NO comment immediately preceding it.' % (FuncName), FileTable, Result[3])\r
52302d4d 2358\r
30fdf114
LG
2359 # Func Def check\r
2360 SqlStatement = """ select Value, StartLine, EndLine, ID\r
2361 from %s\r
2362 where Model = %d\r
2363 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER)\r
52302d4d 2364\r
30fdf114
LG
2365 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2366 CommentSet = []\r
2367 try:\r
2368 for Result in ResultSet:\r
2369 CommentSet.append(Result)\r
2370 except:\r
2371 print 'Unrecognized chars in comment of file %s', FullFileName\r
52302d4d 2372\r
30fdf114
LG
2373 SqlStatement = """ select Modifier, Header, StartLine, ID, Name\r
2374 from Function\r
2375 where BelongsToFile = %d\r
2376 """ % (FileID)\r
2377 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2378 for Result in ResultSet:\r
2379 FuncName = Result[4]\r
2380 FunctionHeaderComment = CheckCommentImmediatelyPrecedeFunctionHeader(Result[1], Result[2], CommentSet)\r
2381 if FunctionHeaderComment:\r
2382 CheckFunctionHeaderConsistentWithDoxygenComment(Result[0], Result[1], Result[2], FunctionHeaderComment[0], FunctionHeaderComment[1], ErrorMsgList, FunctionHeaderComment[3], FileTable)\r
2383 else:\r
2384 if EccGlobalData.gException.IsException(ERROR_HEADER_CHECK_FUNCTION, FuncName):\r
2385 continue\r
2386 ErrorMsgList.append('Line %d :Function [%s] has NO comment immediately preceding it.' % (Result[2], Result[1]))\r
2387 PrintErrorMsg(ERROR_HEADER_CHECK_FUNCTION, 'Function [%s] has NO comment immediately preceding it.' % (FuncName), 'Function', Result[3])\r
2388 return ErrorMsgList\r
2389\r
2390def CheckCommentImmediatelyPrecedeFunctionHeader(FuncName, FuncStartLine, CommentSet):\r
2391\r
2392 for Comment in CommentSet:\r
2393 if Comment[2] == FuncStartLine - 1:\r
2394 return Comment\r
2395 return None\r
2396\r
2397def GetDoxygenStrFromComment(Str):\r
2398 DoxygenStrList = []\r
2399 ParamTagList = Str.split('@param')\r
2400 if len(ParamTagList) > 1:\r
2401 i = 1\r
2402 while i < len(ParamTagList):\r
2403 DoxygenStrList.append('@param' + ParamTagList[i])\r
2404 i += 1\r
52302d4d 2405\r
30fdf114 2406 Str = ParamTagList[0]\r
52302d4d 2407\r
30fdf114
LG
2408 RetvalTagList = ParamTagList[-1].split('@retval')\r
2409 if len(RetvalTagList) > 1:\r
2410 if len(ParamTagList) > 1:\r
2411 DoxygenStrList[-1] = '@param' + RetvalTagList[0]\r
2412 i = 1\r
2413 while i < len(RetvalTagList):\r
2414 DoxygenStrList.append('@retval' + RetvalTagList[i])\r
2415 i += 1\r
52302d4d 2416\r
30fdf114
LG
2417 ReturnTagList = RetvalTagList[-1].split('@return')\r
2418 if len(ReturnTagList) > 1:\r
2419 if len(RetvalTagList) > 1:\r
2420 DoxygenStrList[-1] = '@retval' + ReturnTagList[0]\r
2421 elif len(ParamTagList) > 1:\r
2422 DoxygenStrList[-1] = '@param' + ReturnTagList[0]\r
2423 i = 1\r
2424 while i < len(ReturnTagList):\r
2425 DoxygenStrList.append('@return' + ReturnTagList[i])\r
2426 i += 1\r
52302d4d 2427\r
30fdf114
LG
2428 if len(DoxygenStrList) > 0:\r
2429 DoxygenStrList[-1] = DoxygenStrList[-1].rstrip('--*/')\r
52302d4d 2430\r
30fdf114 2431 return DoxygenStrList\r
52302d4d 2432\r
30fdf114
LG
2433def CheckGeneralDoxygenCommentLayout(Str, StartLine, ErrorMsgList, CommentId = -1, TableName = ''):\r
2434 #/** --*/ @retval after @param\r
2435 if not Str.startswith('/**'):\r
2436 ErrorMsgList.append('Line %d : Comment does NOT have prefix /** ' % StartLine)\r
2437 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'Comment does NOT have prefix /** ', TableName, CommentId)\r
2438 if not Str.endswith('**/'):\r
2439 ErrorMsgList.append('Line %d : Comment does NOT have tail **/ ' % StartLine)\r
2440 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'Comment does NOT have tail **/ ', TableName, CommentId)\r
2441 FirstRetvalIndex = Str.find('@retval')\r
2442 LastParamIndex = Str.rfind('@param')\r
2443 if (FirstRetvalIndex > 0) and (LastParamIndex > 0) and (FirstRetvalIndex < LastParamIndex):\r
2444 ErrorMsgList.append('Line %d : @retval appear before @param ' % StartLine)\r
2445 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, @retval appear before @param ', TableName, CommentId)\r
52302d4d 2446\r
30fdf114 2447def CheckFunctionHeaderConsistentWithDoxygenComment(FuncModifier, FuncHeader, FuncStartLine, CommentStr, CommentStartLine, ErrorMsgList, CommentId = -1, TableName = ''):\r
52302d4d
LG
2448\r
2449 ParamList = GetParamList(FuncHeader)\r
30fdf114
LG
2450 CheckGeneralDoxygenCommentLayout(CommentStr, CommentStartLine, ErrorMsgList, CommentId, TableName)\r
2451 DescriptionStr = CommentStr\r
2452 DoxygenStrList = GetDoxygenStrFromComment(DescriptionStr)\r
2453 if DescriptionStr.find('.') == -1:\r
2454 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMENT_DESCRIPTION, 'Comment description should end with period \'.\'', TableName, CommentId)\r
2455 DoxygenTagNumber = len(DoxygenStrList)\r
2456 ParamNumber = len(ParamList)\r
2457 for Param in ParamList:\r
2458 if Param.Name.upper() == 'VOID' and ParamNumber == 1:\r
2459 ParamNumber -= 1\r
2460 Index = 0\r
2461 if ParamNumber > 0 and DoxygenTagNumber > 0:\r
2462 while Index < ParamNumber and Index < DoxygenTagNumber:\r
2463 ParamModifier = ParamList[Index].Modifier\r
2464 ParamName = ParamList[Index].Name.strip()\r
2465 Tag = DoxygenStrList[Index].strip(' ')\r
2466 if (not Tag[-1] == ('\n')) and (not Tag[-1] == ('\r')):\r
2467 ErrorMsgList.append('Line %d : in Comment, \"%s\" does NOT end with new line ' % (CommentStartLine, Tag.replace('\n', '').replace('\r', '')))\r
2468 PrintErrorMsg(ERROR_HEADER_CHECK_FUNCTION, 'in Comment, \"%s\" does NOT end with new line ' % (Tag.replace('\n', '').replace('\r', '')), TableName, CommentId)\r
2469 TagPartList = Tag.split()\r
2470 if len(TagPartList) < 2:\r
2471 ErrorMsgList.append('Line %d : in Comment, \"%s\" does NOT contain doxygen contents ' % (CommentStartLine, Tag.replace('\n', '').replace('\r', '')))\r
2472 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, \"%s\" does NOT contain doxygen contents ' % (Tag.replace('\n', '').replace('\r', '')), TableName, CommentId)\r
2473 Index += 1\r
2474 continue\r
2475 LBPos = Tag.find('[')\r
2476 RBPos = Tag.find(']')\r
2477 ParamToLBContent = Tag[len('@param'):LBPos].strip()\r
2478 if LBPos > 0 and len(ParamToLBContent)==0 and RBPos > LBPos:\r
2479 InOutStr = ''\r
2480 ModifierPartList = ParamModifier.split()\r
2481 for Part in ModifierPartList:\r
2482 if Part.strip() == 'IN':\r
2483 InOutStr += 'in'\r
2484 if Part.strip() == 'OUT':\r
52302d4d 2485 if InOutStr != '':\r
30fdf114
LG
2486 InOutStr += ', out'\r
2487 else:\r
2488 InOutStr = 'out'\r
52302d4d 2489\r
30fdf114
LG
2490 if InOutStr != '':\r
2491 if Tag.find('['+InOutStr+']') == -1:\r
52302d4d 2492 ErrorMsgList.append('Line %d : in Comment, \"%s\" does NOT have %s ' % (CommentStartLine, (TagPartList[0] + ' ' +TagPartList[1]).replace('\n', '').replace('\r', ''), '['+InOutStr+']'))\r
30fdf114
LG
2493 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
2494 if Tag.find(ParamName) == -1 and ParamName != 'VOID' and ParamName != 'void':\r
52302d4d 2495 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
30fdf114
LG
2496 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
2497 Index += 1\r
52302d4d 2498\r
30fdf114
LG
2499 if Index < ParamNumber:\r
2500 ErrorMsgList.append('Line %d : Number of doxygen tags in comment less than number of function parameters' % CommentStartLine)\r
2501 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'Number of doxygen tags in comment less than number of function parameters ', TableName, CommentId)\r
2502 # VOID return type, NOT VOID*. VOID* should be matched with a doxygen tag.\r
2503 if (FuncModifier.find('VOID') != -1 or FuncModifier.find('void') != -1) and FuncModifier.find('*') == -1:\r
52302d4d 2504\r
30fdf114
LG
2505 # assume we allow a return description tag for void func. return. that's why 'DoxygenTagNumber - 1' is used instead of 'DoxygenTagNumber'\r
2506 if Index < DoxygenTagNumber - 1 or (Index < DoxygenTagNumber and DoxygenStrList[Index].startswith('@retval')):\r
2507 ErrorMsgList.append('Line %d : VOID return type need NO doxygen tags in comment' % CommentStartLine)\r
2508 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'VOID return type need no doxygen tags in comment ', TableName, CommentId)\r
2509 else:\r
52302d4d 2510 if Index < DoxygenTagNumber and not DoxygenStrList[Index].startswith('@retval') and not DoxygenStrList[Index].startswith('@return'):\r
30fdf114
LG
2511 ErrorMsgList.append('Line %d : Number of @param doxygen tags in comment does NOT match number of function parameters' % CommentStartLine)\r
2512 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'Number of @param doxygen tags in comment does NOT match number of function parameters ', TableName, CommentId)\r
2513 else:\r
2514 if ParamNumber == 0 and DoxygenTagNumber != 0 and ((FuncModifier.find('VOID') != -1 or FuncModifier.find('void') != -1) and FuncModifier.find('*') == -1):\r
2515 ErrorMsgList.append('Line %d : VOID return type need NO doxygen tags in comment' % CommentStartLine)\r
2516 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'VOID return type need NO doxygen tags in comment ', TableName, CommentId)\r
2517 if ParamNumber != 0 and DoxygenTagNumber == 0:\r
2518 ErrorMsgList.append('Line %d : No doxygen tags in comment' % CommentStartLine)\r
2519 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'No doxygen tags in comment ', TableName, CommentId)\r
2520\r
2521if __name__ == '__main__':\r
2522\r
2523# EdkLogger.Initialize()\r
2524# EdkLogger.SetLevel(EdkLogger.QUIET)\r
52302d4d 2525# CollectSourceCodeDataIntoDB(sys.argv[1])\r
30fdf114
LG
2526 MsgList = CheckFuncHeaderDoxygenComments('C:\\Combo\\R9\\LakeportX64Dev\\FlashDevicePkg\\Library\\SpiFlashChipM25P64\\SpiFlashChipM25P64.c')\r
2527 for Msg in MsgList:\r
2528 print Msg\r
2529 print 'Done!'\r