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