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