]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Ecc/c.py
edk2: Change BaseTools owner in Maintainers.txt
[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
8c3f9b4e 4# Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>\r
40d841f6 5# This program and the accompanying materials\r
52302d4d
LG
6# are licensed and made available under the terms and conditions of the BSD License\r
7# which accompanies this distribution. The full text of the license may be found at\r
8# http://opensource.org/licenses/bsd-license.php\r
9#\r
10# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12#\r
13\r
30fdf114 14import sys\r
1be2ed90 15import Common.LongFilePathOs as os\r
30fdf114
LG
16import re\r
17import string\r
18import CodeFragmentCollector\r
19import FileProfile\r
20from CommonDataClass import DataClass\r
21import Database\r
22from Common import EdkLogger\r
23from EccToolError import *\r
24import EccGlobalData\r
25import MetaDataParser\r
26\r
27IncludeFileListDict = {}\r
28AllIncludeFileListDict = {}\r
29IncludePathListDict = {}\r
30ComplexTypeDict = {}\r
31SUDict = {}\r
32IgnoredKeywordList = ['EFI_ERROR']\r
33\r
34def GetIgnoredDirListPattern():\r
35 skipList = list(EccGlobalData.gConfig.SkipDirList) + ['.svn']\r
36 DirString = string.join(skipList, '|')\r
37 p = re.compile(r'.*[\\/](?:%s)[\\/]?.*' % DirString)\r
38 return p\r
39\r
40def GetFuncDeclPattern():\r
41 p = re.compile(r'(?:EFIAPI|EFI_BOOT_SERVICE|EFI_RUNTIME_SERVICE)?\s*[_\w]+\s*\(.*\)$', re.DOTALL)\r
42 return p\r
43\r
44def GetArrayPattern():\r
45 p = re.compile(r'[_\w]*\s*[\[.*\]]+')\r
46 return p\r
47\r
48def GetTypedefFuncPointerPattern():\r
49 p = re.compile('[_\w\s]*\([\w\s]*\*+\s*[_\w]+\s*\)\s*\(.*\)', re.DOTALL)\r
50 return p\r
51\r
52def GetDB():\r
53 return EccGlobalData.gDb\r
54\r
55def GetConfig():\r
56 return EccGlobalData.gConfig\r
57\r
58def PrintErrorMsg(ErrorType, Msg, TableName, ItemId):\r
59 Msg = Msg.replace('\n', '').replace('\r', '')\r
60 MsgPartList = Msg.split()\r
61 Msg = ''\r
62 for Part in MsgPartList:\r
63 Msg += Part\r
64 Msg += ' '\r
79b74a03 65 GetDB().TblReport.Insert(ErrorType, OtherMsg=Msg, BelongsToTable=TableName, BelongsToItem=ItemId)\r
30fdf114
LG
66\r
67def GetIdType(Str):\r
68 Type = DataClass.MODEL_UNKNOWN\r
69 Str = Str.replace('#', '# ')\r
70 List = Str.split()\r
71 if List[1] == 'include':\r
72 Type = DataClass.MODEL_IDENTIFIER_INCLUDE\r
73 elif List[1] == 'define':\r
74 Type = DataClass.MODEL_IDENTIFIER_MACRO_DEFINE\r
75 elif List[1] == 'ifdef':\r
76 Type = DataClass.MODEL_IDENTIFIER_MACRO_IFDEF\r
77 elif List[1] == 'ifndef':\r
78 Type = DataClass.MODEL_IDENTIFIER_MACRO_IFNDEF\r
79 elif List[1] == 'endif':\r
80 Type = DataClass.MODEL_IDENTIFIER_MACRO_ENDIF\r
81 elif List[1] == 'pragma':\r
82 Type = DataClass.MODEL_IDENTIFIER_MACRO_PROGMA\r
83 else:\r
84 Type = DataClass.MODEL_UNKNOWN\r
85 return Type\r
86\r
87def SuOccurInTypedef (Su, TdList):\r
88 for Td in TdList:\r
89 if Su.StartPos[0] == Td.StartPos[0] and Su.EndPos[0] == Td.EndPos[0]:\r
90 return True\r
91 return False\r
92\r
93def GetIdentifierList():\r
94 IdList = []\r
95 for comment in FileProfile.CommentList:\r
79b74a03 96 IdComment = DataClass.IdentifierClass(-1, '', '', '', comment.Content, DataClass.MODEL_IDENTIFIER_COMMENT, -1, -1, comment.StartPos[0], comment.StartPos[1], comment.EndPos[0], comment.EndPos[1])\r
30fdf114 97 IdList.append(IdComment)\r
52302d4d 98\r
30fdf114
LG
99 for pp in FileProfile.PPDirectiveList:\r
100 Type = GetIdType(pp.Content)\r
79b74a03 101 IdPP = DataClass.IdentifierClass(-1, '', '', '', pp.Content, Type, -1, -1, pp.StartPos[0], pp.StartPos[1], pp.EndPos[0], pp.EndPos[1])\r
30fdf114 102 IdList.append(IdPP)\r
52302d4d 103\r
30fdf114 104 for pe in FileProfile.PredicateExpressionList:\r
79b74a03 105 IdPE = DataClass.IdentifierClass(-1, '', '', '', pe.Content, DataClass.MODEL_IDENTIFIER_PREDICATE_EXPRESSION, -1, -1, pe.StartPos[0], pe.StartPos[1], pe.EndPos[0], pe.EndPos[1])\r
30fdf114 106 IdList.append(IdPE)\r
52302d4d 107\r
30fdf114
LG
108 FuncDeclPattern = GetFuncDeclPattern()\r
109 ArrayPattern = GetArrayPattern()\r
110 for var in FileProfile.VariableDeclarationList:\r
111 DeclText = var.Declarator.lstrip()\r
112 FuncPointerPattern = GetTypedefFuncPointerPattern()\r
113 if FuncPointerPattern.match(DeclText):\r
114 continue\r
115 VarNameStartLine = var.NameStartPos[0]\r
116 VarNameStartColumn = var.NameStartPos[1]\r
117 FirstChar = DeclText[0]\r
118 while not FirstChar.isalpha() and FirstChar != '_':\r
119 if FirstChar == '*':\r
120 var.Modifier += '*'\r
121 VarNameStartColumn += 1\r
122 DeclText = DeclText.lstrip('*')\r
123 elif FirstChar == '\r':\r
124 DeclText = DeclText.lstrip('\r\n').lstrip('\r')\r
125 VarNameStartLine += 1\r
126 VarNameStartColumn = 0\r
127 elif FirstChar == '\n':\r
128 DeclText = DeclText.lstrip('\n')\r
129 VarNameStartLine += 1\r
130 VarNameStartColumn = 0\r
131 elif FirstChar == ' ':\r
132 DeclText = DeclText.lstrip(' ')\r
133 VarNameStartColumn += 1\r
134 elif FirstChar == '\t':\r
135 DeclText = DeclText.lstrip('\t')\r
136 VarNameStartColumn += 8\r
137 else:\r
138 DeclText = DeclText[1:]\r
139 VarNameStartColumn += 1\r
140 FirstChar = DeclText[0]\r
52302d4d 141\r
30fdf114
LG
142 var.Declarator = DeclText\r
143 if FuncDeclPattern.match(var.Declarator):\r
52302d4d 144 DeclSplitList = var.Declarator.split('(')\r
30fdf114
LG
145 FuncName = DeclSplitList[0].strip()\r
146 FuncNamePartList = FuncName.split()\r
147 if len(FuncNamePartList) > 1:\r
148 FuncName = FuncNamePartList[-1].strip()\r
149 NameStart = DeclSplitList[0].rfind(FuncName)\r
150 var.Declarator = var.Declarator[NameStart:]\r
151 if NameStart > 0:\r
152 var.Modifier += ' ' + DeclSplitList[0][0:NameStart]\r
153 Index = 0\r
154 PreChar = ''\r
155 while Index < NameStart:\r
156 FirstChar = DeclSplitList[0][Index]\r
157 if DeclSplitList[0][Index:].startswith('EFIAPI'):\r
158 Index += 6\r
159 VarNameStartColumn += 6\r
160 PreChar = ''\r
161 continue\r
162 elif FirstChar == '\r':\r
163 Index += 1\r
164 VarNameStartLine += 1\r
165 VarNameStartColumn = 0\r
166 elif FirstChar == '\n':\r
167 Index += 1\r
168 if PreChar != '\r':\r
169 VarNameStartLine += 1\r
170 VarNameStartColumn = 0\r
171 elif FirstChar == ' ':\r
172 Index += 1\r
173 VarNameStartColumn += 1\r
174 elif FirstChar == '\t':\r
175 Index += 1\r
176 VarNameStartColumn += 8\r
177 else:\r
178 Index += 1\r
179 VarNameStartColumn += 1\r
180 PreChar = FirstChar\r
181 IdVar = DataClass.IdentifierClass(-1, var.Modifier, '', var.Declarator, FuncName, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION, -1, -1, var.StartPos[0], var.StartPos[1], VarNameStartLine, VarNameStartColumn)\r
182 IdList.append(IdVar)\r
183 continue\r
52302d4d
LG
184\r
185 if var.Declarator.find('{') == -1:\r
30fdf114
LG
186 for decl in var.Declarator.split(','):\r
187 DeclList = decl.split('=')\r
188 Name = DeclList[0].strip()\r
189 if ArrayPattern.match(Name):\r
190 LSBPos = var.Declarator.find('[')\r
191 var.Modifier += ' ' + Name[LSBPos:]\r
192 Name = Name[0:LSBPos]\r
52302d4d 193\r
79b74a03 194 IdVar = DataClass.IdentifierClass(-1, var.Modifier, '', Name, (len(DeclList) > 1 and [DeclList[1]]or [''])[0], DataClass.MODEL_IDENTIFIER_VARIABLE, -1, -1, var.StartPos[0], var.StartPos[1], VarNameStartLine, VarNameStartColumn)\r
30fdf114
LG
195 IdList.append(IdVar)\r
196 else:\r
197 DeclList = var.Declarator.split('=')\r
198 Name = DeclList[0].strip()\r
199 if ArrayPattern.match(Name):\r
200 LSBPos = var.Declarator.find('[')\r
201 var.Modifier += ' ' + Name[LSBPos:]\r
202 Name = Name[0:LSBPos]\r
79b74a03 203 IdVar = DataClass.IdentifierClass(-1, var.Modifier, '', Name, (len(DeclList) > 1 and [DeclList[1]]or [''])[0], DataClass.MODEL_IDENTIFIER_VARIABLE, -1, -1, var.StartPos[0], var.StartPos[1], VarNameStartLine, VarNameStartColumn)\r
30fdf114 204 IdList.append(IdVar)\r
52302d4d 205\r
30fdf114
LG
206 for enum in FileProfile.EnumerationDefinitionList:\r
207 LBPos = enum.Content.find('{')\r
208 RBPos = enum.Content.find('}')\r
209 Name = enum.Content[4:LBPos].strip()\r
79b74a03
LG
210 Value = enum.Content[LBPos + 1:RBPos]\r
211 IdEnum = DataClass.IdentifierClass(-1, '', '', Name, Value, DataClass.MODEL_IDENTIFIER_ENUMERATE, -1, -1, enum.StartPos[0], enum.StartPos[1], enum.EndPos[0], enum.EndPos[1])\r
30fdf114 212 IdList.append(IdEnum)\r
52302d4d 213\r
30fdf114
LG
214 for su in FileProfile.StructUnionDefinitionList:\r
215 if SuOccurInTypedef(su, FileProfile.TypedefDefinitionList):\r
216 continue\r
217 Type = DataClass.MODEL_IDENTIFIER_STRUCTURE\r
218 SkipLen = 6\r
219 if su.Content.startswith('union'):\r
220 Type = DataClass.MODEL_IDENTIFIER_UNION\r
221 SkipLen = 5\r
222 LBPos = su.Content.find('{')\r
223 RBPos = su.Content.find('}')\r
224 if LBPos == -1 or RBPos == -1:\r
225 Name = su.Content[SkipLen:].strip()\r
226 Value = ''\r
227 else:\r
228 Name = su.Content[SkipLen:LBPos].strip()\r
79b74a03
LG
229 Value = su.Content[LBPos:RBPos + 1]\r
230 IdPE = DataClass.IdentifierClass(-1, '', '', Name, Value, Type, -1, -1, su.StartPos[0], su.StartPos[1], su.EndPos[0], su.EndPos[1])\r
30fdf114 231 IdList.append(IdPE)\r
52302d4d
LG
232\r
233 TdFuncPointerPattern = GetTypedefFuncPointerPattern()\r
30fdf114
LG
234 for td in FileProfile.TypedefDefinitionList:\r
235 Modifier = ''\r
236 Name = td.ToType\r
237 Value = td.FromType\r
238 if TdFuncPointerPattern.match(td.ToType):\r
239 Modifier = td.FromType\r
240 LBPos = td.ToType.find('(')\r
79b74a03 241 TmpStr = td.ToType[LBPos + 1:].strip()\r
30fdf114
LG
242 StarPos = TmpStr.find('*')\r
243 if StarPos != -1:\r
244 Modifier += ' ' + TmpStr[0:StarPos]\r
245 while TmpStr[StarPos] == '*':\r
246# Modifier += ' ' + '*'\r
247 StarPos += 1\r
248 TmpStr = TmpStr[StarPos:].strip()\r
249 RBPos = TmpStr.find(')')\r
250 Name = TmpStr[0:RBPos]\r
251 Value = 'FP' + TmpStr[RBPos + 1:]\r
252 else:\r
253 while Name.startswith('*'):\r
254 Value += ' ' + '*'\r
255 Name = Name.lstrip('*').strip()\r
52302d4d 256\r
30fdf114
LG
257 if Name.find('[') != -1:\r
258 LBPos = Name.find('[')\r
259 RBPos = Name.rfind(']')\r
260 Value += Name[LBPos : RBPos + 1]\r
261 Name = Name[0 : LBPos]\r
52302d4d 262\r
79b74a03 263 IdTd = DataClass.IdentifierClass(-1, Modifier, '', Name, Value, DataClass.MODEL_IDENTIFIER_TYPEDEF, -1, -1, td.StartPos[0], td.StartPos[1], td.EndPos[0], td.EndPos[1])\r
30fdf114 264 IdList.append(IdTd)\r
52302d4d 265\r
30fdf114 266 for funcCall in FileProfile.FunctionCallingList:\r
79b74a03 267 IdFC = DataClass.IdentifierClass(-1, '', '', funcCall.FuncName, funcCall.ParamList, DataClass.MODEL_IDENTIFIER_FUNCTION_CALLING, -1, -1, funcCall.StartPos[0], funcCall.StartPos[1], funcCall.EndPos[0], funcCall.EndPos[1])\r
30fdf114
LG
268 IdList.append(IdFC)\r
269 return IdList\r
270\r
271def StripNonAlnumChars(Str):\r
272 StrippedStr = ''\r
273 for Char in Str:\r
274 if Char.isalnum():\r
275 StrippedStr += Char\r
276 return StrippedStr\r
277\r
79b74a03 278def GetParamList(FuncDeclarator, FuncNameLine=0, FuncNameOffset=0):\r
30fdf114
LG
279 FuncDeclarator = StripComments(FuncDeclarator)\r
280 ParamIdList = []\r
281 #DeclSplitList = FuncDeclarator.split('(')\r
282 LBPos = FuncDeclarator.find('(')\r
283 #if len(DeclSplitList) < 2:\r
284 if LBPos == -1:\r
285 return ParamIdList\r
286 #FuncName = DeclSplitList[0]\r
287 FuncName = FuncDeclarator[0:LBPos]\r
288 #ParamStr = DeclSplitList[1].rstrip(')')\r
289 ParamStr = FuncDeclarator[LBPos + 1:].rstrip(')')\r
290 LineSkipped = 0\r
291 OffsetSkipped = 0\r
292 TailChar = FuncName[-1]\r
293 while not TailChar.isalpha() and TailChar != '_':\r
52302d4d 294\r
30fdf114
LG
295 if TailChar == '\n':\r
296 FuncName = FuncName.rstrip('\r\n').rstrip('\n')\r
297 LineSkipped += 1\r
298 OffsetSkipped = 0\r
299 elif TailChar == '\r':\r
300 FuncName = FuncName.rstrip('\r')\r
301 LineSkipped += 1\r
302 OffsetSkipped = 0\r
303 elif TailChar == ' ':\r
304 FuncName = FuncName.rstrip(' ')\r
305 OffsetSkipped += 1\r
306 elif TailChar == '\t':\r
307 FuncName = FuncName.rstrip('\t')\r
308 OffsetSkipped += 8\r
309 else:\r
310 FuncName = FuncName[:-1]\r
311 TailChar = FuncName[-1]\r
52302d4d 312\r
30fdf114 313 OffsetSkipped += 1 #skip '('\r
52302d4d 314\r
30fdf114
LG
315 for p in ParamStr.split(','):\r
316 ListP = p.split()\r
317 if len(ListP) == 0:\r
318 continue\r
319 ParamName = ListP[-1]\r
320 DeclText = ParamName.strip()\r
321 RightSpacePos = p.rfind(ParamName)\r
322 ParamModifier = p[0:RightSpacePos]\r
323 if ParamName == 'OPTIONAL':\r
324 if ParamModifier == '':\r
325 ParamModifier += ' ' + 'OPTIONAL'\r
326 DeclText = ''\r
327 else:\r
328 ParamName = ListP[-2]\r
329 DeclText = ParamName.strip()\r
330 RightSpacePos = p.rfind(ParamName)\r
331 ParamModifier = p[0:RightSpacePos]\r
332 ParamModifier += 'OPTIONAL'\r
333 while DeclText.startswith('*'):\r
334 ParamModifier += ' ' + '*'\r
335 DeclText = DeclText.lstrip('*').strip()\r
336 ParamName = DeclText\r
337 # ignore array length if exists.\r
338 LBIndex = ParamName.find('[')\r
339 if LBIndex != -1:\r
340 ParamName = ParamName[0:LBIndex]\r
52302d4d 341\r
30fdf114
LG
342 Start = RightSpacePos\r
343 Index = 0\r
344 PreChar = ''\r
345 while Index < Start:\r
346 FirstChar = p[Index]\r
52302d4d 347\r
30fdf114
LG
348 if FirstChar == '\r':\r
349 Index += 1\r
350 LineSkipped += 1\r
351 OffsetSkipped = 0\r
352 elif FirstChar == '\n':\r
353 Index += 1\r
354 if PreChar != '\r':\r
355 LineSkipped += 1\r
356 OffsetSkipped = 0\r
357 elif FirstChar == ' ':\r
358 Index += 1\r
359 OffsetSkipped += 1\r
360 elif FirstChar == '\t':\r
361 Index += 1\r
362 OffsetSkipped += 8\r
363 else:\r
364 Index += 1\r
365 OffsetSkipped += 1\r
366 PreChar = FirstChar\r
52302d4d 367\r
30fdf114
LG
368 ParamBeginLine = FuncNameLine + LineSkipped\r
369 ParamBeginOffset = FuncNameOffset + OffsetSkipped\r
52302d4d 370\r
30fdf114
LG
371 Index = Start + len(ParamName)\r
372 PreChar = ''\r
373 while Index < len(p):\r
374 FirstChar = p[Index]\r
52302d4d 375\r
30fdf114
LG
376 if FirstChar == '\r':\r
377 Index += 1\r
378 LineSkipped += 1\r
379 OffsetSkipped = 0\r
380 elif FirstChar == '\n':\r
381 Index += 1\r
382 if PreChar != '\r':\r
383 LineSkipped += 1\r
384 OffsetSkipped = 0\r
385 elif FirstChar == ' ':\r
386 Index += 1\r
387 OffsetSkipped += 1\r
388 elif FirstChar == '\t':\r
389 Index += 1\r
390 OffsetSkipped += 8\r
391 else:\r
392 Index += 1\r
393 OffsetSkipped += 1\r
394 PreChar = FirstChar\r
52302d4d 395\r
30fdf114
LG
396 ParamEndLine = FuncNameLine + LineSkipped\r
397 ParamEndOffset = FuncNameOffset + OffsetSkipped\r
398 if ParamName != '...':\r
399 ParamName = StripNonAlnumChars(ParamName)\r
400 IdParam = DataClass.IdentifierClass(-1, ParamModifier, '', ParamName, '', DataClass.MODEL_IDENTIFIER_PARAMETER, -1, -1, ParamBeginLine, ParamBeginOffset, ParamEndLine, ParamEndOffset)\r
401 ParamIdList.append(IdParam)\r
52302d4d 402\r
30fdf114 403 OffsetSkipped += 1 #skip ','\r
52302d4d 404\r
30fdf114 405 return ParamIdList\r
52302d4d 406\r
30fdf114
LG
407def GetFunctionList():\r
408 FuncObjList = []\r
409 for FuncDef in FileProfile.FunctionDefinitionList:\r
410 ParamIdList = []\r
411 DeclText = FuncDef.Declarator.lstrip()\r
412 FuncNameStartLine = FuncDef.NamePos[0]\r
413 FuncNameStartColumn = FuncDef.NamePos[1]\r
414 FirstChar = DeclText[0]\r
415 while not FirstChar.isalpha() and FirstChar != '_':\r
416 if FirstChar == '*':\r
417 FuncDef.Modifier += '*'\r
418 FuncNameStartColumn += 1\r
419 DeclText = DeclText.lstrip('*')\r
420 elif FirstChar == '\r':\r
421 DeclText = DeclText.lstrip('\r\n').lstrip('\r')\r
422 FuncNameStartLine += 1\r
423 FuncNameStartColumn = 0\r
424 elif FirstChar == '\n':\r
425 DeclText = DeclText.lstrip('\n')\r
426 FuncNameStartLine += 1\r
427 FuncNameStartColumn = 0\r
428 elif FirstChar == ' ':\r
429 DeclText = DeclText.lstrip(' ')\r
430 FuncNameStartColumn += 1\r
431 elif FirstChar == '\t':\r
432 DeclText = DeclText.lstrip('\t')\r
433 FuncNameStartColumn += 8\r
434 else:\r
435 DeclText = DeclText[1:]\r
436 FuncNameStartColumn += 1\r
437 FirstChar = DeclText[0]\r
52302d4d 438\r
30fdf114
LG
439 FuncDef.Declarator = DeclText\r
440 DeclSplitList = FuncDef.Declarator.split('(')\r
441 if len(DeclSplitList) < 2:\r
442 continue\r
52302d4d 443\r
30fdf114
LG
444 FuncName = DeclSplitList[0]\r
445 FuncNamePartList = FuncName.split()\r
446 if len(FuncNamePartList) > 1:\r
447 FuncName = FuncNamePartList[-1]\r
448 NameStart = DeclSplitList[0].rfind(FuncName)\r
449 if NameStart > 0:\r
450 FuncDef.Modifier += ' ' + DeclSplitList[0][0:NameStart]\r
451 Index = 0\r
452 PreChar = ''\r
453 while Index < NameStart:\r
454 FirstChar = DeclSplitList[0][Index]\r
455 if DeclSplitList[0][Index:].startswith('EFIAPI'):\r
456 Index += 6\r
457 FuncNameStartColumn += 6\r
458 PreChar = ''\r
459 continue\r
460 elif FirstChar == '\r':\r
461 Index += 1\r
462 FuncNameStartLine += 1\r
463 FuncNameStartColumn = 0\r
464 elif FirstChar == '\n':\r
465 Index += 1\r
466 if PreChar != '\r':\r
467 FuncNameStartLine += 1\r
468 FuncNameStartColumn = 0\r
469 elif FirstChar == ' ':\r
470 Index += 1\r
471 FuncNameStartColumn += 1\r
472 elif FirstChar == '\t':\r
473 Index += 1\r
474 FuncNameStartColumn += 8\r
475 else:\r
476 Index += 1\r
477 FuncNameStartColumn += 1\r
478 PreChar = FirstChar\r
52302d4d 479\r
79b74a03 480 FuncObj = DataClass.FunctionClass(-1, FuncDef.Declarator, FuncDef.Modifier, FuncName.strip(), '', FuncDef.StartPos[0], FuncDef.StartPos[1], FuncDef.EndPos[0], FuncDef.EndPos[1], FuncDef.LeftBracePos[0], FuncDef.LeftBracePos[1], -1, ParamIdList, [], FuncNameStartLine, FuncNameStartColumn)\r
30fdf114 481 FuncObjList.append(FuncObj)\r
52302d4d 482\r
30fdf114
LG
483 return FuncObjList\r
484\r
485def GetFileModificationTimeFromDB(FullFileName):\r
486 TimeValue = 0.0\r
487 Db = GetDB()\r
488 SqlStatement = """ select TimeStamp\r
489 from File\r
490 where FullPath = \'%s\'\r
491 """ % (FullFileName)\r
492 ResultSet = Db.TblFile.Exec(SqlStatement)\r
493 for Result in ResultSet:\r
494 TimeValue = Result[0]\r
495 return TimeValue\r
496\r
497def CollectSourceCodeDataIntoDB(RootDir):\r
498 FileObjList = []\r
499 tuple = os.walk(RootDir)\r
500 IgnoredPattern = GetIgnoredDirListPattern()\r
501 ParseErrorFileList = []\r
502\r
503 for dirpath, dirnames, filenames in tuple:\r
504 if IgnoredPattern.match(dirpath.upper()):\r
505 continue\r
506\r
507 for Dir in dirnames:\r
508 Dirname = os.path.join(dirpath, Dir)\r
509 if os.path.islink(Dirname):\r
510 Dirname = os.path.realpath(Dirname)\r
511 if os.path.isdir(Dirname):\r
512 # symlinks to directories are treated as directories\r
513 dirnames.remove(Dir)\r
514 dirnames.append(Dirname)\r
515\r
516 for f in filenames:\r
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
30fdf114
LG
553 if ErrorMsgList == None:\r
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
LG
577 IFList = IncludeFileListDict.get(FullFileName)\r
578 if IFList != None:\r
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
604 if AllIncludeFileListDict.get(FullFileName) != None:\r
605 return AllIncludeFileListDict.get(FullFileName)\r
52302d4d 606\r
30fdf114
LG
607 FileDirName = os.path.dirname(FullFileName)\r
608 IncludePathList = IncludePathListDict.get(FileDirName)\r
609 if IncludePathList == None:\r
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
621 if FullPath != None:\r
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
632 if FullPath != None and FullPath not in IncludeFileQueue:\r
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
LG
855 Dict = ComplexTypeDict.get(FullFileName)\r
856 if Dict != None:\r
857 return Dict\r
52302d4d 858\r
30fdf114
LG
859 FileID = GetTableID(FullFileName)\r
860 FileTable = 'Identifier' + str(FileID)\r
861 Db = GetDB()\r
862 SqlStatement = """ select Modifier, Name, Value, ID\r
863 from %s\r
864 where Model = %d\r
865 """ % (FileTable, DataClass.MODEL_IDENTIFIER_TYPEDEF)\r
866 ResultSet = Db.TblFile.Exec(SqlStatement)\r
52302d4d 867\r
30fdf114
LG
868 Dict = {}\r
869 for Result in ResultSet:\r
870 if len(Result[0]) == 0:\r
871 Dict[Result[1]] = Result[2]\r
52302d4d 872\r
30fdf114
LG
873 IncludeFileList = GetAllIncludeFiles(FullFileName)\r
874 for F in IncludeFileList:\r
875 FileID = GetTableID(F)\r
876 if FileID < 0:\r
877 continue\r
52302d4d 878\r
30fdf114
LG
879 FileTable = 'Identifier' + str(FileID)\r
880 SqlStatement = """ select Modifier, Name, Value, ID\r
881 from %s\r
882 where Model = %d\r
883 """ % (FileTable, DataClass.MODEL_IDENTIFIER_TYPEDEF)\r
884 ResultSet = Db.TblFile.Exec(SqlStatement)\r
52302d4d 885\r
30fdf114
LG
886 for Result in ResultSet:\r
887 if not Result[2].startswith('FP ('):\r
888 Dict[Result[1]] = Result[2]\r
889 else:\r
890 if len(Result[0]) == 0:\r
891 Dict[Result[1]] = 'VOID'\r
892 else:\r
893 Dict[Result[1]] = GetDataTypeFromModifier(Result[0])\r
52302d4d 894\r
30fdf114
LG
895 ComplexTypeDict[FullFileName] = Dict\r
896 return Dict\r
897\r
898def GetSUDict(FullFileName):\r
52302d4d 899\r
30fdf114
LG
900 Dict = SUDict.get(FullFileName)\r
901 if Dict != None:\r
902 return Dict\r
52302d4d 903\r
30fdf114
LG
904 FileID = GetTableID(FullFileName)\r
905 FileTable = 'Identifier' + str(FileID)\r
906 Db = GetDB()\r
907 SqlStatement = """ select Name, Value, ID\r
908 from %s\r
909 where Model = %d or Model = %d\r
910 """ % (FileTable, DataClass.MODEL_IDENTIFIER_STRUCTURE, DataClass.MODEL_IDENTIFIER_UNION)\r
911 ResultSet = Db.TblFile.Exec(SqlStatement)\r
52302d4d 912\r
30fdf114
LG
913 Dict = {}\r
914 for Result in ResultSet:\r
915 if len(Result[1]) > 0:\r
916 Dict[Result[0]] = Result[1]\r
52302d4d 917\r
30fdf114
LG
918 IncludeFileList = GetAllIncludeFiles(FullFileName)\r
919 for F in IncludeFileList:\r
920 FileID = GetTableID(F)\r
921 if FileID < 0:\r
922 continue\r
52302d4d 923\r
30fdf114
LG
924 FileTable = 'Identifier' + str(FileID)\r
925 SqlStatement = """ select Name, Value, ID\r
926 from %s\r
927 where Model = %d or Model = %d\r
928 """ % (FileTable, DataClass.MODEL_IDENTIFIER_STRUCTURE, DataClass.MODEL_IDENTIFIER_UNION)\r
929 ResultSet = Db.TblFile.Exec(SqlStatement)\r
52302d4d 930\r
30fdf114
LG
931 for Result in ResultSet:\r
932 if len(Result[1]) > 0:\r
933 Dict[Result[0]] = Result[1]\r
52302d4d 934\r
30fdf114
LG
935 SUDict[FullFileName] = Dict\r
936 return Dict\r
937\r
938def StripComments(Str):\r
939 Str += ' '\r
940 ListFromStr = list(Str)\r
52302d4d 941\r
30fdf114
LG
942 InComment = False\r
943 DoubleSlashComment = False\r
944 Index = 0\r
945 while Index < len(ListFromStr):\r
946 # meet new line, then no longer in a comment for //\r
947 if ListFromStr[Index] == '\n':\r
948 if InComment and DoubleSlashComment:\r
949 InComment = False\r
950 DoubleSlashComment = False\r
951 Index += 1\r
952 # check for */ comment end\r
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
986 if Value == None:\r
987 Value = SUDict.get(Type)\r
988 if Value == None:\r
989 return None\r
52302d4d 990\r
30fdf114
LG
991 LBPos = Value.find('{')\r
992 while LBPos == -1:\r
993 FTList = Value.split()\r
994 for FT in FTList:\r
995 if FT not in ('struct', 'union'):\r
996 Value = TypedefDict.get(FT)\r
997 if Value == None:\r
998 Value = SUDict.get(FT)\r
999 break\r
52302d4d 1000\r
30fdf114
LG
1001 if Value == None:\r
1002 return None\r
52302d4d 1003\r
30fdf114 1004 LBPos = Value.find('{')\r
52302d4d 1005\r
30fdf114
LG
1006# RBPos = Value.find('}')\r
1007 Fields = Value[LBPos + 1:]\r
1008 Fields = StripComments(Fields)\r
1009 FieldsList = Fields.split(';')\r
1010 for Field in FieldsList:\r
1011 Field = Field.strip()\r
1012 Index = Field.rfind(FieldName)\r
1013 if Index < 1:\r
1014 continue\r
1015 if not Field[Index - 1].isalnum():\r
1016 if Index + len(FieldName) == len(Field):\r
1017 Type = GetDataTypeFromModifier(Field[0:Index])\r
1018 return Type.strip()\r
1019 else:\r
52302d4d 1020 # For the condition that the field in struct is an array with [] sufixes...\r
30fdf114
LG
1021 if not Field[Index + len(FieldName)].isalnum():\r
1022 Type = GetDataTypeFromModifier(Field[0:Index])\r
1023 return Type.strip()\r
52302d4d 1024\r
30fdf114 1025 return None\r
52302d4d 1026\r
79b74a03 1027def GetRealType(Type, TypedefDict, TargetType=None):\r
30fdf114
LG
1028 if TargetType != None and Type == TargetType:\r
1029 return Type\r
1030 while TypedefDict.get(Type):\r
1031 Type = TypedefDict.get(Type)\r
1032 if TargetType != None and Type == TargetType:\r
1033 return Type\r
1034 return Type\r
1035\r
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
1046 if FromType == None:\r
1047 return None\r
1048 # we want to determine the exact type.\r
1049 if TargetType != None:\r
1050 Type = FromType.split()[0]\r
1051 # we only want to check if it is a pointer\r
1052 else:\r
1053 Type = FromType\r
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
1154 if len(TypeList) > 1 and StarList != None:\r
1155 for Star in StarList:\r
1156 Type = Type.strip()\r
1157 Type = Type.rstrip(Star)\r
1158 # Get real type after de-reference pointers.\r
1159 if len(Type.strip()) == 0:\r
1160 Type = TypeList[-2]\r
1161 TypedefDict = GetTypedefDict(FullFileName)\r
1162 Type = GetRealType(Type, TypedefDict, TargetType)\r
1163 return Type\r
52302d4d 1164\r
30fdf114
LG
1165 # search function parameters second\r
1166 ParamList = GetParamList(FuncRecord[2])\r
1167 for Param in ParamList:\r
1168 if Param.Name.strip() == PredVar:\r
1169 if len(PredVarList) > 1:\r
1170 Type = GetTypeInfo(PredVarList[1:], Param.Modifier, FullFileName, TargetType)\r
1171 return Type\r
1172 else:\r
1173 TypeList = GetDataTypeFromModifier(Param.Modifier).split()\r
1174 Type = TypeList[-1]\r
83461d2c
HC
1175 if Type == '*' and len(TypeList) >= 2:\r
1176 Type = TypeList[-2]\r
30fdf114
LG
1177 if len(TypeList) > 1 and StarList != None:\r
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
1202 if len(TypeList) > 1 and StarList != None:\r
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
1233 if len(TypeList) > 1 and StarList != None:\r
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
1274 Index = Result[0].find(TypeStart)\r
1275 if Index != 0 or Result[3] != 0:\r
1276 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '[%s] Return Type should appear at the start of line' % FuncName, FileTable, Result[1])\r
52302d4d 1277\r
30fdf114
LG
1278 if Result[2] == Result[4]:\r
1279 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '[%s] Return Type should appear on its own line' % FuncName, FileTable, Result[1])\r
52302d4d 1280\r
30fdf114
LG
1281 SqlStatement = """ select Modifier, ID, StartLine, StartColumn, FunNameStartLine, Name\r
1282 from Function\r
1283 where BelongsToFile = %d\r
1284 """ % (FileID)\r
1285 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1286 for Result in ResultSet:\r
1287 ReturnType = GetDataTypeFromModifier(Result[0])\r
1288 TypeStart = ReturnType.split()[0]\r
1289 FuncName = Result[5]\r
1290 if EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, FuncName):\r
1291 continue\r
72358997
HC
1292 Result0 = Result[0]\r
1293 if Result0.upper().startswith('STATIC'):\r
1294 Result0 = Result0[6:].strip()\r
1295 Index = Result0.find(ReturnType)\r
30fdf114
LG
1296 if Index != 0 or Result[3] != 0:\r
1297 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '[%s] Return Type should appear at the start of line' % FuncName, 'Function', Result[1])\r
52302d4d 1298\r
30fdf114
LG
1299def CheckFuncLayoutModifier(FullFileName):\r
1300 ErrorMsgList = []\r
52302d4d 1301\r
30fdf114
LG
1302 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1303 if FileID < 0:\r
1304 return ErrorMsgList\r
52302d4d 1305\r
30fdf114
LG
1306 Db = GetDB()\r
1307 FileTable = 'Identifier' + str(FileID)\r
1308 SqlStatement = """ select Modifier, ID\r
1309 from %s\r
1310 where Model = %d\r
1311 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
1312 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1313 for Result in ResultSet:\r
1314 ReturnType = GetDataTypeFromModifier(Result[0])\r
1315 TypeStart = ReturnType.split()[0]\r
1316# if len(ReturnType) == 0:\r
1317# continue\r
1318 Index = Result[0].find(TypeStart)\r
1319 if Index != 0:\r
1320 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_OPTIONAL_FUNCTIONAL_MODIFIER, '', FileTable, Result[1])\r
52302d4d 1321\r
30fdf114
LG
1322 SqlStatement = """ select Modifier, ID\r
1323 from Function\r
1324 where BelongsToFile = %d\r
1325 """ % (FileID)\r
1326 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1327 for Result in ResultSet:\r
1328 ReturnType = GetDataTypeFromModifier(Result[0])\r
1329 TypeStart = ReturnType.split()[0]\r
1330# if len(ReturnType) == 0:\r
1331# continue\r
72358997
HC
1332 Result0 = Result[0]\r
1333 if Result0.upper().startswith('STATIC'):\r
1334 Result0 = Result0[6:].strip()\r
1335 Index = Result0.find(TypeStart)\r
30fdf114
LG
1336 if Index != 0:\r
1337 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_OPTIONAL_FUNCTIONAL_MODIFIER, '', 'Function', Result[1])\r
1338\r
1339def CheckFuncLayoutName(FullFileName):\r
1340 ErrorMsgList = []\r
1341 # Parameter variable format pattern.\r
1342 Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$')\r
1343 ParamIgnoreList = ('VOID', '...')\r
1344 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1345 if FileID < 0:\r
1346 return ErrorMsgList\r
52302d4d 1347\r
30fdf114
LG
1348 Db = GetDB()\r
1349 FileTable = 'Identifier' + str(FileID)\r
1350 SqlStatement = """ select Name, ID, EndColumn, Value\r
1351 from %s\r
1352 where Model = %d\r
1353 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
1354 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1355 for Result in ResultSet:\r
1356 FuncName = Result[3]\r
1357 if EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, FuncName):\r
1358 continue\r
1359 if Result[2] != 0:\r
1360 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Function name [%s] should appear at the start of a line' % FuncName, FileTable, Result[1])\r
1361 ParamList = GetParamList(Result[0])\r
1362 if len(ParamList) == 0:\r
1363 continue\r
1364 StartLine = 0\r
1365 for Param in ParamList:\r
1366 if Param.StartLine <= StartLine:\r
1367 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Parameter %s should be in its own line.' % Param.Name, FileTable, Result[1])\r
1368 if Param.StartLine - StartLine > 1:\r
52302d4d 1369 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Empty line appears before Parameter %s.' % Param.Name, FileTable, Result[1])\r
30fdf114
LG
1370 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
1371 PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Parameter [%s] NOT follow naming convention.' % Param.Name, FileTable, Result[1])\r
1372 StartLine = Param.StartLine\r
52302d4d 1373\r
30fdf114
LG
1374 if not Result[0].endswith('\n )') and not Result[0].endswith('\r )'):\r
1375 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, '\')\' should be on a new line and indented two spaces', FileTable, Result[1])\r
52302d4d 1376\r
30fdf114
LG
1377 SqlStatement = """ select Modifier, ID, FunNameStartColumn, Name\r
1378 from Function\r
1379 where BelongsToFile = %d\r
1380 """ % (FileID)\r
1381 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1382 for Result in ResultSet:\r
1383 FuncName = Result[3]\r
1384 if EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, FuncName):\r
1385 continue\r
1386 if Result[2] != 0:\r
1387 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Function name [%s] should appear at the start of a line' % FuncName, 'Function', Result[1])\r
1388 ParamList = GetParamList(Result[0])\r
1389 if len(ParamList) == 0:\r
1390 continue\r
1391 StartLine = 0\r
1392 for Param in ParamList:\r
1393 if Param.StartLine <= StartLine:\r
1394 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Parameter %s should be in its own line.' % Param.Name, 'Function', Result[1])\r
1395 if Param.StartLine - StartLine > 1:\r
1396 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Empty line appears before Parameter %s.' % Param.Name, 'Function', Result[1])\r
1397 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
1398 PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Parameter [%s] NOT follow naming convention.' % Param.Name, FileTable, Result[1])\r
1399 StartLine = Param.StartLine\r
1400 if not Result[0].endswith('\n )') and not Result[0].endswith('\r )'):\r
1401 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, '\')\' should be on a new line and indented two spaces', 'Function', Result[1])\r
1402\r
1403def CheckFuncLayoutPrototype(FullFileName):\r
1404 ErrorMsgList = []\r
52302d4d 1405\r
30fdf114
LG
1406 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1407 if FileID < 0:\r
1408 return ErrorMsgList\r
52302d4d 1409\r
30fdf114
LG
1410 FileTable = 'Identifier' + str(FileID)\r
1411 Db = GetDB()\r
1412 SqlStatement = """ select Modifier, Header, Name, ID\r
1413 from Function\r
1414 where BelongsToFile = %d\r
1415 """ % (FileID)\r
1416 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1417 if len(ResultSet) == 0:\r
1418 return ErrorMsgList\r
52302d4d 1419\r
30fdf114
LG
1420 FuncDefList = []\r
1421 for Result in ResultSet:\r
1422 FuncDefList.append(Result)\r
52302d4d 1423\r
30fdf114
LG
1424 SqlStatement = """ select Modifier, Name, ID\r
1425 from %s\r
1426 where Model = %d\r
1427 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
1428 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1429 FuncDeclList = []\r
1430 for Result in ResultSet:\r
1431 FuncDeclList.append(Result)\r
52302d4d 1432\r
30fdf114
LG
1433 UndeclFuncList = []\r
1434 for FuncDef in FuncDefList:\r
1435 FuncName = FuncDef[2].strip()\r
1436 FuncModifier = FuncDef[0]\r
1437 FuncDefHeader = FuncDef[1]\r
1438 for FuncDecl in FuncDeclList:\r
1439 LBPos = FuncDecl[1].find('(')\r
1440 DeclName = FuncDecl[1][0:LBPos].strip()\r
1441 DeclModifier = FuncDecl[0]\r
1442 if DeclName == FuncName:\r
1443 if DiffModifier(FuncModifier, DeclModifier) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, FuncName):\r
1444 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, 'Function [%s] modifier different with prototype.' % FuncName, 'Function', FuncDef[3])\r
1445 ParamListOfDef = GetParamList(FuncDefHeader)\r
1446 ParamListOfDecl = GetParamList(FuncDecl[1])\r
52302d4d
LG
1447 if len(ParamListOfDef) != len(ParamListOfDecl) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_2, FuncName):\r
1448 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_2, 'Parameter number different in function [%s].' % FuncName, 'Function', FuncDef[3])\r
30fdf114
LG
1449 break\r
1450\r
1451 Index = 0\r
1452 while Index < len(ParamListOfDef):\r
52302d4d
LG
1453 if DiffModifier(ParamListOfDef[Index].Modifier, ParamListOfDecl[Index].Modifier) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_3, FuncName):\r
1454 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
1455 Index += 1\r
1456 break\r
1457 else:\r
1458 UndeclFuncList.append(FuncDef)\r
52302d4d 1459\r
30fdf114
LG
1460 IncludeFileList = GetAllIncludeFiles(FullFileName)\r
1461 FuncDeclList = []\r
1462 for F in IncludeFileList:\r
1463 FileID = GetTableID(F, ErrorMsgList)\r
1464 if FileID < 0:\r
1465 continue\r
52302d4d 1466\r
30fdf114
LG
1467 FileTable = 'Identifier' + str(FileID)\r
1468 SqlStatement = """ select Modifier, Name, ID\r
1469 from %s\r
1470 where Model = %d\r
1471 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
1472 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1473\r
1474 for Result in ResultSet:\r
1475 FuncDeclList.append(Result)\r
52302d4d 1476\r
30fdf114
LG
1477 for FuncDef in UndeclFuncList:\r
1478 FuncName = FuncDef[2].strip()\r
1479 FuncModifier = FuncDef[0]\r
1480 FuncDefHeader = FuncDef[1]\r
1481 for FuncDecl in FuncDeclList:\r
1482 LBPos = FuncDecl[1].find('(')\r
1483 DeclName = FuncDecl[1][0:LBPos].strip()\r
1484 DeclModifier = FuncDecl[0]\r
1485 if DeclName == FuncName:\r
1486 if DiffModifier(FuncModifier, DeclModifier) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, FuncName):\r
1487 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, 'Function [%s] modifier different with prototype.' % FuncName, 'Function', FuncDef[3])\r
1488 ParamListOfDef = GetParamList(FuncDefHeader)\r
1489 ParamListOfDecl = GetParamList(FuncDecl[1])\r
52302d4d
LG
1490 if len(ParamListOfDef) != len(ParamListOfDecl) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_2, FuncName):\r
1491 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_2, 'Parameter number different in function [%s].' % FuncName, 'Function', FuncDef[3])\r
30fdf114
LG
1492 break\r
1493\r
1494 Index = 0\r
1495 while Index < len(ParamListOfDef):\r
52302d4d
LG
1496 if DiffModifier(ParamListOfDef[Index].Modifier, ParamListOfDecl[Index].Modifier) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_3, FuncName):\r
1497 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
1498 Index += 1\r
1499 break\r
52302d4d 1500\r
30fdf114
LG
1501def CheckFuncLayoutBody(FullFileName):\r
1502 ErrorMsgList = []\r
52302d4d 1503\r
30fdf114
LG
1504 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1505 if FileID < 0:\r
1506 return ErrorMsgList\r
52302d4d 1507\r
30fdf114
LG
1508 FileTable = 'Identifier' + str(FileID)\r
1509 Db = GetDB()\r
1510 SqlStatement = """ select BodyStartColumn, EndColumn, ID\r
1511 from Function\r
1512 where BelongsToFile = %d\r
1513 """ % (FileID)\r
1514 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1515 if len(ResultSet) == 0:\r
1516 return ErrorMsgList\r
1517 for Result in ResultSet:\r
1518 if Result[0] != 0:\r
1519 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY, 'open brace should be at the very beginning of a line.', 'Function', Result[2])\r
1520 if Result[1] != 0:\r
1521 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY, 'close brace should be at the very beginning of a line.', 'Function', Result[2])\r
1522\r
1523def CheckFuncLayoutLocalVariable(FullFileName):\r
1524 ErrorMsgList = []\r
52302d4d 1525\r
30fdf114
LG
1526 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1527 if FileID < 0:\r
1528 return ErrorMsgList\r
52302d4d 1529\r
30fdf114
LG
1530 Db = GetDB()\r
1531 FileTable = 'Identifier' + str(FileID)\r
1532 SqlStatement = """ select ID\r
1533 from Function\r
1534 where BelongsToFile = %d\r
1535 """ % (FileID)\r
1536 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1537 if len(ResultSet) == 0:\r
1538 return ErrorMsgList\r
1539 FL = []\r
1540 for Result in ResultSet:\r
1541 FL.append(Result)\r
52302d4d 1542\r
30fdf114 1543 for F in FL:\r
79b74a03 1544 SqlStatement = """ select Name, Value, ID, Modifier\r
30fdf114
LG
1545 from %s\r
1546 where Model = %d and BelongsToFunction = %d\r
1547 """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE, F[0])\r
1548 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1549 if len(ResultSet) == 0:\r
1550 continue\r
52302d4d 1551\r
30fdf114 1552 for Result in ResultSet:\r
79b74a03 1553 if len(Result[1]) > 0 and 'CONST' not in Result[3]:\r
30fdf114 1554 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_NO_INIT_OF_VARIABLE, 'Variable Name: %s' % Result[0], FileTable, Result[2])\r
52302d4d 1555\r
30fdf114
LG
1556def CheckMemberVariableFormat(Name, Value, FileTable, TdId, ModelId):\r
1557 ErrMsgList = []\r
1558 # Member variable format pattern.\r
1559 Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$')\r
52302d4d 1560\r
30fdf114
LG
1561 LBPos = Value.find('{')\r
1562 RBPos = Value.rfind('}')\r
1563 if LBPos == -1 or RBPos == -1:\r
1564 return ErrMsgList\r
52302d4d 1565\r
30fdf114
LG
1566 Fields = Value[LBPos + 1 : RBPos]\r
1567 Fields = StripComments(Fields).strip()\r
1568 NestPos = Fields.find ('struct')\r
1569 if NestPos != -1 and (NestPos + len('struct') < len(Fields)):\r
1570 if not Fields[NestPos + len('struct') + 1].isalnum():\r
1571 if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, Name):\r
1572 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, 'Nested struct in [%s].' % (Name), FileTable, TdId)\r
1573 return ErrMsgList\r
1574 NestPos = Fields.find ('union')\r
1575 if NestPos != -1 and (NestPos + len('union') < len(Fields)):\r
1576 if not Fields[NestPos + len('union') + 1].isalnum():\r
1577 if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, Name):\r
1578 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, 'Nested union in [%s].' % (Name), FileTable, TdId)\r
1579 return ErrMsgList\r
1580 NestPos = Fields.find ('enum')\r
1581 if NestPos != -1 and (NestPos + len('enum') < len(Fields)):\r
1582 if not Fields[NestPos + len('enum') + 1].isalnum():\r
1583 if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, Name):\r
1584 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, 'Nested enum in [%s].' % (Name), FileTable, TdId)\r
1585 return ErrMsgList\r
52302d4d 1586\r
30fdf114
LG
1587 if ModelId == DataClass.MODEL_IDENTIFIER_ENUMERATE:\r
1588 FieldsList = Fields.split(',')\r
1589 # deal with enum is pre-assigned a value by function call ( , , , ...)\r
1590 QuoteCount = 0\r
1591 Index = 0\r
1592 RemoveCurrentElement = False\r
1593 while Index < len(FieldsList):\r
1594 Field = FieldsList[Index]\r
52302d4d 1595\r
30fdf114
LG
1596 if Field.find('(') != -1:\r
1597 QuoteCount += 1\r
1598 RemoveCurrentElement = True\r
1599 Index += 1\r
1600 continue\r
52302d4d 1601\r
30fdf114
LG
1602 if Field.find(')') != -1 and QuoteCount > 0:\r
1603 QuoteCount -= 1\r
1604\r
52302d4d 1605 if RemoveCurrentElement:\r
30fdf114
LG
1606 FieldsList.remove(Field)\r
1607 if QuoteCount == 0:\r
1608 RemoveCurrentElement = False\r
1609 continue\r
52302d4d 1610\r
30fdf114
LG
1611 if QuoteCount == 0:\r
1612 RemoveCurrentElement = False\r
52302d4d 1613\r
30fdf114
LG
1614 Index += 1\r
1615 else:\r
1616 FieldsList = Fields.split(';')\r
52302d4d 1617\r
30fdf114
LG
1618 for Field in FieldsList:\r
1619 Field = Field.strip()\r
1620 if Field == '':\r
1621 continue\r
52302d4d 1622 # For the condition that the field in struct is an array with [] sufixes...\r
30fdf114
LG
1623 if Field[-1] == ']':\r
1624 LBPos = Field.find('[')\r
1625 Field = Field[0:LBPos]\r
1626 # For the condition that bit field ": Number"\r
1627 if Field.find(':') != -1:\r
1628 ColonPos = Field.find(':')\r
1629 Field = Field[0:ColonPos]\r
52302d4d 1630\r
30fdf114
LG
1631 Field = Field.strip()\r
1632 if Field == '':\r
1633 continue\r
1634 # Enum could directly assign value to variable\r
1635 Field = Field.split('=')[0].strip()\r
52302d4d 1636 TokenList = Field.split()\r
30fdf114 1637 # Remove pointers before variable\r
fa3a2156
HC
1638 Token = TokenList[-1]\r
1639 if Token in ['OPTIONAL']:\r
1640 Token = TokenList[-2]\r
1641 if not Pattern.match(Token.lstrip('*')):\r
1642 ErrMsgList.append(Token.lstrip('*'))\r
52302d4d 1643\r
30fdf114
LG
1644 return ErrMsgList\r
1645\r
1646def CheckDeclTypedefFormat(FullFileName, ModelId):\r
1647 ErrorMsgList = []\r
52302d4d 1648\r
30fdf114
LG
1649 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1650 if FileID < 0:\r
1651 return ErrorMsgList\r
52302d4d 1652\r
30fdf114
LG
1653 Db = GetDB()\r
1654 FileTable = 'Identifier' + str(FileID)\r
1655 SqlStatement = """ select Name, StartLine, EndLine, ID, Value\r
1656 from %s\r
1657 where Model = %d\r
1658 """ % (FileTable, ModelId)\r
1659 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1660 ResultList = []\r
1661 for Result in ResultSet:\r
1662 ResultList.append(Result)\r
52302d4d 1663\r
30fdf114
LG
1664 ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_ALL\r
1665 if ModelId == DataClass.MODEL_IDENTIFIER_STRUCTURE:\r
1666 ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_STRUCTURE_DECLARATION\r
1667 elif ModelId == DataClass.MODEL_IDENTIFIER_ENUMERATE:\r
1668 ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_ENUMERATED_TYPE\r
1669 elif ModelId == DataClass.MODEL_IDENTIFIER_UNION:\r
1670 ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_UNION_TYPE\r
52302d4d 1671\r
30fdf114
LG
1672 SqlStatement = """ select Modifier, Name, Value, StartLine, EndLine, ID\r
1673 from %s\r
1674 where Model = %d\r
1675 """ % (FileTable, DataClass.MODEL_IDENTIFIER_TYPEDEF)\r
1676 TdSet = Db.TblFile.Exec(SqlStatement)\r
1677 TdList = []\r
1678 for Td in TdSet:\r
1679 TdList.append(Td)\r
1680 # Check member variable name format that from typedefs of ONLY this file.\r
1681 for Td in TdList:\r
1682 Name = Td[1].strip()\r
1683 Value = Td[2].strip()\r
1684 if Value.startswith('enum'):\r
1685 ValueModelId = DataClass.MODEL_IDENTIFIER_ENUMERATE\r
1686 elif Value.startswith('struct'):\r
1687 ValueModelId = DataClass.MODEL_IDENTIFIER_STRUCTURE\r
1688 elif Value.startswith('union'):\r
1689 ValueModelId = DataClass.MODEL_IDENTIFIER_UNION\r
1690 else:\r
1691 continue\r
52302d4d 1692\r
30fdf114
LG
1693 if ValueModelId != ModelId:\r
1694 continue\r
1695 # Check member variable format.\r
1696 ErrMsgList = CheckMemberVariableFormat(Name, Value, FileTable, Td[5], ModelId)\r
1697 for ErrMsg in ErrMsgList:\r
79b74a03 1698 if EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Name + '.' + ErrMsg):\r
30fdf114 1699 continue\r
79b74a03 1700 PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Member variable [%s] NOT follow naming convention.' % (Name + '.' + ErrMsg), FileTable, Td[5])\r
52302d4d 1701\r
30fdf114
LG
1702 # First check in current file to see whether struct/union/enum is typedef-ed.\r
1703 UntypedefedList = []\r
1704 for Result in ResultList:\r
1705 # Check member variable format.\r
1706 Name = Result[0].strip()\r
1707 Value = Result[4].strip()\r
1708 if Value.startswith('enum'):\r
1709 ValueModelId = DataClass.MODEL_IDENTIFIER_ENUMERATE\r
1710 elif Value.startswith('struct'):\r
1711 ValueModelId = DataClass.MODEL_IDENTIFIER_STRUCTURE\r
1712 elif Value.startswith('union'):\r
1713 ValueModelId = DataClass.MODEL_IDENTIFIER_UNION\r
1714 else:\r
1715 continue\r
52302d4d 1716\r
30fdf114
LG
1717 if ValueModelId != ModelId:\r
1718 continue\r
1719 ErrMsgList = CheckMemberVariableFormat(Name, Value, FileTable, Result[3], ModelId)\r
1720 for ErrMsg in ErrMsgList:\r
79b74a03 1721 if EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Result[0] + '.' + ErrMsg):\r
30fdf114 1722 continue\r
79b74a03 1723 PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Member variable [%s] NOT follow naming convention.' % (Result[0] + '.' + ErrMsg), FileTable, Result[3])\r
30fdf114
LG
1724 # Check whether it is typedefed.\r
1725 Found = False\r
1726 for Td in TdList:\r
1727 # skip function pointer\r
1728 if len(Td[0]) > 0:\r
1729 continue\r
1730 if Result[1] >= Td[3] and Td[4] >= Result[2]:\r
1731 Found = True\r
1732 if not Td[1].isupper():\r
1733 PrintErrorMsg(ErrorType, 'Typedef should be UPPER case', FileTable, Td[5])\r
1734 if Result[0] in Td[2].split():\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 Found:\r
1739 break\r
52302d4d 1740\r
30fdf114
LG
1741 if not Found:\r
1742 UntypedefedList.append(Result)\r
1743 continue\r
52302d4d 1744\r
30fdf114
LG
1745 if len(UntypedefedList) == 0:\r
1746 return\r
52302d4d 1747\r
30fdf114
LG
1748 IncludeFileList = GetAllIncludeFiles(FullFileName)\r
1749 TdList = []\r
1750 for F in IncludeFileList:\r
1751 FileID = GetTableID(F, ErrorMsgList)\r
1752 if FileID < 0:\r
1753 continue\r
52302d4d 1754\r
30fdf114
LG
1755 IncludeFileTable = 'Identifier' + str(FileID)\r
1756 SqlStatement = """ select Modifier, Name, Value, StartLine, EndLine, ID\r
1757 from %s\r
1758 where Model = %d\r
1759 """ % (IncludeFileTable, DataClass.MODEL_IDENTIFIER_TYPEDEF)\r
1760 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1761 TdList.extend(ResultSet)\r
52302d4d 1762\r
30fdf114 1763 for Result in UntypedefedList:\r
52302d4d 1764\r
30fdf114
LG
1765 # Check whether it is typedefed.\r
1766 Found = False\r
1767 for Td in TdList:\r
52302d4d 1768\r
30fdf114
LG
1769 if len(Td[0]) > 0:\r
1770 continue\r
1771 if Result[1] >= Td[3] and Td[4] >= Result[2]:\r
1772 Found = True\r
1773 if not Td[1].isupper():\r
1774 PrintErrorMsg(ErrorType, 'Typedef should be UPPER case', FileTable, Td[5])\r
1775 if Result[0] in Td[2].split():\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 Found:\r
1780 break\r
52302d4d 1781\r
30fdf114
LG
1782 if not Found:\r
1783 PrintErrorMsg(ErrorType, 'No Typedef for %s' % Result[0], FileTable, Result[3])\r
1784 continue\r
52302d4d 1785\r
30fdf114
LG
1786def CheckDeclStructTypedef(FullFileName):\r
1787 CheckDeclTypedefFormat(FullFileName, DataClass.MODEL_IDENTIFIER_STRUCTURE)\r
1788\r
1789def CheckDeclEnumTypedef(FullFileName):\r
1790 CheckDeclTypedefFormat(FullFileName, DataClass.MODEL_IDENTIFIER_ENUMERATE)\r
52302d4d 1791\r
30fdf114
LG
1792def CheckDeclUnionTypedef(FullFileName):\r
1793 CheckDeclTypedefFormat(FullFileName, DataClass.MODEL_IDENTIFIER_UNION)\r
1794\r
1795def CheckDeclArgModifier(FullFileName):\r
1796 ErrorMsgList = []\r
52302d4d 1797\r
30fdf114
LG
1798 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1799 if FileID < 0:\r
1800 return ErrorMsgList\r
52302d4d 1801\r
30fdf114
LG
1802 Db = GetDB()\r
1803 FileTable = 'Identifier' + str(FileID)\r
1804 SqlStatement = """ select Modifier, Name, ID\r
1805 from %s\r
1806 where Model = %d\r
1807 """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE)\r
1808 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1809 ModifierTuple = ('IN', 'OUT', 'OPTIONAL', 'UNALIGNED')\r
1810 MAX_MODIFIER_LENGTH = 100\r
1811 for Result in ResultSet:\r
1812 for Modifier in ModifierTuple:\r
1813 if PatternInModifier(Result[0], Modifier) and len(Result[0]) < MAX_MODIFIER_LENGTH:\r
1814 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER, 'Variable Modifier %s' % Result[0], FileTable, Result[2])\r
1815 break\r
52302d4d 1816\r
30fdf114
LG
1817 SqlStatement = """ select Modifier, Name, ID\r
1818 from %s\r
1819 where Model = %d\r
1820 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
1821 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1822 for Result in ResultSet:\r
1823 for Modifier in ModifierTuple:\r
1824 if PatternInModifier(Result[0], Modifier):\r
1825 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER, 'Return Type Modifier %s' % Result[0], FileTable, Result[2])\r
1826 break\r
52302d4d 1827\r
30fdf114
LG
1828 SqlStatement = """ select Modifier, Header, ID\r
1829 from Function\r
1830 where BelongsToFile = %d\r
1831 """ % (FileID)\r
1832 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1833 for Result in ResultSet:\r
1834 for Modifier in ModifierTuple:\r
1835 if PatternInModifier(Result[0], Modifier):\r
1836 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER, 'Return Type Modifier %s' % Result[0], FileTable, Result[2])\r
1837 break\r
1838\r
1839def CheckDeclNoUseCType(FullFileName):\r
1840 ErrorMsgList = []\r
52302d4d 1841\r
30fdf114
LG
1842 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1843 if FileID < 0:\r
1844 return ErrorMsgList\r
52302d4d 1845\r
30fdf114
LG
1846 Db = GetDB()\r
1847 FileTable = 'Identifier' + str(FileID)\r
1848 SqlStatement = """ select Modifier, Name, ID\r
1849 from %s\r
1850 where Model = %d\r
1851 """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE)\r
1852 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1853 CTypeTuple = ('int', 'unsigned', 'char', 'void', 'static', 'long')\r
1854 for Result in ResultSet:\r
1855 for Type in CTypeTuple:\r
1856 if PatternInModifier(Result[0], Type):\r
1857 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, 'Variable type %s' % Type, FileTable, Result[2])\r
1858 break\r
52302d4d 1859\r
30fdf114
LG
1860 SqlStatement = """ select Modifier, Name, ID, Value\r
1861 from %s\r
1862 where Model = %d\r
1863 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
1864 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1865 for Result in ResultSet:\r
1866 ParamList = GetParamList(Result[1])\r
1867 FuncName = Result[3]\r
1868 if EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, FuncName):\r
1869 continue\r
1870 for Type in CTypeTuple:\r
1871 if PatternInModifier(Result[0], Type):\r
1872 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, '%s Return type %s' % (FuncName, Result[0]), FileTable, Result[2])\r
52302d4d 1873\r
30fdf114
LG
1874 for Param in ParamList:\r
1875 if PatternInModifier(Param.Modifier, Type):\r
1876 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, 'Parameter %s' % Param.Name, FileTable, Result[2])\r
52302d4d 1877\r
30fdf114
LG
1878 SqlStatement = """ select Modifier, Header, ID, Name\r
1879 from Function\r
1880 where BelongsToFile = %d\r
1881 """ % (FileID)\r
1882 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1883 for Result in ResultSet:\r
1884 ParamList = GetParamList(Result[1])\r
1885 FuncName = Result[3]\r
1886 if EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, FuncName):\r
1887 continue\r
1888 for Type in CTypeTuple:\r
1889 if PatternInModifier(Result[0], Type):\r
1890 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, '[%s] Return type %s' % (FuncName, Result[0]), FileTable, Result[2])\r
52302d4d 1891\r
30fdf114
LG
1892 for Param in ParamList:\r
1893 if PatternInModifier(Param.Modifier, Type):\r
1894 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, 'Parameter %s' % Param.Name, FileTable, Result[2])\r
52302d4d 1895\r
30fdf114
LG
1896\r
1897def CheckPointerNullComparison(FullFileName):\r
1898 ErrorMsgList = []\r
52302d4d 1899\r
30fdf114
LG
1900 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1901 if FileID < 0:\r
1902 return ErrorMsgList\r
52302d4d 1903\r
30fdf114
LG
1904 # cache the found function return type to accelerate later checking in this file.\r
1905 FuncReturnTypeDict = {}\r
52302d4d 1906\r
30fdf114
LG
1907 Db = GetDB()\r
1908 FileTable = 'Identifier' + str(FileID)\r
1909 SqlStatement = """ select Value, StartLine, ID\r
1910 from %s\r
1911 where Model = %d\r
1912 """ % (FileTable, DataClass.MODEL_IDENTIFIER_PREDICATE_EXPRESSION)\r
1913 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1914 if len(ResultSet) == 0:\r
1915 return\r
1916 PSL = []\r
1917 for Result in ResultSet:\r
1918 PSL.append([Result[0], Result[1], Result[2]])\r
52302d4d 1919\r
30fdf114
LG
1920 SqlStatement = """ select BodyStartLine, EndLine, Header, Modifier, ID\r
1921 from Function\r
1922 where BelongsToFile = %d\r
1923 """ % (FileID)\r
1924 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1925 FL = []\r
1926 for Result in ResultSet:\r
1927 FL.append([Result[0], Result[1], Result[2], Result[3], Result[4]])\r
52302d4d 1928\r
30fdf114
LG
1929 p = GetFuncDeclPattern()\r
1930 for Str in PSL:\r
1931 FuncRecord = GetFuncContainsPE(Str[1], FL)\r
1932 if FuncRecord == None:\r
1933 continue\r
52302d4d 1934\r
30fdf114
LG
1935 for Exp in GetPredicateListFromPredicateExpStr(Str[0]):\r
1936 PredInfo = SplitPredicateStr(Exp)\r
1937 if PredInfo[1] == None:\r
1938 PredVarStr = PredInfo[0][0].strip()\r
1939 IsFuncCall = False\r
1940 SearchInCache = False\r
1941 # PredVarStr may contain '.' or '->'\r
1942 TmpStr = PredVarStr.replace('.', '').replace('->', '')\r
1943 if p.match(TmpStr):\r
1944 PredVarStr = PredVarStr[0:PredVarStr.find('(')]\r
1945 SearchInCache = True\r
1946 # Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable.\r
52302d4d 1947 if TmpStr.startswith(PredVarStr):\r
30fdf114 1948 IsFuncCall = True\r
52302d4d 1949\r
30fdf114
LG
1950 if PredVarStr.strip() in IgnoredKeywordList:\r
1951 continue\r
1952 StarList = []\r
1953 PredVarList = GetCNameList(PredVarStr, StarList)\r
1954 # No variable found, maybe value first? like (0 == VarName)\r
1955 if len(PredVarList) == 0:\r
1956 continue\r
1957 if SearchInCache:\r
1958 Type = FuncReturnTypeDict.get(PredVarStr)\r
1959 if Type != None:\r
79b74a03 1960 if Type.find('*') != -1 and Type != 'BOOLEAN*':\r
30fdf114
LG
1961 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
1962 continue\r
52302d4d 1963\r
30fdf114
LG
1964 if PredVarStr in FuncReturnTypeDict:\r
1965 continue\r
52302d4d 1966\r
30fdf114
LG
1967 Type = GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall, None, StarList)\r
1968 if SearchInCache:\r
1969 FuncReturnTypeDict[PredVarStr] = Type\r
1970 if Type == None:\r
1971 continue\r
52302d4d 1972 Type = GetTypeFromArray(Type, PredVarStr)\r
79b74a03 1973 if Type.find('*') != -1 and Type != 'BOOLEAN*':\r
30fdf114
LG
1974 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
1975\r
1976def CheckNonBooleanValueComparison(FullFileName):\r
1977 ErrorMsgList = []\r
52302d4d 1978\r
30fdf114
LG
1979 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1980 if FileID < 0:\r
1981 return ErrorMsgList\r
52302d4d 1982\r
30fdf114
LG
1983 # cache the found function return type to accelerate later checking in this file.\r
1984 FuncReturnTypeDict = {}\r
52302d4d 1985\r
30fdf114
LG
1986 Db = GetDB()\r
1987 FileTable = 'Identifier' + str(FileID)\r
1988 SqlStatement = """ select Value, StartLine, ID\r
1989 from %s\r
1990 where Model = %d\r
1991 """ % (FileTable, DataClass.MODEL_IDENTIFIER_PREDICATE_EXPRESSION)\r
1992 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1993 if len(ResultSet) == 0:\r
1994 return\r
1995 PSL = []\r
1996 for Result in ResultSet:\r
1997 PSL.append([Result[0], Result[1], Result[2]])\r
52302d4d 1998\r
30fdf114
LG
1999 SqlStatement = """ select BodyStartLine, EndLine, Header, Modifier, ID\r
2000 from Function\r
2001 where BelongsToFile = %d\r
2002 """ % (FileID)\r
2003 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2004 FL = []\r
2005 for Result in ResultSet:\r
2006 FL.append([Result[0], Result[1], Result[2], Result[3], Result[4]])\r
52302d4d 2007\r
30fdf114
LG
2008 p = GetFuncDeclPattern()\r
2009 for Str in PSL:\r
2010 FuncRecord = GetFuncContainsPE(Str[1], FL)\r
2011 if FuncRecord == None:\r
2012 continue\r
52302d4d 2013\r
30fdf114 2014 for Exp in GetPredicateListFromPredicateExpStr(Str[0]):\r
30fdf114
LG
2015 PredInfo = SplitPredicateStr(Exp)\r
2016 if PredInfo[1] == None:\r
2017 PredVarStr = PredInfo[0][0].strip()\r
2018 IsFuncCall = False\r
2019 SearchInCache = False\r
2020 # PredVarStr may contain '.' or '->'\r
2021 TmpStr = PredVarStr.replace('.', '').replace('->', '')\r
2022 if p.match(TmpStr):\r
2023 PredVarStr = PredVarStr[0:PredVarStr.find('(')]\r
2024 SearchInCache = True\r
2025 # Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable.\r
52302d4d 2026 if TmpStr.startswith(PredVarStr):\r
30fdf114 2027 IsFuncCall = True\r
52302d4d 2028\r
30fdf114
LG
2029 if PredVarStr.strip() in IgnoredKeywordList:\r
2030 continue\r
2031 StarList = []\r
2032 PredVarList = GetCNameList(PredVarStr, StarList)\r
2033 # No variable found, maybe value first? like (0 == VarName)\r
2034 if len(PredVarList) == 0:\r
2035 continue\r
52302d4d 2036\r
30fdf114
LG
2037 if SearchInCache:\r
2038 Type = FuncReturnTypeDict.get(PredVarStr)\r
2039 if Type != None:\r
2040 if Type.find('BOOLEAN') == -1:\r
2041 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
2042 continue\r
52302d4d 2043\r
30fdf114
LG
2044 if PredVarStr in FuncReturnTypeDict:\r
2045 continue\r
30fdf114
LG
2046 Type = GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall, 'BOOLEAN', StarList)\r
2047 if SearchInCache:\r
2048 FuncReturnTypeDict[PredVarStr] = Type\r
2049 if Type == None:\r
2050 continue\r
2051 if Type.find('BOOLEAN') == -1:\r
2052 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
52302d4d 2053\r
30fdf114
LG
2054\r
2055def CheckBooleanValueComparison(FullFileName):\r
2056 ErrorMsgList = []\r
52302d4d 2057\r
30fdf114
LG
2058 FileID = GetTableID(FullFileName, ErrorMsgList)\r
2059 if FileID < 0:\r
2060 return ErrorMsgList\r
52302d4d 2061\r
30fdf114
LG
2062 # cache the found function return type to accelerate later checking in this file.\r
2063 FuncReturnTypeDict = {}\r
52302d4d 2064\r
30fdf114
LG
2065 Db = GetDB()\r
2066 FileTable = 'Identifier' + str(FileID)\r
2067 SqlStatement = """ select Value, StartLine, ID\r
2068 from %s\r
2069 where Model = %d\r
2070 """ % (FileTable, DataClass.MODEL_IDENTIFIER_PREDICATE_EXPRESSION)\r
2071 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2072 if len(ResultSet) == 0:\r
2073 return\r
2074 PSL = []\r
2075 for Result in ResultSet:\r
2076 PSL.append([Result[0], Result[1], Result[2]])\r
52302d4d 2077\r
30fdf114
LG
2078 SqlStatement = """ select BodyStartLine, EndLine, Header, Modifier, ID\r
2079 from Function\r
2080 where BelongsToFile = %d\r
2081 """ % (FileID)\r
2082 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2083 FL = []\r
2084 for Result in ResultSet:\r
2085 FL.append([Result[0], Result[1], Result[2], Result[3], Result[4]])\r
52302d4d 2086\r
30fdf114
LG
2087 p = GetFuncDeclPattern()\r
2088 for Str in PSL:\r
2089 FuncRecord = GetFuncContainsPE(Str[1], FL)\r
2090 if FuncRecord == None:\r
2091 continue\r
52302d4d 2092\r
30fdf114
LG
2093 for Exp in GetPredicateListFromPredicateExpStr(Str[0]):\r
2094 PredInfo = SplitPredicateStr(Exp)\r
2095 if PredInfo[1] in ('==', '!=') and PredInfo[0][1] in ('TRUE', 'FALSE'):\r
2096 PredVarStr = PredInfo[0][0].strip()\r
2097 IsFuncCall = False\r
2098 SearchInCache = False\r
2099 # PredVarStr may contain '.' or '->'\r
2100 TmpStr = PredVarStr.replace('.', '').replace('->', '')\r
2101 if p.match(TmpStr):\r
2102 PredVarStr = PredVarStr[0:PredVarStr.find('(')]\r
2103 SearchInCache = True\r
2104 # Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable.\r
52302d4d 2105 if TmpStr.startswith(PredVarStr):\r
30fdf114 2106 IsFuncCall = True\r
52302d4d 2107\r
30fdf114
LG
2108 if PredVarStr.strip() in IgnoredKeywordList:\r
2109 continue\r
2110 StarList = []\r
2111 PredVarList = GetCNameList(PredVarStr, StarList)\r
2112 # No variable found, maybe value first? like (0 == VarName)\r
2113 if len(PredVarList) == 0:\r
2114 continue\r
52302d4d 2115\r
30fdf114
LG
2116 if SearchInCache:\r
2117 Type = FuncReturnTypeDict.get(PredVarStr)\r
2118 if Type != None:\r
2119 if Type.find('BOOLEAN') != -1:\r
2120 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
2121 continue\r
52302d4d 2122\r
30fdf114
LG
2123 if PredVarStr in FuncReturnTypeDict:\r
2124 continue\r
52302d4d 2125\r
30fdf114
LG
2126 Type = GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall, 'BOOLEAN', StarList)\r
2127 if SearchInCache:\r
2128 FuncReturnTypeDict[PredVarStr] = Type\r
2129 if Type == None:\r
2130 continue\r
2131 if Type.find('BOOLEAN') != -1:\r
2132 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
52302d4d 2133\r
30fdf114
LG
2134\r
2135def CheckHeaderFileData(FullFileName):\r
2136 ErrorMsgList = []\r
52302d4d 2137\r
30fdf114
LG
2138 FileID = GetTableID(FullFileName, ErrorMsgList)\r
2139 if FileID < 0:\r
2140 return ErrorMsgList\r
52302d4d 2141\r
30fdf114
LG
2142 Db = GetDB()\r
2143 FileTable = 'Identifier' + str(FileID)\r
2144 SqlStatement = """ select ID, Modifier\r
2145 from %s\r
2146 where Model = %d\r
2147 """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE)\r
2148 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2149 for Result in ResultSet:\r
2150 if not Result[1].startswith('extern'):\r
2151 PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_DATA, 'Variable definition appears in header file', FileTable, Result[0])\r
52302d4d 2152\r
30fdf114
LG
2153 SqlStatement = """ select ID\r
2154 from Function\r
2155 where BelongsToFile = %d\r
2156 """ % FileID\r
2157 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2158 for Result in ResultSet:\r
2159 PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_DATA, 'Function definition appears in header file', 'Function', Result[0])\r
2160\r
2161 return ErrorMsgList\r
2162\r
2163def CheckHeaderFileIfndef(FullFileName):\r
2164 ErrorMsgList = []\r
52302d4d 2165\r
30fdf114
LG
2166 FileID = GetTableID(FullFileName, ErrorMsgList)\r
2167 if FileID < 0:\r
2168 return ErrorMsgList\r
52302d4d 2169\r
30fdf114
LG
2170 Db = GetDB()\r
2171 FileTable = 'Identifier' + str(FileID)\r
2172 SqlStatement = """ select Value, StartLine\r
2173 from %s\r
2174 where Model = %d order by StartLine\r
2175 """ % (FileTable, DataClass.MODEL_IDENTIFIER_MACRO_IFNDEF)\r
2176 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2177 if len(ResultSet) == 0:\r
2178 PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_1, '', 'File', FileID)\r
2179 return ErrorMsgList\r
2180 for Result in ResultSet:\r
2181 SqlStatement = """ select Value, EndLine\r
2182 from %s\r
2183 where EndLine < %d\r
2184 """ % (FileTable, Result[1])\r
2185 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2186 for Result in ResultSet:\r
2187 if not Result[0].startswith('/*') and not Result[0].startswith('//'):\r
2188 PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_2, '', 'File', FileID)\r
2189 break\r
52302d4d 2190\r
30fdf114
LG
2191 SqlStatement = """ select Value\r
2192 from %s\r
2193 where StartLine > (select max(EndLine) from %s where Model = %d)\r
2194 """ % (FileTable, FileTable, DataClass.MODEL_IDENTIFIER_MACRO_ENDIF)\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_3, '', 'File', FileID)\r
2199 return ErrorMsgList\r
2200\r
2201def CheckDoxygenCommand(FullFileName):\r
2202 ErrorMsgList = []\r
52302d4d 2203\r
30fdf114
LG
2204 FileID = GetTableID(FullFileName, ErrorMsgList)\r
2205 if FileID < 0:\r
2206 return ErrorMsgList\r
52302d4d 2207\r
30fdf114
LG
2208 Db = GetDB()\r
2209 FileTable = 'Identifier' + str(FileID)\r
2210 SqlStatement = """ select Value, ID\r
2211 from %s\r
2212 where Model = %d or Model = %d\r
2213 """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT, DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER)\r
2214 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2215 DoxygenCommandList = ['bug', 'todo', 'example', 'file', 'attention', 'param', 'post', 'pre', 'retval', 'return', 'sa', 'since', 'test', 'note', 'par']\r
2216 for Result in ResultSet:\r
2217 CommentStr = Result[0]\r
2218 CommentPartList = CommentStr.split()\r
2219 for Part in CommentPartList:\r
2220 if Part.upper() == 'BUGBUG':\r
2221 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Bug should be marked with doxygen tag @bug', FileTable, Result[1])\r
2222 if Part.upper() == 'TODO':\r
2223 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'ToDo should be marked with doxygen tag @todo', FileTable, Result[1])\r
2224 if Part.startswith('@'):\r
2225 if EccGlobalData.gException.IsException(ERROR_DOXYGEN_CHECK_COMMAND, Part):\r
2226 continue\r
2227 if Part.lstrip('@').isalpha():\r
2228 if Part.lstrip('@') not in DoxygenCommandList:\r
2229 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Unknown doxygen command %s' % Part, FileTable, Result[1])\r
2230 else:\r
2231 Index = Part.find('[')\r
2232 if Index == -1:\r
2233 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Unknown doxygen command %s' % Part, FileTable, Result[1])\r
2234 RealCmd = Part[1:Index]\r
2235 if RealCmd not in DoxygenCommandList:\r
2236 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Unknown doxygen command %s' % Part, FileTable, Result[1])\r
52302d4d
LG
2237\r
2238\r
30fdf114
LG
2239def CheckDoxygenTripleForwardSlash(FullFileName):\r
2240 ErrorMsgList = []\r
52302d4d 2241\r
30fdf114
LG
2242 FileID = GetTableID(FullFileName, ErrorMsgList)\r
2243 if FileID < 0:\r
2244 return ErrorMsgList\r
52302d4d 2245\r
30fdf114 2246 Db = GetDB()\r
52302d4d 2247\r
30fdf114
LG
2248 SqlStatement = """ select ID, BodyStartLine, BodyStartColumn, EndLine, EndColumn\r
2249 from Function\r
2250 where BelongsToFile = %d\r
2251 """ % (FileID)\r
2252 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2253 if len(ResultSet) == 0:\r
2254 return\r
52302d4d
LG
2255\r
2256 FuncDefSet = []\r
30fdf114
LG
2257 for Result in ResultSet:\r
2258 FuncDefSet.append(Result)\r
52302d4d
LG
2259\r
2260\r
30fdf114
LG
2261 FileTable = 'Identifier' + str(FileID)\r
2262 SqlStatement = """ select Value, ID, StartLine, StartColumn, EndLine, EndColumn\r
2263 from %s\r
52302d4d
LG
2264 where Model = %d\r
2265\r
30fdf114
LG
2266 """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT)\r
2267 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2268 CommentSet = []\r
2269 try:\r
2270 for Result in ResultSet:\r
2271 CommentSet.append(Result)\r
2272 except:\r
2273 print 'Unrecognized chars in comment of file %s', FullFileName\r
52302d4d
LG
2274\r
2275\r
30fdf114
LG
2276 for Result in CommentSet:\r
2277 CommentStr = Result[0]\r
2278 StartLine = Result[2]\r
2279 StartColumn = Result[3]\r
2280 EndLine = Result[4]\r
2281 EndColumn = Result[5]\r
2282 if not CommentStr.startswith('///<'):\r
2283 continue\r
52302d4d 2284\r
30fdf114
LG
2285 Found = False\r
2286 for FuncDef in FuncDefSet:\r
2287 if StartLine == FuncDef[1] and StartColumn > FuncDef[2] and EndLine == FuncDef[3] and EndColumn < FuncDef[4]:\r
2288 Found = True\r
2289 break\r
2290 if StartLine > FuncDef[1] and EndLine < FuncDef[3]:\r
2291 Found = True\r
2292 break\r
2293 if StartLine == FuncDef[1] and StartColumn > FuncDef[2] and EndLine < FuncDef[3]:\r
2294 Found = True\r
2295 break\r
2296 if StartLine > FuncDef[1] and EndLine == FuncDef[3] and EndColumn < FuncDef[4]:\r
2297 Found = True\r
2298 break\r
2299 if Found:\r
2300 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMENT_FORMAT, '', FileTable, Result[1])\r
2301\r
2302\r
2303def CheckFileHeaderDoxygenComments(FullFileName):\r
2304 ErrorMsgList = []\r
52302d4d 2305\r
30fdf114
LG
2306 FileID = GetTableID(FullFileName, ErrorMsgList)\r
2307 if FileID < 0:\r
2308 return ErrorMsgList\r
52302d4d 2309\r
30fdf114
LG
2310 Db = GetDB()\r
2311 FileTable = 'Identifier' + str(FileID)\r
2312 SqlStatement = """ select Value, ID\r
2313 from %s\r
e56468c0 2314 where Model = %d and (StartLine = 1 or StartLine = 7 or StartLine = 8) and StartColumn = 0\r
30fdf114
LG
2315 """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT)\r
2316 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2317 if len(ResultSet) == 0:\r
d0acc87a 2318 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'No File License header appear at the very beginning of file.', 'File', FileID)\r
30fdf114 2319 return ErrorMsgList\r
52302d4d 2320\r
d0acc87a
LG
2321 NoHeaderCommentStartFlag = True\r
2322 NoHeaderCommentEndFlag = True\r
2323 NoHeaderCommentPeriodFlag = True\r
2324 NoCopyrightFlag = True\r
2325 NoLicenseFlag = True\r
2326 NoRevReferFlag = True\r
2327 NextLineIndex = 0\r
30fdf114 2328 for Result in ResultSet:\r
d0acc87a
LG
2329 FileStartFlag = False\r
2330 CommentStrList = []\r
e56468c0 2331 CommentStr = Result[0].strip()\r
d0acc87a
LG
2332 CommentStrListTemp = CommentStr.split('\n')\r
2333 if (len(CommentStrListTemp) <= 1):\r
2334 # For Mac\r
2335 CommentStrListTemp = CommentStr.split('\r')\r
2336 # Skip the content before the file header \r
2337 for CommentLine in CommentStrListTemp:\r
2338 if CommentLine.strip().startswith('/** @file'):\r
2339 FileStartFlag = True\r
2340 if FileStartFlag == True:\r
2341 CommentStrList.append(CommentLine)\r
2342 \r
e56468c0 2343 ID = Result[1]\r
d0acc87a
LG
2344 Index = 0\r
2345 if CommentStrList and CommentStrList[0].strip().startswith('/** @file'):\r
2346 NoHeaderCommentStartFlag = False\r
2347 else:\r
2348 continue\r
2349 if CommentStrList and CommentStrList[-1].strip().endswith('**/'):\r
2350 NoHeaderCommentEndFlag = False\r
2351 else:\r
2352 continue\r
2353\r
2354 for CommentLine in CommentStrList:\r
2355 Index = Index + 1\r
2356 NextLineIndex = Index\r
2357 if CommentLine.startswith('/** @file'):\r
2358 continue\r
2359 if CommentLine.startswith('**/'):\r
2360 break\r
2361 # Check whether C File header Comment content start with two spaces.\r
2362 if EccGlobalData.gConfig.HeaderCheckCFileCommentStartSpacesNum == '1' or EccGlobalData.gConfig.HeaderCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
2363 if CommentLine.startswith('/** @file') == False and CommentLine.startswith('**/') == False and CommentLine.strip() and CommentLine.startswith(' ') == False:\r
2364 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment content should start with two spaces at each line', FileTable, ID)\r
2365 \r
2366 CommentLine = CommentLine.strip()\r
2367 if CommentLine.startswith('Copyright'):\r
2368 NoCopyrightFlag = False\r
2369 if CommentLine.find('All rights reserved') == -1:\r
d77cc206
HC
2370 for Copyright in EccGlobalData.gConfig.Copyright:\r
2371 if CommentLine.find(Copyright) > -1:\r
2372 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, '""All rights reserved"" announcement should be following the ""Copyright"" at the same line', FileTable, ID)\r
2373 break\r
d0acc87a
LG
2374 if CommentLine.endswith('<BR>') == -1:\r
2375 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'The ""<BR>"" at the end of the Copyright line is required', FileTable, ID)\r
2376 if NextLineIndex < len(CommentStrList) and CommentStrList[NextLineIndex].strip().startswith('Copyright') == False and CommentStrList[NextLineIndex].strip():\r
2377 NoLicenseFlag = False\r
2378 if CommentLine.startswith('@par Revision Reference:'):\r
2379 NoRevReferFlag = False\r
2380 RefListFlag = False\r
2381 for RefLine in CommentStrList[NextLineIndex:]:\r
2382 if RefLine.strip() and (NextLineIndex + 1) < len(CommentStrList) and CommentStrList[NextLineIndex+1].strip() and CommentStrList[NextLineIndex+1].strip().startswith('**/') == False:\r
2383 RefListFlag = True\r
2384 if RefLine.strip() == False or RefLine.strip().startswith('**/'):\r
2385 RefListFlag = False\r
2386 break\r
2387 # Check whether C File header Comment's each reference at list should begin with a bullet character.\r
2388 if EccGlobalData.gConfig.HeaderCheckCFileCommentReferenceFormat == '1' or EccGlobalData.gConfig.HeaderCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
2389 if RefListFlag == True:\r
2390 if RefLine.strip() and RefLine.strip().startswith('**/') == False and RefLine.startswith(' -') == False: \r
2391 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'Each reference on a separate line should begin with a bullet character ""-"" ', FileTable, ID) \r
2392 \r
2393 if NoHeaderCommentStartFlag:\r
e56468c0 2394 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FILE_HEADER, 'File header comment should begin with ""/** @file""', FileTable, ID)\r
d0acc87a
LG
2395 return\r
2396 if NoHeaderCommentEndFlag:\r
e56468c0 2397 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment should end with ""**/""', FileTable, ID)\r
d0acc87a
LG
2398 return\r
2399 if NoCopyrightFlag:\r
2400 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment missing the ""Copyright""', FileTable, ID)\r
2401 #Check whether C File header Comment have the License immediately after the ""Copyright"" line.\r
2402 if EccGlobalData.gConfig.HeaderCheckCFileCommentLicenseFormat == '1' or EccGlobalData.gConfig.HeaderCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
2403 if NoLicenseFlag:\r
2404 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment should have the License immediately after the ""Copyright"" line', FileTable, ID)\r
30fdf114
LG
2405\r
2406def CheckFuncHeaderDoxygenComments(FullFileName):\r
2407 ErrorMsgList = []\r
52302d4d 2408\r
30fdf114
LG
2409 FileID = GetTableID(FullFileName, ErrorMsgList)\r
2410 if FileID < 0:\r
2411 return ErrorMsgList\r
52302d4d 2412\r
30fdf114
LG
2413 Db = GetDB()\r
2414 FileTable = 'Identifier' + str(FileID)\r
2415 SqlStatement = """ select Value, StartLine, EndLine, ID\r
2416 from %s\r
2417 where Model = %d\r
2418 """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT)\r
52302d4d 2419\r
30fdf114
LG
2420 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2421 CommentSet = []\r
2422 try:\r
2423 for Result in ResultSet:\r
2424 CommentSet.append(Result)\r
2425 except:\r
2426 print 'Unrecognized chars in comment of file %s', FullFileName\r
52302d4d 2427\r
30fdf114
LG
2428 # Func Decl check\r
2429 SqlStatement = """ select Modifier, Name, StartLine, ID, Value\r
2430 from %s\r
2431 where Model = %d\r
2432 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
2433 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2434 for Result in ResultSet:\r
2435 FuncName = Result[4]\r
2436 FunctionHeaderComment = CheckCommentImmediatelyPrecedeFunctionHeader(Result[1], Result[2], CommentSet)\r
2437 if FunctionHeaderComment:\r
2438 CheckFunctionHeaderConsistentWithDoxygenComment(Result[0], Result[1], Result[2], FunctionHeaderComment[0], FunctionHeaderComment[1], ErrorMsgList, FunctionHeaderComment[3], FileTable)\r
2439 else:\r
2440 if EccGlobalData.gException.IsException(ERROR_HEADER_CHECK_FUNCTION, FuncName):\r
2441 continue\r
2442 ErrorMsgList.append('Line %d :Function %s has NO comment immediately preceding it.' % (Result[2], Result[1]))\r
2443 PrintErrorMsg(ERROR_HEADER_CHECK_FUNCTION, 'Function [%s] has NO comment immediately preceding it.' % (FuncName), FileTable, Result[3])\r
52302d4d 2444\r
30fdf114
LG
2445 # Func Def check\r
2446 SqlStatement = """ select Value, StartLine, EndLine, ID\r
2447 from %s\r
2448 where Model = %d\r
2449 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER)\r
52302d4d 2450\r
30fdf114
LG
2451 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2452 CommentSet = []\r
2453 try:\r
2454 for Result in ResultSet:\r
2455 CommentSet.append(Result)\r
2456 except:\r
2457 print 'Unrecognized chars in comment of file %s', FullFileName\r
52302d4d 2458\r
30fdf114
LG
2459 SqlStatement = """ select Modifier, Header, StartLine, ID, Name\r
2460 from Function\r
2461 where BelongsToFile = %d\r
2462 """ % (FileID)\r
2463 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2464 for Result in ResultSet:\r
2465 FuncName = Result[4]\r
2466 FunctionHeaderComment = CheckCommentImmediatelyPrecedeFunctionHeader(Result[1], Result[2], CommentSet)\r
2467 if FunctionHeaderComment:\r
2468 CheckFunctionHeaderConsistentWithDoxygenComment(Result[0], Result[1], Result[2], FunctionHeaderComment[0], FunctionHeaderComment[1], ErrorMsgList, FunctionHeaderComment[3], FileTable)\r
2469 else:\r
2470 if EccGlobalData.gException.IsException(ERROR_HEADER_CHECK_FUNCTION, FuncName):\r
2471 continue\r
2472 ErrorMsgList.append('Line %d :Function [%s] has NO comment immediately preceding it.' % (Result[2], Result[1]))\r
2473 PrintErrorMsg(ERROR_HEADER_CHECK_FUNCTION, 'Function [%s] has NO comment immediately preceding it.' % (FuncName), 'Function', Result[3])\r
2474 return ErrorMsgList\r
2475\r
2476def CheckCommentImmediatelyPrecedeFunctionHeader(FuncName, FuncStartLine, CommentSet):\r
2477\r
2478 for Comment in CommentSet:\r
2479 if Comment[2] == FuncStartLine - 1:\r
2480 return Comment\r
2481 return None\r
2482\r
2483def GetDoxygenStrFromComment(Str):\r
2484 DoxygenStrList = []\r
2485 ParamTagList = Str.split('@param')\r
2486 if len(ParamTagList) > 1:\r
2487 i = 1\r
2488 while i < len(ParamTagList):\r
2489 DoxygenStrList.append('@param' + ParamTagList[i])\r
2490 i += 1\r
52302d4d 2491\r
30fdf114 2492 Str = ParamTagList[0]\r
52302d4d 2493\r
30fdf114
LG
2494 RetvalTagList = ParamTagList[-1].split('@retval')\r
2495 if len(RetvalTagList) > 1:\r
2496 if len(ParamTagList) > 1:\r
2497 DoxygenStrList[-1] = '@param' + RetvalTagList[0]\r
2498 i = 1\r
2499 while i < len(RetvalTagList):\r
2500 DoxygenStrList.append('@retval' + RetvalTagList[i])\r
2501 i += 1\r
52302d4d 2502\r
30fdf114
LG
2503 ReturnTagList = RetvalTagList[-1].split('@return')\r
2504 if len(ReturnTagList) > 1:\r
2505 if len(RetvalTagList) > 1:\r
2506 DoxygenStrList[-1] = '@retval' + ReturnTagList[0]\r
2507 elif len(ParamTagList) > 1:\r
2508 DoxygenStrList[-1] = '@param' + ReturnTagList[0]\r
2509 i = 1\r
2510 while i < len(ReturnTagList):\r
2511 DoxygenStrList.append('@return' + ReturnTagList[i])\r
2512 i += 1\r
52302d4d 2513\r
30fdf114
LG
2514 if len(DoxygenStrList) > 0:\r
2515 DoxygenStrList[-1] = DoxygenStrList[-1].rstrip('--*/')\r
52302d4d 2516\r
30fdf114 2517 return DoxygenStrList\r
52302d4d 2518\r
79b74a03 2519def CheckGeneralDoxygenCommentLayout(Str, StartLine, ErrorMsgList, CommentId= -1, TableName=''):\r
30fdf114
LG
2520 #/** --*/ @retval after @param\r
2521 if not Str.startswith('/**'):\r
2522 ErrorMsgList.append('Line %d : Comment does NOT have prefix /** ' % StartLine)\r
2523 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'Comment does NOT have prefix /** ', TableName, CommentId)\r
2524 if not Str.endswith('**/'):\r
2525 ErrorMsgList.append('Line %d : Comment does NOT have tail **/ ' % StartLine)\r
2526 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'Comment does NOT have tail **/ ', TableName, CommentId)\r
2527 FirstRetvalIndex = Str.find('@retval')\r
2528 LastParamIndex = Str.rfind('@param')\r
2529 if (FirstRetvalIndex > 0) and (LastParamIndex > 0) and (FirstRetvalIndex < LastParamIndex):\r
2530 ErrorMsgList.append('Line %d : @retval appear before @param ' % StartLine)\r
2531 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, @retval appear before @param ', TableName, CommentId)\r
52302d4d 2532\r
79b74a03 2533def CheckFunctionHeaderConsistentWithDoxygenComment(FuncModifier, FuncHeader, FuncStartLine, CommentStr, CommentStartLine, ErrorMsgList, CommentId= -1, TableName=''):\r
52302d4d
LG
2534\r
2535 ParamList = GetParamList(FuncHeader)\r
30fdf114
LG
2536 CheckGeneralDoxygenCommentLayout(CommentStr, CommentStartLine, ErrorMsgList, CommentId, TableName)\r
2537 DescriptionStr = CommentStr\r
2538 DoxygenStrList = GetDoxygenStrFromComment(DescriptionStr)\r
2539 if DescriptionStr.find('.') == -1:\r
2540 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMENT_DESCRIPTION, 'Comment description should end with period \'.\'', TableName, CommentId)\r
2541 DoxygenTagNumber = len(DoxygenStrList)\r
2542 ParamNumber = len(ParamList)\r
2543 for Param in ParamList:\r
2544 if Param.Name.upper() == 'VOID' and ParamNumber == 1:\r
2545 ParamNumber -= 1\r
2546 Index = 0\r
2547 if ParamNumber > 0 and DoxygenTagNumber > 0:\r
2548 while Index < ParamNumber and Index < DoxygenTagNumber:\r
2549 ParamModifier = ParamList[Index].Modifier\r
2550 ParamName = ParamList[Index].Name.strip()\r
2551 Tag = DoxygenStrList[Index].strip(' ')\r
2552 if (not Tag[-1] == ('\n')) and (not Tag[-1] == ('\r')):\r
79b74a03
LG
2553 ErrorMsgList.append('Line %d : in Comment, <%s> does NOT end with new line ' % (CommentStartLine, Tag.replace('\n', '').replace('\r', '')))\r
2554 PrintErrorMsg(ERROR_HEADER_CHECK_FUNCTION, 'in Comment, <%s> does NOT end with new line ' % (Tag.replace('\n', '').replace('\r', '')), TableName, CommentId)\r
30fdf114
LG
2555 TagPartList = Tag.split()\r
2556 if len(TagPartList) < 2:\r
79b74a03
LG
2557 ErrorMsgList.append('Line %d : in Comment, <%s> does NOT contain doxygen contents ' % (CommentStartLine, Tag.replace('\n', '').replace('\r', '')))\r
2558 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, <%s> does NOT contain doxygen contents ' % (Tag.replace('\n', '').replace('\r', '')), TableName, CommentId)\r
30fdf114
LG
2559 Index += 1\r
2560 continue\r
2561 LBPos = Tag.find('[')\r
2562 RBPos = Tag.find(']')\r
2563 ParamToLBContent = Tag[len('@param'):LBPos].strip()\r
79b74a03 2564 if LBPos > 0 and len(ParamToLBContent) == 0 and RBPos > LBPos:\r
30fdf114
LG
2565 InOutStr = ''\r
2566 ModifierPartList = ParamModifier.split()\r
2567 for Part in ModifierPartList:\r
2568 if Part.strip() == 'IN':\r
2569 InOutStr += 'in'\r
2570 if Part.strip() == 'OUT':\r
52302d4d 2571 if InOutStr != '':\r
30fdf114
LG
2572 InOutStr += ', out'\r
2573 else:\r
2574 InOutStr = 'out'\r
52302d4d 2575\r
30fdf114 2576 if InOutStr != '':\r
79b74a03
LG
2577 if Tag.find('[' + InOutStr + ']') == -1:\r
2578 if InOutStr != 'in, out':\r
2579 ErrorMsgList.append('Line %d : in Comment, <%s> does NOT have %s ' % (CommentStartLine, (TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), '[' + InOutStr + ']'))\r
2580 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
2581 else:\r
2582 if Tag.find('[in,out]') == -1:\r
2583 ErrorMsgList.append('Line %d : in Comment, <%s> does NOT have %s ' % (CommentStartLine, (TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), '[' + InOutStr + ']'))\r
2584 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
2585\r
2586\r
30fdf114 2587 if Tag.find(ParamName) == -1 and ParamName != 'VOID' and ParamName != 'void':\r
79b74a03
LG
2588 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
2589 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 2590 Index += 1\r
52302d4d 2591\r
30fdf114
LG
2592 if Index < ParamNumber:\r
2593 ErrorMsgList.append('Line %d : Number of doxygen tags in comment less than number of function parameters' % CommentStartLine)\r
2594 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'Number of doxygen tags in comment less than number of function parameters ', TableName, CommentId)\r
2595 # VOID return type, NOT VOID*. VOID* should be matched with a doxygen tag.\r
2596 if (FuncModifier.find('VOID') != -1 or FuncModifier.find('void') != -1) and FuncModifier.find('*') == -1:\r
52302d4d 2597\r
30fdf114
LG
2598 # assume we allow a return description tag for void func. return. that's why 'DoxygenTagNumber - 1' is used instead of 'DoxygenTagNumber'\r
2599 if Index < DoxygenTagNumber - 1 or (Index < DoxygenTagNumber and DoxygenStrList[Index].startswith('@retval')):\r
2600 ErrorMsgList.append('Line %d : VOID return type need NO doxygen tags in comment' % CommentStartLine)\r
2601 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'VOID return type need no doxygen tags in comment ', TableName, CommentId)\r
2602 else:\r
52302d4d 2603 if Index < DoxygenTagNumber and not DoxygenStrList[Index].startswith('@retval') and not DoxygenStrList[Index].startswith('@return'):\r
30fdf114
LG
2604 ErrorMsgList.append('Line %d : Number of @param doxygen tags in comment does NOT match number of function parameters' % CommentStartLine)\r
2605 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'Number of @param doxygen tags in comment does NOT match number of function parameters ', TableName, CommentId)\r
2606 else:\r
2607 if ParamNumber == 0 and DoxygenTagNumber != 0 and ((FuncModifier.find('VOID') != -1 or FuncModifier.find('void') != -1) and FuncModifier.find('*') == -1):\r
2608 ErrorMsgList.append('Line %d : VOID return type need NO doxygen tags in comment' % CommentStartLine)\r
2609 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'VOID return type need NO doxygen tags in comment ', TableName, CommentId)\r
2610 if ParamNumber != 0 and DoxygenTagNumber == 0:\r
2611 ErrorMsgList.append('Line %d : No doxygen tags in comment' % CommentStartLine)\r
2612 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'No doxygen tags in comment ', TableName, CommentId)\r
2613\r
2614if __name__ == '__main__':\r
2615\r
2616# EdkLogger.Initialize()\r
2617# EdkLogger.SetLevel(EdkLogger.QUIET)\r
52302d4d 2618# CollectSourceCodeDataIntoDB(sys.argv[1])\r
b36d134f
LG
2619 try:\r
2620 test_file = sys.argv[1]\r
2621 except IndexError, v:\r
2622 print "Usage: %s filename" % sys.argv[0]\r
2623 sys.exit(1)\r
2624 MsgList = CheckFuncHeaderDoxygenComments(test_file)\r
30fdf114
LG
2625 for Msg in MsgList:\r
2626 print Msg\r
2627 print 'Done!'\r