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