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