5 import CodeFragmentCollector
7 from CommonDataClass
import DataClass
9 from Common
import EdkLogger
10 from EccToolError
import *
14 IncludeFileListDict
= {}
15 AllIncludeFileListDict
= {}
16 IncludePathListDict
= {}
19 IgnoredKeywordList
= ['EFI_ERROR']
21 def GetIgnoredDirListPattern():
22 skipList
= list(EccGlobalData
.gConfig
.SkipDirList
) + ['.svn']
23 DirString
= string
.join(skipList
, '|')
24 p
= re
.compile(r
'.*[\\/](?:%s)[\\/]?.*' % DirString
)
27 def GetFuncDeclPattern():
28 p
= re
.compile(r
'(?:EFIAPI|EFI_BOOT_SERVICE|EFI_RUNTIME_SERVICE)?\s*[_\w]+\s*\(.*\)$', re
.DOTALL
)
31 def GetArrayPattern():
32 p
= re
.compile(r
'[_\w]*\s*[\[.*\]]+')
35 def GetTypedefFuncPointerPattern():
36 p
= re
.compile('[_\w\s]*\([\w\s]*\*+\s*[_\w]+\s*\)\s*\(.*\)', re
.DOTALL
)
40 return EccGlobalData
.gDb
43 return EccGlobalData
.gConfig
45 def PrintErrorMsg(ErrorType
, Msg
, TableName
, ItemId
):
46 Msg
= Msg
.replace('\n', '').replace('\r', '')
47 MsgPartList
= Msg
.split()
49 for Part
in MsgPartList
:
52 GetDB().TblReport
.Insert(ErrorType
, OtherMsg
= Msg
, BelongsToTable
= TableName
, BelongsToItem
= ItemId
)
55 Type
= DataClass
.MODEL_UNKNOWN
56 Str
= Str
.replace('#', '# ')
58 if List
[1] == 'include':
59 Type
= DataClass
.MODEL_IDENTIFIER_INCLUDE
60 elif List
[1] == 'define':
61 Type
= DataClass
.MODEL_IDENTIFIER_MACRO_DEFINE
62 elif List
[1] == 'ifdef':
63 Type
= DataClass
.MODEL_IDENTIFIER_MACRO_IFDEF
64 elif List
[1] == 'ifndef':
65 Type
= DataClass
.MODEL_IDENTIFIER_MACRO_IFNDEF
66 elif List
[1] == 'endif':
67 Type
= DataClass
.MODEL_IDENTIFIER_MACRO_ENDIF
68 elif List
[1] == 'pragma':
69 Type
= DataClass
.MODEL_IDENTIFIER_MACRO_PROGMA
71 Type
= DataClass
.MODEL_UNKNOWN
74 def SuOccurInTypedef (Su
, TdList
):
76 if Su
.StartPos
[0] == Td
.StartPos
[0] and Su
.EndPos
[0] == Td
.EndPos
[0]:
80 def GetIdentifierList():
82 for comment
in FileProfile
.CommentList
:
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])
84 IdList
.append(IdComment
)
86 for pp
in FileProfile
.PPDirectiveList
:
87 Type
= GetIdType(pp
.Content
)
88 IdPP
= DataClass
.IdentifierClass(-1, '', '', '', pp
.Content
, Type
, -1, -1, pp
.StartPos
[0],pp
.StartPos
[1],pp
.EndPos
[0],pp
.EndPos
[1])
91 for pe
in FileProfile
.PredicateExpressionList
:
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])
95 FuncDeclPattern
= GetFuncDeclPattern()
96 ArrayPattern
= GetArrayPattern()
97 for var
in FileProfile
.VariableDeclarationList
:
98 DeclText
= var
.Declarator
.lstrip()
99 FuncPointerPattern
= GetTypedefFuncPointerPattern()
100 if FuncPointerPattern
.match(DeclText
):
102 VarNameStartLine
= var
.NameStartPos
[0]
103 VarNameStartColumn
= var
.NameStartPos
[1]
104 FirstChar
= DeclText
[0]
105 while not FirstChar
.isalpha() and FirstChar
!= '_':
108 VarNameStartColumn
+= 1
109 DeclText
= DeclText
.lstrip('*')
110 elif FirstChar
== '\r':
111 DeclText
= DeclText
.lstrip('\r\n').lstrip('\r')
112 VarNameStartLine
+= 1
113 VarNameStartColumn
= 0
114 elif FirstChar
== '\n':
115 DeclText
= DeclText
.lstrip('\n')
116 VarNameStartLine
+= 1
117 VarNameStartColumn
= 0
118 elif FirstChar
== ' ':
119 DeclText
= DeclText
.lstrip(' ')
120 VarNameStartColumn
+= 1
121 elif FirstChar
== '\t':
122 DeclText
= DeclText
.lstrip('\t')
123 VarNameStartColumn
+= 8
125 DeclText
= DeclText
[1:]
126 VarNameStartColumn
+= 1
127 FirstChar
= DeclText
[0]
129 var
.Declarator
= DeclText
130 if FuncDeclPattern
.match(var
.Declarator
):
131 DeclSplitList
= var
.Declarator
.split('(')
132 FuncName
= DeclSplitList
[0].strip()
133 FuncNamePartList
= FuncName
.split()
134 if len(FuncNamePartList
) > 1:
135 FuncName
= FuncNamePartList
[-1].strip()
136 NameStart
= DeclSplitList
[0].rfind(FuncName
)
137 var
.Declarator
= var
.Declarator
[NameStart
:]
139 var
.Modifier
+= ' ' + DeclSplitList
[0][0:NameStart
]
142 while Index
< NameStart
:
143 FirstChar
= DeclSplitList
[0][Index
]
144 if DeclSplitList
[0][Index
:].startswith('EFIAPI'):
146 VarNameStartColumn
+= 6
149 elif FirstChar
== '\r':
151 VarNameStartLine
+= 1
152 VarNameStartColumn
= 0
153 elif FirstChar
== '\n':
156 VarNameStartLine
+= 1
157 VarNameStartColumn
= 0
158 elif FirstChar
== ' ':
160 VarNameStartColumn
+= 1
161 elif FirstChar
== '\t':
163 VarNameStartColumn
+= 8
166 VarNameStartColumn
+= 1
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
)
172 if var
.Declarator
.find('{') == -1:
173 for decl
in var
.Declarator
.split(','):
174 DeclList
= decl
.split('=')
175 Name
= DeclList
[0].strip()
176 if ArrayPattern
.match(Name
):
177 LSBPos
= var
.Declarator
.find('[')
178 var
.Modifier
+= ' ' + Name
[LSBPos
:]
179 Name
= Name
[0:LSBPos
]
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
)
184 DeclList
= var
.Declarator
.split('=')
185 Name
= DeclList
[0].strip()
186 if ArrayPattern
.match(Name
):
187 LSBPos
= var
.Declarator
.find('[')
188 var
.Modifier
+= ' ' + Name
[LSBPos
:]
189 Name
= Name
[0:LSBPos
]
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
)
193 for enum
in FileProfile
.EnumerationDefinitionList
:
194 LBPos
= enum
.Content
.find('{')
195 RBPos
= enum
.Content
.find('}')
196 Name
= enum
.Content
[4:LBPos
].strip()
197 Value
= enum
.Content
[LBPos
+1:RBPos
]
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])
199 IdList
.append(IdEnum
)
201 for su
in FileProfile
.StructUnionDefinitionList
:
202 if SuOccurInTypedef(su
, FileProfile
.TypedefDefinitionList
):
204 Type
= DataClass
.MODEL_IDENTIFIER_STRUCTURE
206 if su
.Content
.startswith('union'):
207 Type
= DataClass
.MODEL_IDENTIFIER_UNION
209 LBPos
= su
.Content
.find('{')
210 RBPos
= su
.Content
.find('}')
211 if LBPos
== -1 or RBPos
== -1:
212 Name
= su
.Content
[SkipLen
:].strip()
215 Name
= su
.Content
[SkipLen
:LBPos
].strip()
216 Value
= su
.Content
[LBPos
:RBPos
+1]
217 IdPE
= DataClass
.IdentifierClass(-1, '', '', Name
, Value
, Type
, -1, -1, su
.StartPos
[0],su
.StartPos
[1],su
.EndPos
[0],su
.EndPos
[1])
220 TdFuncPointerPattern
= GetTypedefFuncPointerPattern()
221 for td
in FileProfile
.TypedefDefinitionList
:
225 if TdFuncPointerPattern
.match(td
.ToType
):
226 Modifier
= td
.FromType
227 LBPos
= td
.ToType
.find('(')
228 TmpStr
= td
.ToType
[LBPos
+1:].strip()
229 StarPos
= TmpStr
.find('*')
231 Modifier
+= ' ' + TmpStr
[0:StarPos
]
232 while TmpStr
[StarPos
] == '*':
233 # Modifier += ' ' + '*'
235 TmpStr
= TmpStr
[StarPos
:].strip()
236 RBPos
= TmpStr
.find(')')
237 Name
= TmpStr
[0:RBPos
]
238 Value
= 'FP' + TmpStr
[RBPos
+ 1:]
240 while Name
.startswith('*'):
242 Name
= Name
.lstrip('*').strip()
244 if Name
.find('[') != -1:
245 LBPos
= Name
.find('[')
246 RBPos
= Name
.rfind(']')
247 Value
+= Name
[LBPos
: RBPos
+ 1]
248 Name
= Name
[0 : LBPos
]
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])
253 for funcCall
in FileProfile
.FunctionCallingList
:
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])
258 def StripNonAlnumChars(Str
):
265 def GetParamList(FuncDeclarator
, FuncNameLine
= 0, FuncNameOffset
= 0):
266 FuncDeclarator
= StripComments(FuncDeclarator
)
268 #DeclSplitList = FuncDeclarator.split('(')
269 LBPos
= FuncDeclarator
.find('(')
270 #if len(DeclSplitList) < 2:
273 #FuncName = DeclSplitList[0]
274 FuncName
= FuncDeclarator
[0:LBPos
]
275 #ParamStr = DeclSplitList[1].rstrip(')')
276 ParamStr
= FuncDeclarator
[LBPos
+ 1:].rstrip(')')
279 TailChar
= FuncName
[-1]
280 while not TailChar
.isalpha() and TailChar
!= '_':
283 FuncName
= FuncName
.rstrip('\r\n').rstrip('\n')
286 elif TailChar
== '\r':
287 FuncName
= FuncName
.rstrip('\r')
290 elif TailChar
== ' ':
291 FuncName
= FuncName
.rstrip(' ')
293 elif TailChar
== '\t':
294 FuncName
= FuncName
.rstrip('\t')
297 FuncName
= FuncName
[:-1]
298 TailChar
= FuncName
[-1]
300 OffsetSkipped
+= 1 #skip '('
302 for p
in ParamStr
.split(','):
306 ParamName
= ListP
[-1]
307 DeclText
= ParamName
.strip()
308 RightSpacePos
= p
.rfind(ParamName
)
309 ParamModifier
= p
[0:RightSpacePos
]
310 if ParamName
== 'OPTIONAL':
311 if ParamModifier
== '':
312 ParamModifier
+= ' ' + 'OPTIONAL'
315 ParamName
= ListP
[-2]
316 DeclText
= ParamName
.strip()
317 RightSpacePos
= p
.rfind(ParamName
)
318 ParamModifier
= p
[0:RightSpacePos
]
319 ParamModifier
+= 'OPTIONAL'
320 while DeclText
.startswith('*'):
321 ParamModifier
+= ' ' + '*'
322 DeclText
= DeclText
.lstrip('*').strip()
324 # ignore array length if exists.
325 LBIndex
= ParamName
.find('[')
327 ParamName
= ParamName
[0:LBIndex
]
329 Start
= RightSpacePos
335 if FirstChar
== '\r':
339 elif FirstChar
== '\n':
344 elif FirstChar
== ' ':
347 elif FirstChar
== '\t':
355 ParamBeginLine
= FuncNameLine
+ LineSkipped
356 ParamBeginOffset
= FuncNameOffset
+ OffsetSkipped
358 Index
= Start
+ len(ParamName
)
360 while Index
< len(p
):
363 if FirstChar
== '\r':
367 elif FirstChar
== '\n':
372 elif FirstChar
== ' ':
375 elif FirstChar
== '\t':
383 ParamEndLine
= FuncNameLine
+ LineSkipped
384 ParamEndOffset
= FuncNameOffset
+ OffsetSkipped
385 if ParamName
!= '...':
386 ParamName
= StripNonAlnumChars(ParamName
)
387 IdParam
= DataClass
.IdentifierClass(-1, ParamModifier
, '', ParamName
, '', DataClass
.MODEL_IDENTIFIER_PARAMETER
, -1, -1, ParamBeginLine
, ParamBeginOffset
, ParamEndLine
, ParamEndOffset
)
388 ParamIdList
.append(IdParam
)
390 OffsetSkipped
+= 1 #skip ','
394 def GetFunctionList():
396 for FuncDef
in FileProfile
.FunctionDefinitionList
:
398 DeclText
= FuncDef
.Declarator
.lstrip()
399 FuncNameStartLine
= FuncDef
.NamePos
[0]
400 FuncNameStartColumn
= FuncDef
.NamePos
[1]
401 FirstChar
= DeclText
[0]
402 while not FirstChar
.isalpha() and FirstChar
!= '_':
404 FuncDef
.Modifier
+= '*'
405 FuncNameStartColumn
+= 1
406 DeclText
= DeclText
.lstrip('*')
407 elif FirstChar
== '\r':
408 DeclText
= DeclText
.lstrip('\r\n').lstrip('\r')
409 FuncNameStartLine
+= 1
410 FuncNameStartColumn
= 0
411 elif FirstChar
== '\n':
412 DeclText
= DeclText
.lstrip('\n')
413 FuncNameStartLine
+= 1
414 FuncNameStartColumn
= 0
415 elif FirstChar
== ' ':
416 DeclText
= DeclText
.lstrip(' ')
417 FuncNameStartColumn
+= 1
418 elif FirstChar
== '\t':
419 DeclText
= DeclText
.lstrip('\t')
420 FuncNameStartColumn
+= 8
422 DeclText
= DeclText
[1:]
423 FuncNameStartColumn
+= 1
424 FirstChar
= DeclText
[0]
426 FuncDef
.Declarator
= DeclText
427 DeclSplitList
= FuncDef
.Declarator
.split('(')
428 if len(DeclSplitList
) < 2:
431 FuncName
= DeclSplitList
[0]
432 FuncNamePartList
= FuncName
.split()
433 if len(FuncNamePartList
) > 1:
434 FuncName
= FuncNamePartList
[-1]
435 NameStart
= DeclSplitList
[0].rfind(FuncName
)
437 FuncDef
.Modifier
+= ' ' + DeclSplitList
[0][0:NameStart
]
440 while Index
< NameStart
:
441 FirstChar
= DeclSplitList
[0][Index
]
442 if DeclSplitList
[0][Index
:].startswith('EFIAPI'):
444 FuncNameStartColumn
+= 6
447 elif FirstChar
== '\r':
449 FuncNameStartLine
+= 1
450 FuncNameStartColumn
= 0
451 elif FirstChar
== '\n':
454 FuncNameStartLine
+= 1
455 FuncNameStartColumn
= 0
456 elif FirstChar
== ' ':
458 FuncNameStartColumn
+= 1
459 elif FirstChar
== '\t':
461 FuncNameStartColumn
+= 8
464 FuncNameStartColumn
+= 1
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
)
468 FuncObjList
.append(FuncObj
)
472 def GetFileModificationTimeFromDB(FullFileName
):
475 SqlStatement
= """ select TimeStamp
477 where FullPath = \'%s\'
479 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
480 for Result
in ResultSet
:
481 TimeValue
= Result
[0]
484 def CollectSourceCodeDataIntoDB(RootDir
):
486 tuple = os
.walk(RootDir
)
487 IgnoredPattern
= GetIgnoredDirListPattern()
488 ParseErrorFileList
= []
490 for dirpath
, dirnames
, filenames
in tuple:
491 if IgnoredPattern
.match(dirpath
.upper()):
495 Dirname
= os
.path
.join(dirpath
, Dir
)
496 if os
.path
.islink(Dirname
):
497 Dirname
= os
.path
.realpath(Dirname
)
498 if os
.path
.isdir(Dirname
):
499 # symlinks to directories are treated as directories
501 dirnames
.append(Dirname
)
504 FullName
= os
.path
.normpath(os
.path
.join(dirpath
, f
))
505 if os
.path
.splitext(f
)[1] in ('.h', '.c'):
506 EdkLogger
.info("Parsing " + FullName
)
507 model
= f
.endswith('c') and DataClass
.MODEL_FILE_C
or DataClass
.MODEL_FILE_H
508 collector
= CodeFragmentCollector
.CodeFragmentCollector(FullName
)
510 collector
.ParseFile()
512 ParseErrorFileList
.append(FullName
)
513 collector
.CleanFileProfileBuffer()
514 collector
.ParseFileWithClearedPPDirective()
515 # collector.PrintFragments()
516 BaseName
= os
.path
.basename(f
)
517 DirName
= os
.path
.dirname(FullName
)
518 Ext
= os
.path
.splitext(f
)[1].lstrip('.')
519 ModifiedTime
= os
.path
.getmtime(FullName
)
520 FileObj
= DataClass
.FileClass(-1, BaseName
, Ext
, DirName
, FullName
, model
, ModifiedTime
, GetFunctionList(), GetIdentifierList(), [])
521 FileObjList
.append(FileObj
)
522 collector
.CleanFileProfileBuffer()
524 if len(ParseErrorFileList
) > 0:
525 EdkLogger
.info("Found unrecoverable error during parsing:\n\t%s\n" % "\n\t".join(ParseErrorFileList
))
528 for file in FileObjList
:
529 Db
.InsertOneFile(file)
531 Db
.UpdateIdentifierBelongsToFunction()
533 def GetTableID(FullFileName
, ErrorMsgList
= None):
534 if ErrorMsgList
== None:
538 SqlStatement
= """ select ID
540 where FullPath like '%s'
543 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
546 for Result
in ResultSet
:
548 ErrorMsgList
.append('Duplicate file ID found in DB for file %s' % FullFileName
)
552 ErrorMsgList
.append('NO file ID found in DB for file %s' % FullFileName
)
556 def GetIncludeFileList(FullFileName
):
557 IFList
= IncludeFileListDict
.get(FullFileName
)
561 FileID
= GetTableID(FullFileName
)
566 FileTable
= 'Identifier' + str(FileID
)
567 SqlStatement
= """ select Value
570 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_INCLUDE
)
571 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
572 IncludeFileListDict
[FullFileName
] = ResultSet
575 def GetFullPathOfIncludeFile(Str
, IncludePathList
):
576 for IncludePath
in IncludePathList
:
577 FullPath
= os
.path
.join(IncludePath
, Str
)
578 FullPath
= os
.path
.normpath(FullPath
)
579 if os
.path
.exists(FullPath
):
583 def GetAllIncludeFiles(FullFileName
):
584 if AllIncludeFileListDict
.get(FullFileName
) != None:
585 return AllIncludeFileListDict
.get(FullFileName
)
587 FileDirName
= os
.path
.dirname(FullFileName
)
588 IncludePathList
= IncludePathListDict
.get(FileDirName
)
589 if IncludePathList
== None:
590 IncludePathList
= MetaDataParser
.GetIncludeListOfFile(EccGlobalData
.gWorkspace
, FullFileName
, GetDB())
591 if FileDirName
not in IncludePathList
:
592 IncludePathList
.insert(0, FileDirName
)
593 IncludePathListDict
[FileDirName
] = IncludePathList
594 IncludeFileQueue
= []
595 for IncludeFile
in GetIncludeFileList(FullFileName
):
596 FileName
= IncludeFile
[0].lstrip('#').strip()
597 FileName
= FileName
.lstrip('include').strip()
598 FileName
= FileName
.strip('\"')
599 FileName
= FileName
.lstrip('<').rstrip('>').strip()
600 FullPath
= GetFullPathOfIncludeFile(FileName
, IncludePathList
)
602 IncludeFileQueue
.append(FullPath
)
605 while i
< len(IncludeFileQueue
):
606 for IncludeFile
in GetIncludeFileList(IncludeFileQueue
[i
]):
607 FileName
= IncludeFile
[0].lstrip('#').strip()
608 FileName
= FileName
.lstrip('include').strip()
609 FileName
= FileName
.strip('\"')
610 FileName
= FileName
.lstrip('<').rstrip('>').strip()
611 FullPath
= GetFullPathOfIncludeFile(FileName
, IncludePathList
)
612 if FullPath
!= None and FullPath
not in IncludeFileQueue
:
613 IncludeFileQueue
.insert(i
+ 1, FullPath
)
616 AllIncludeFileListDict
[FullFileName
] = IncludeFileQueue
617 return IncludeFileQueue
619 def GetPredicateListFromPredicateExpStr(PES
):
626 p
= GetFuncDeclPattern()
627 while i
< len(PES
) - 1:
628 if (PES
[i
].isalnum() or PES
[i
] == '_' or PES
[i
] == '*') and LogicOpPos
> PredicateBegin
:
630 if (PES
[i
] == '&' and PES
[i
+1] == '&') or (PES
[i
] == '|' and PES
[i
+1] == '|'):
632 Exp
= PES
[PredicateBegin
:i
].strip()
633 # Exp may contain '.' or '->'
634 TmpExp
= Exp
.replace('.', '').replace('->', '')
636 PredicateList
.append(Exp
)
638 PredicateList
.append(Exp
.rstrip(';').rstrip(')').strip())
641 if PredicateBegin
> LogicOpPos
:
642 while PredicateBegin
< len(PES
):
643 if PES
[PredicateBegin
].isalnum() or PES
[PredicateBegin
] == '_' or PES
[PredicateBegin
] == '*':
646 Exp
= PES
[PredicateBegin
:len(PES
)].strip()
647 # Exp may contain '.' or '->'
648 TmpExp
= Exp
.replace('.', '').replace('->', '')
650 PredicateList
.append(Exp
)
652 PredicateList
.append(Exp
.rstrip(';').rstrip(')').strip())
655 def GetCNameList(Lvalue
, StarList
= []):
663 while SearchBegin
< len(Lvalue
):
664 while i
< len(Lvalue
):
665 if Lvalue
[i
].isalnum() or Lvalue
[i
] == '_':
671 VarList
.append(Lvalue
[VarStart
:VarEnd
+1])
675 if VarStart
== -1 and Lvalue
[i
] == '*':
682 DotIndex
= Lvalue
[VarEnd
:].find('.')
683 ArrowIndex
= Lvalue
[VarEnd
:].find('->')
684 if DotIndex
== -1 and ArrowIndex
== -1:
686 elif DotIndex
== -1 and ArrowIndex
!= -1:
687 SearchBegin
= VarEnd
+ ArrowIndex
688 elif ArrowIndex
== -1 and DotIndex
!= -1:
689 SearchBegin
= VarEnd
+ DotIndex
691 SearchBegin
= VarEnd
+ ((DotIndex
< ArrowIndex
) and DotIndex
or ArrowIndex
)
699 def SplitPredicateByOp(Str
, Op
, IsFuncCalling
= False):
708 while Index
< len(Str
):
709 while not LBFound
and Str
[Index
] != '_' and not Str
[Index
].isalnum():
712 while not LBFound
and (Str
[Index
].isalnum() or Str
[Index
] == '_'):
714 # maybe type-cast at the begining, skip it.
715 RemainingStr
= Str
[Index
:].lstrip()
716 if RemainingStr
.startswith(')') and not LBFound
:
720 if RemainingStr
.startswith('(') and not LBFound
:
723 if Str
[Index
] == '(':
724 UnmatchedLBCount
+= 1
728 if Str
[Index
] == ')':
729 UnmatchedLBCount
-= 1
731 if UnmatchedLBCount
== 0:
737 if UnmatchedLBCount
> 0:
740 IndexInRemainingStr
= Str
[Index
:].find(Op
)
741 if IndexInRemainingStr
== -1:
744 Name
= Str
[0:Index
+ IndexInRemainingStr
].strip()
745 Value
= Str
[Index
+IndexInRemainingStr
+len(Op
):].strip().strip(')')
748 TmpStr
= Str
.rstrip(';').rstrip(')')
750 Index
= TmpStr
.rfind(Op
)
754 if Str
[Index
- 1].isalnum() or Str
[Index
- 1].isspace() or Str
[Index
- 1] == ')':
755 Name
= Str
[0:Index
].strip()
756 Value
= Str
[Index
+ len(Op
):].strip()
759 TmpStr
= Str
[0:Index
- 1]
761 def SplitPredicateStr(Str
):
763 Str
= Str
.lstrip('(')
764 IsFuncCalling
= False
765 p
= GetFuncDeclPattern()
766 TmpStr
= Str
.replace('.', '').replace('->', '')
770 PredPartList
= SplitPredicateByOp(Str
, '==', IsFuncCalling
)
771 if len(PredPartList
) > 1:
772 return [PredPartList
, '==']
774 PredPartList
= SplitPredicateByOp(Str
, '!=', IsFuncCalling
)
775 if len(PredPartList
) > 1:
776 return [PredPartList
, '!=']
778 PredPartList
= SplitPredicateByOp(Str
, '>=', IsFuncCalling
)
779 if len(PredPartList
) > 1:
780 return [PredPartList
, '>=']
782 PredPartList
= SplitPredicateByOp(Str
, '<=', IsFuncCalling
)
783 if len(PredPartList
) > 1:
784 return [PredPartList
, '<=']
786 PredPartList
= SplitPredicateByOp(Str
, '>', IsFuncCalling
)
787 if len(PredPartList
) > 1:
788 return [PredPartList
, '>']
790 PredPartList
= SplitPredicateByOp(Str
, '<', IsFuncCalling
)
791 if len(PredPartList
) > 1:
792 return [PredPartList
, '<']
794 return [[Str
, None], None]
796 def GetFuncContainsPE(ExpLine
, ResultSet
):
797 for Result
in ResultSet
:
798 if Result
[0] < ExpLine
and Result
[1] > ExpLine
:
802 def PatternInModifier(Modifier
, SubStr
):
803 PartList
= Modifier
.split()
804 for Part
in PartList
:
809 def GetDataTypeFromModifier(ModifierStr
):
810 MList
= ModifierStr
.split()
812 if M
in EccGlobalData
.gConfig
.ModifierList
:
815 if M
.startswith('['):
820 ReturnType
+= M
+ ' '
822 ReturnType
= ReturnType
.strip()
823 if len(ReturnType
) == 0:
827 def DiffModifier(Str1
, Str2
):
828 PartList1
= Str1
.split()
829 PartList2
= Str2
.split()
830 if PartList1
== PartList2
:
835 def GetTypedefDict(FullFileName
):
837 Dict
= ComplexTypeDict
.get(FullFileName
)
841 FileID
= GetTableID(FullFileName
)
842 FileTable
= 'Identifier' + str(FileID
)
844 SqlStatement
= """ select Modifier, Name, Value, ID
847 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_TYPEDEF
)
848 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
851 for Result
in ResultSet
:
852 if len(Result
[0]) == 0:
853 Dict
[Result
[1]] = Result
[2]
855 IncludeFileList
= GetAllIncludeFiles(FullFileName
)
856 for F
in IncludeFileList
:
857 FileID
= GetTableID(F
)
861 FileTable
= 'Identifier' + str(FileID
)
862 SqlStatement
= """ select Modifier, Name, Value, ID
865 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_TYPEDEF
)
866 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
868 for Result
in ResultSet
:
869 if not Result
[2].startswith('FP ('):
870 Dict
[Result
[1]] = Result
[2]
872 if len(Result
[0]) == 0:
873 Dict
[Result
[1]] = 'VOID'
875 Dict
[Result
[1]] = GetDataTypeFromModifier(Result
[0])
877 ComplexTypeDict
[FullFileName
] = Dict
880 def GetSUDict(FullFileName
):
882 Dict
= SUDict
.get(FullFileName
)
886 FileID
= GetTableID(FullFileName
)
887 FileTable
= 'Identifier' + str(FileID
)
889 SqlStatement
= """ select Name, Value, ID
891 where Model = %d or Model = %d
892 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_STRUCTURE
, DataClass
.MODEL_IDENTIFIER_UNION
)
893 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
896 for Result
in ResultSet
:
897 if len(Result
[1]) > 0:
898 Dict
[Result
[0]] = Result
[1]
900 IncludeFileList
= GetAllIncludeFiles(FullFileName
)
901 for F
in IncludeFileList
:
902 FileID
= GetTableID(F
)
906 FileTable
= 'Identifier' + str(FileID
)
907 SqlStatement
= """ select Name, Value, ID
909 where Model = %d or Model = %d
910 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_STRUCTURE
, DataClass
.MODEL_IDENTIFIER_UNION
)
911 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
913 for Result
in ResultSet
:
914 if len(Result
[1]) > 0:
915 Dict
[Result
[0]] = Result
[1]
917 SUDict
[FullFileName
] = Dict
920 def StripComments(Str
):
922 ListFromStr
= list(Str
)
925 DoubleSlashComment
= False
927 while Index
< len(ListFromStr
):
928 # meet new line, then no longer in a comment for //
929 if ListFromStr
[Index
] == '\n':
930 if InComment
and DoubleSlashComment
:
932 DoubleSlashComment
= False
934 # check for */ comment end
935 elif InComment
and not DoubleSlashComment
and ListFromStr
[Index
] == '*' and ListFromStr
[Index
+1] == '/':
936 ListFromStr
[Index
] = ' '
938 ListFromStr
[Index
] = ' '
941 # set comments to spaces
943 ListFromStr
[Index
] = ' '
945 # check for // comment
946 elif ListFromStr
[Index
] == '/' and ListFromStr
[Index
+1] == '/' and ListFromStr
[Index
+2] != '\n':
948 DoubleSlashComment
= True
950 # check for /* comment start
951 elif ListFromStr
[Index
] == '/' and ListFromStr
[Index
+1] == '*':
952 ListFromStr
[Index
] = ' '
954 ListFromStr
[Index
] = ' '
960 # restore from List to String
961 Str
= "".join(ListFromStr
)
962 Str
= Str
.rstrip(' ')
966 def GetFinalTypeValue(Type
, FieldName
, TypedefDict
, SUDict
):
967 Value
= TypedefDict
.get(Type
)
969 Value
= SUDict
.get(Type
)
973 LBPos
= Value
.find('{')
975 FTList
= Value
.split()
977 if FT
not in ('struct', 'union'):
978 Value
= TypedefDict
.get(FT
)
980 Value
= SUDict
.get(FT
)
986 LBPos
= Value
.find('{')
988 # RBPos = Value.find('}')
989 Fields
= Value
[LBPos
+ 1:]
990 Fields
= StripComments(Fields
)
991 FieldsList
= Fields
.split(';')
992 for Field
in FieldsList
:
993 Field
= Field
.strip()
994 Index
= Field
.rfind(FieldName
)
997 if not Field
[Index
- 1].isalnum():
998 if Index
+ len(FieldName
) == len(Field
):
999 Type
= GetDataTypeFromModifier(Field
[0:Index
])
1002 # For the condition that the field in struct is an array with [] sufixes...
1003 if not Field
[Index
+ len(FieldName
)].isalnum():
1004 Type
= GetDataTypeFromModifier(Field
[0:Index
])
1009 def GetRealType(Type
, TypedefDict
, TargetType
= None):
1010 if TargetType
!= None and Type
== TargetType
:
1012 while TypedefDict
.get(Type
):
1013 Type
= TypedefDict
.get(Type
)
1014 if TargetType
!= None and Type
== TargetType
:
1018 def GetTypeInfo(RefList
, Modifier
, FullFileName
, TargetType
= None):
1019 TypedefDict
= GetTypedefDict(FullFileName
)
1020 SUDict
= GetSUDict(FullFileName
)
1021 Type
= GetDataTypeFromModifier(Modifier
).replace('*', '').strip()
1023 Type
= Type
.split()[-1]
1025 while Index
< len(RefList
):
1026 FieldName
= RefList
[Index
]
1027 FromType
= GetFinalTypeValue(Type
, FieldName
, TypedefDict
, SUDict
)
1028 if FromType
== None:
1030 # we want to determine the exact type.
1031 if TargetType
!= None:
1032 Type
= FromType
.split()[0]
1033 # we only want to check if it is a pointer
1036 if Type
.find('*') != -1 and Index
== len(RefList
)-1:
1038 Type
= FromType
.split()[0]
1042 Type
= GetRealType(Type
, TypedefDict
, TargetType
)
1046 def GetVarInfo(PredVarList
, FuncRecord
, FullFileName
, IsFuncCall
= False, TargetType
= None, StarList
= None):
1048 PredVar
= PredVarList
[0]
1049 FileID
= GetTableID(FullFileName
)
1052 FileTable
= 'Identifier' + str(FileID
)
1053 # search variable in include files
1055 # it is a function call, search function declarations and definitions
1057 SqlStatement
= """ select Modifier, ID
1059 where Model = %d and Value = \'%s\'
1060 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_FUNCTION_DECLARATION
, PredVar
)
1061 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1063 for Result
in ResultSet
:
1064 Type
= GetDataTypeFromModifier(Result
[0]).split()[-1]
1065 TypedefDict
= GetTypedefDict(FullFileName
)
1066 Type
= GetRealType(Type
, TypedefDict
, TargetType
)
1069 IncludeFileList
= GetAllIncludeFiles(FullFileName
)
1070 for F
in IncludeFileList
:
1071 FileID
= GetTableID(F
)
1075 FileTable
= 'Identifier' + str(FileID
)
1076 SqlStatement
= """ select Modifier, ID
1078 where Model = %d and Value = \'%s\'
1079 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_FUNCTION_DECLARATION
, PredVar
)
1080 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1082 for Result
in ResultSet
:
1083 Type
= GetDataTypeFromModifier(Result
[0]).split()[-1]
1084 TypedefDict
= GetTypedefDict(FullFileName
)
1085 Type
= GetRealType(Type
, TypedefDict
, TargetType
)
1088 FileID
= GetTableID(FullFileName
)
1089 SqlStatement
= """ select Modifier, ID
1091 where BelongsToFile = %d and Name = \'%s\'
1092 """ % (FileID
, PredVar
)
1093 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1095 for Result
in ResultSet
:
1096 Type
= GetDataTypeFromModifier(Result
[0]).split()[-1]
1097 TypedefDict
= GetTypedefDict(FullFileName
)
1098 Type
= GetRealType(Type
, TypedefDict
, TargetType
)
1101 for F
in IncludeFileList
:
1102 FileID
= GetTableID(F
)
1106 FileTable
= 'Identifier' + str(FileID
)
1107 SqlStatement
= """ select Modifier, ID
1109 where BelongsToFile = %d and Name = \'%s\'
1110 """ % (FileID
, PredVar
)
1111 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1113 for Result
in ResultSet
:
1114 Type
= GetDataTypeFromModifier(Result
[0]).split()[-1]
1115 TypedefDict
= GetTypedefDict(FullFileName
)
1116 Type
= GetRealType(Type
, TypedefDict
, TargetType
)
1121 # really variable, search local variable first
1122 SqlStatement
= """ select Modifier, ID
1124 where Model = %d and Name = \'%s\' and StartLine >= %d and StartLine <= %d
1125 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_VARIABLE
, PredVar
, FuncRecord
[0], FuncRecord
[1])
1126 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1128 for Result
in ResultSet
:
1129 if len(PredVarList
) > 1:
1130 Type
= GetTypeInfo(PredVarList
[1:], Result
[0], FullFileName
, TargetType
)
1133 # Type = GetDataTypeFromModifier(Result[0]).split()[-1]
1134 TypeList
= GetDataTypeFromModifier(Result
[0]).split()
1136 if len(TypeList
) > 1 and StarList
!= None:
1137 for Star
in StarList
:
1139 Type
= Type
.rstrip(Star
)
1140 # Get real type after de-reference pointers.
1141 if len(Type
.strip()) == 0:
1143 TypedefDict
= GetTypedefDict(FullFileName
)
1144 Type
= GetRealType(Type
, TypedefDict
, TargetType
)
1147 # search function parameters second
1148 ParamList
= GetParamList(FuncRecord
[2])
1149 for Param
in ParamList
:
1150 if Param
.Name
.strip() == PredVar
:
1151 if len(PredVarList
) > 1:
1152 Type
= GetTypeInfo(PredVarList
[1:], Param
.Modifier
, FullFileName
, TargetType
)
1155 TypeList
= GetDataTypeFromModifier(Param
.Modifier
).split()
1157 if len(TypeList
) > 1 and StarList
!= None:
1158 for Star
in StarList
:
1160 Type
= Type
.rstrip(Star
)
1161 # Get real type after de-reference pointers.
1162 if len(Type
.strip()) == 0:
1164 TypedefDict
= GetTypedefDict(FullFileName
)
1165 Type
= GetRealType(Type
, TypedefDict
, TargetType
)
1168 # search global variable next
1169 SqlStatement
= """ select Modifier, ID
1171 where Model = %d and Name = \'%s\' and BelongsToFunction = -1
1172 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_VARIABLE
, PredVar
)
1173 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1175 for Result
in ResultSet
:
1176 if len(PredVarList
) > 1:
1177 Type
= GetTypeInfo(PredVarList
[1:], Result
[0], FullFileName
, TargetType
)
1180 TypeList
= GetDataTypeFromModifier(Result
[0]).split()
1182 if len(TypeList
) > 1 and StarList
!= None:
1183 for Star
in StarList
:
1185 Type
= Type
.rstrip(Star
)
1186 # Get real type after de-reference pointers.
1187 if len(Type
.strip()) == 0:
1189 TypedefDict
= GetTypedefDict(FullFileName
)
1190 Type
= GetRealType(Type
, TypedefDict
, TargetType
)
1193 IncludeFileList
= GetAllIncludeFiles(FullFileName
)
1194 for F
in IncludeFileList
:
1195 FileID
= GetTableID(F
)
1199 FileTable
= 'Identifier' + str(FileID
)
1200 SqlStatement
= """ select Modifier, ID
1202 where Model = %d and BelongsToFunction = -1 and Name = \'%s\'
1203 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_VARIABLE
, PredVar
)
1204 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1206 for Result
in ResultSet
:
1207 if len(PredVarList
) > 1:
1208 Type
= GetTypeInfo(PredVarList
[1:], Result
[0], FullFileName
, TargetType
)
1211 TypeList
= GetDataTypeFromModifier(Result
[0]).split()
1213 if len(TypeList
) > 1 and StarList
!= None:
1214 for Star
in StarList
:
1216 Type
= Type
.rstrip(Star
)
1217 # Get real type after de-reference pointers.
1218 if len(Type
.strip()) == 0:
1220 TypedefDict
= GetTypedefDict(FullFileName
)
1221 Type
= GetRealType(Type
, TypedefDict
, TargetType
)
1224 def GetTypeFromArray(Type
, Var
):
1225 Count
= Var
.count('[')
1229 Type
= Type
.rstrip('*')
1234 def CheckFuncLayoutReturnType(FullFileName
):
1237 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
1242 FileTable
= 'Identifier' + str(FileID
)
1243 SqlStatement
= """ select Modifier, ID, StartLine, StartColumn, EndLine, Value
1246 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_FUNCTION_DECLARATION
)
1247 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1248 for Result
in ResultSet
:
1249 ReturnType
= GetDataTypeFromModifier(Result
[0])
1250 TypeStart
= ReturnType
.split()[0]
1251 FuncName
= Result
[5]
1252 if EccGlobalData
.gException
.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE
, FuncName
):
1254 Index
= Result
[0].find(TypeStart
)
1255 if Index
!= 0 or Result
[3] != 0:
1256 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE
, '[%s] Return Type should appear at the start of line' % FuncName
, FileTable
, Result
[1])
1258 if Result
[2] == Result
[4]:
1259 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE
, '[%s] Return Type should appear on its own line' % FuncName
, FileTable
, Result
[1])
1261 SqlStatement
= """ select Modifier, ID, StartLine, StartColumn, FunNameStartLine, Name
1263 where BelongsToFile = %d
1265 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1266 for Result
in ResultSet
:
1267 ReturnType
= GetDataTypeFromModifier(Result
[0])
1268 TypeStart
= ReturnType
.split()[0]
1269 FuncName
= Result
[5]
1270 if EccGlobalData
.gException
.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE
, FuncName
):
1272 Index
= Result
[0].find(ReturnType
)
1273 if Index
!= 0 or Result
[3] != 0:
1274 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE
, '[%s] Return Type should appear at the start of line' % FuncName
, 'Function', Result
[1])
1276 if Result
[2] == Result
[4]:
1277 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE
, '[%s] Return Type should appear on its own line' % FuncName
, 'Function', Result
[1])
1279 def CheckFuncLayoutModifier(FullFileName
):
1282 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
1287 FileTable
= 'Identifier' + str(FileID
)
1288 SqlStatement
= """ select Modifier, ID
1291 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_FUNCTION_DECLARATION
)
1292 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1293 for Result
in ResultSet
:
1294 ReturnType
= GetDataTypeFromModifier(Result
[0])
1295 TypeStart
= ReturnType
.split()[0]
1296 # if len(ReturnType) == 0:
1298 Index
= Result
[0].find(TypeStart
)
1300 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_OPTIONAL_FUNCTIONAL_MODIFIER
, '', FileTable
, Result
[1])
1302 SqlStatement
= """ select Modifier, ID
1304 where BelongsToFile = %d
1306 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1307 for Result
in ResultSet
:
1308 ReturnType
= GetDataTypeFromModifier(Result
[0])
1309 TypeStart
= ReturnType
.split()[0]
1310 # if len(ReturnType) == 0:
1312 Index
= Result
[0].find(TypeStart
)
1314 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_OPTIONAL_FUNCTIONAL_MODIFIER
, '', 'Function', Result
[1])
1316 def CheckFuncLayoutName(FullFileName
):
1318 # Parameter variable format pattern.
1319 Pattern
= re
.compile(r
'^[A-Z]+\S*[a-z]\S*$')
1320 ParamIgnoreList
= ('VOID', '...')
1321 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
1326 FileTable
= 'Identifier' + str(FileID
)
1327 SqlStatement
= """ select Name, ID, EndColumn, Value
1330 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_FUNCTION_DECLARATION
)
1331 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1332 for Result
in ResultSet
:
1333 FuncName
= Result
[3]
1334 if EccGlobalData
.gException
.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME
, FuncName
):
1337 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME
, 'Function name [%s] should appear at the start of a line' % FuncName
, FileTable
, Result
[1])
1338 ParamList
= GetParamList(Result
[0])
1339 if len(ParamList
) == 0:
1342 for Param
in ParamList
:
1343 if Param
.StartLine
<= StartLine
:
1344 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME
, 'Parameter %s should be in its own line.' % Param
.Name
, FileTable
, Result
[1])
1345 if Param
.StartLine
- StartLine
> 1:
1346 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME
, 'Empty line appears before Parameter %s.' % Param
.Name
, FileTable
, Result
[1])
1347 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
):
1348 PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME
, 'Parameter [%s] NOT follow naming convention.' % Param
.Name
, FileTable
, Result
[1])
1349 StartLine
= Param
.StartLine
1351 if not Result
[0].endswith('\n )') and not Result
[0].endswith('\r )'):
1352 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME
, '\')\' should be on a new line and indented two spaces', FileTable
, Result
[1])
1354 SqlStatement
= """ select Modifier, ID, FunNameStartColumn, Name
1356 where BelongsToFile = %d
1358 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1359 for Result
in ResultSet
:
1360 FuncName
= Result
[3]
1361 if EccGlobalData
.gException
.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME
, FuncName
):
1364 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME
, 'Function name [%s] should appear at the start of a line' % FuncName
, 'Function', Result
[1])
1365 ParamList
= GetParamList(Result
[0])
1366 if len(ParamList
) == 0:
1369 for Param
in ParamList
:
1370 if Param
.StartLine
<= StartLine
:
1371 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME
, 'Parameter %s should be in its own line.' % Param
.Name
, 'Function', Result
[1])
1372 if Param
.StartLine
- StartLine
> 1:
1373 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME
, 'Empty line appears before Parameter %s.' % Param
.Name
, 'Function', Result
[1])
1374 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
):
1375 PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME
, 'Parameter [%s] NOT follow naming convention.' % Param
.Name
, FileTable
, Result
[1])
1376 StartLine
= Param
.StartLine
1377 if not Result
[0].endswith('\n )') and not Result
[0].endswith('\r )'):
1378 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME
, '\')\' should be on a new line and indented two spaces', 'Function', Result
[1])
1380 def CheckFuncLayoutPrototype(FullFileName
):
1383 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
1387 FileTable
= 'Identifier' + str(FileID
)
1389 SqlStatement
= """ select Modifier, Header, Name, ID
1391 where BelongsToFile = %d
1393 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1394 if len(ResultSet
) == 0:
1398 for Result
in ResultSet
:
1399 FuncDefList
.append(Result
)
1401 SqlStatement
= """ select Modifier, Name, ID
1404 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_FUNCTION_DECLARATION
)
1405 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1407 for Result
in ResultSet
:
1408 FuncDeclList
.append(Result
)
1411 for FuncDef
in FuncDefList
:
1412 FuncName
= FuncDef
[2].strip()
1413 FuncModifier
= FuncDef
[0]
1414 FuncDefHeader
= FuncDef
[1]
1415 for FuncDecl
in FuncDeclList
:
1416 LBPos
= FuncDecl
[1].find('(')
1417 DeclName
= FuncDecl
[1][0:LBPos
].strip()
1418 DeclModifier
= FuncDecl
[0]
1419 if DeclName
== FuncName
:
1420 if DiffModifier(FuncModifier
, DeclModifier
) and not EccGlobalData
.gException
.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE
, FuncName
):
1421 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE
, 'Function [%s] modifier different with prototype.' % FuncName
, 'Function', FuncDef
[3])
1422 ParamListOfDef
= GetParamList(FuncDefHeader
)
1423 ParamListOfDecl
= GetParamList(FuncDecl
[1])
1424 if len(ParamListOfDef
) != len(ParamListOfDecl
):
1425 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE
, 'Parameter number different.', 'Function', FuncDef
[3])
1429 while Index
< len(ParamListOfDef
):
1430 if DiffModifier(ParamListOfDef
[Index
].Modifier
, ParamListOfDecl
[Index
].Modifier
):
1431 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE
, 'Parameter %s has different modifier with prototype.' % ParamListOfDef
[Index
].Name
, 'Function', FuncDef
[3])
1435 UndeclFuncList
.append(FuncDef
)
1437 IncludeFileList
= GetAllIncludeFiles(FullFileName
)
1439 for F
in IncludeFileList
:
1440 FileID
= GetTableID(F
, ErrorMsgList
)
1444 FileTable
= 'Identifier' + str(FileID
)
1445 SqlStatement
= """ select Modifier, Name, ID
1448 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_FUNCTION_DECLARATION
)
1449 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1451 for Result
in ResultSet
:
1452 FuncDeclList
.append(Result
)
1454 for FuncDef
in UndeclFuncList
:
1455 FuncName
= FuncDef
[2].strip()
1456 FuncModifier
= FuncDef
[0]
1457 FuncDefHeader
= FuncDef
[1]
1458 for FuncDecl
in FuncDeclList
:
1459 LBPos
= FuncDecl
[1].find('(')
1460 DeclName
= FuncDecl
[1][0:LBPos
].strip()
1461 DeclModifier
= FuncDecl
[0]
1462 if DeclName
== FuncName
:
1463 if DiffModifier(FuncModifier
, DeclModifier
) and not EccGlobalData
.gException
.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE
, FuncName
):
1464 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE
, 'Function [%s] modifier different with prototype.' % FuncName
, 'Function', FuncDef
[3])
1465 ParamListOfDef
= GetParamList(FuncDefHeader
)
1466 ParamListOfDecl
= GetParamList(FuncDecl
[1])
1467 if len(ParamListOfDef
) != len(ParamListOfDecl
):
1468 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE
, 'Parameter number different.', 'Function', FuncDef
[3])
1472 while Index
< len(ParamListOfDef
):
1473 if DiffModifier(ParamListOfDef
[Index
].Modifier
, ParamListOfDecl
[Index
].Modifier
):
1474 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE
, 'Parameter %s has different modifier with prototype.' % ParamListOfDef
[Index
].Name
, 'Function', FuncDef
[3])
1478 def CheckFuncLayoutBody(FullFileName
):
1481 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
1485 FileTable
= 'Identifier' + str(FileID
)
1487 SqlStatement
= """ select BodyStartColumn, EndColumn, ID
1489 where BelongsToFile = %d
1491 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1492 if len(ResultSet
) == 0:
1494 for Result
in ResultSet
:
1496 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY
, 'open brace should be at the very beginning of a line.', 'Function', Result
[2])
1498 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY
, 'close brace should be at the very beginning of a line.', 'Function', Result
[2])
1500 def CheckFuncLayoutLocalVariable(FullFileName
):
1503 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
1508 FileTable
= 'Identifier' + str(FileID
)
1509 SqlStatement
= """ select ID
1511 where BelongsToFile = %d
1513 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1514 if len(ResultSet
) == 0:
1517 for Result
in ResultSet
:
1521 SqlStatement
= """ select Name, Value, ID
1523 where Model = %d and BelongsToFunction = %d
1524 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_VARIABLE
, F
[0])
1525 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1526 if len(ResultSet
) == 0:
1529 for Result
in ResultSet
:
1530 if len(Result
[1]) > 0:
1531 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_NO_INIT_OF_VARIABLE
, 'Variable Name: %s' % Result
[0], FileTable
, Result
[2])
1533 def CheckMemberVariableFormat(Name
, Value
, FileTable
, TdId
, ModelId
):
1535 # Member variable format pattern.
1536 Pattern
= re
.compile(r
'^[A-Z]+\S*[a-z]\S*$')
1538 LBPos
= Value
.find('{')
1539 RBPos
= Value
.rfind('}')
1540 if LBPos
== -1 or RBPos
== -1:
1543 Fields
= Value
[LBPos
+ 1 : RBPos
]
1544 Fields
= StripComments(Fields
).strip()
1545 NestPos
= Fields
.find ('struct')
1546 if NestPos
!= -1 and (NestPos
+ len('struct') < len(Fields
)):
1547 if not Fields
[NestPos
+ len('struct') + 1].isalnum():
1548 if not EccGlobalData
.gException
.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE
, Name
):
1549 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE
, 'Nested struct in [%s].' % (Name
), FileTable
, TdId
)
1551 NestPos
= Fields
.find ('union')
1552 if NestPos
!= -1 and (NestPos
+ len('union') < len(Fields
)):
1553 if not Fields
[NestPos
+ len('union') + 1].isalnum():
1554 if not EccGlobalData
.gException
.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE
, Name
):
1555 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE
, 'Nested union in [%s].' % (Name
), FileTable
, TdId
)
1557 NestPos
= Fields
.find ('enum')
1558 if NestPos
!= -1 and (NestPos
+ len('enum') < len(Fields
)):
1559 if not Fields
[NestPos
+ len('enum') + 1].isalnum():
1560 if not EccGlobalData
.gException
.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE
, Name
):
1561 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE
, 'Nested enum in [%s].' % (Name
), FileTable
, TdId
)
1564 if ModelId
== DataClass
.MODEL_IDENTIFIER_ENUMERATE
:
1565 FieldsList
= Fields
.split(',')
1566 # deal with enum is pre-assigned a value by function call ( , , , ...)
1569 RemoveCurrentElement
= False
1570 while Index
< len(FieldsList
):
1571 Field
= FieldsList
[Index
]
1573 if Field
.find('(') != -1:
1575 RemoveCurrentElement
= True
1579 if Field
.find(')') != -1 and QuoteCount
> 0:
1582 if RemoveCurrentElement
:
1583 FieldsList
.remove(Field
)
1585 RemoveCurrentElement
= False
1589 RemoveCurrentElement
= False
1593 FieldsList
= Fields
.split(';')
1595 for Field
in FieldsList
:
1596 Field
= Field
.strip()
1599 # For the condition that the field in struct is an array with [] sufixes...
1600 if Field
[-1] == ']':
1601 LBPos
= Field
.find('[')
1602 Field
= Field
[0:LBPos
]
1603 # For the condition that bit field ": Number"
1604 if Field
.find(':') != -1:
1605 ColonPos
= Field
.find(':')
1606 Field
= Field
[0:ColonPos
]
1608 Field
= Field
.strip()
1611 # Enum could directly assign value to variable
1612 Field
= Field
.split('=')[0].strip()
1613 TokenList
= Field
.split()
1614 # Remove pointers before variable
1615 if not Pattern
.match(TokenList
[-1].lstrip('*')):
1616 ErrMsgList
.append(TokenList
[-1].lstrip('*'))
1620 def CheckDeclTypedefFormat(FullFileName
, ModelId
):
1623 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
1628 FileTable
= 'Identifier' + str(FileID
)
1629 SqlStatement
= """ select Name, StartLine, EndLine, ID, Value
1632 """ % (FileTable
, ModelId
)
1633 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1635 for Result
in ResultSet
:
1636 ResultList
.append(Result
)
1638 ErrorType
= ERROR_DECLARATION_DATA_TYPE_CHECK_ALL
1639 if ModelId
== DataClass
.MODEL_IDENTIFIER_STRUCTURE
:
1640 ErrorType
= ERROR_DECLARATION_DATA_TYPE_CHECK_STRUCTURE_DECLARATION
1641 elif ModelId
== DataClass
.MODEL_IDENTIFIER_ENUMERATE
:
1642 ErrorType
= ERROR_DECLARATION_DATA_TYPE_CHECK_ENUMERATED_TYPE
1643 elif ModelId
== DataClass
.MODEL_IDENTIFIER_UNION
:
1644 ErrorType
= ERROR_DECLARATION_DATA_TYPE_CHECK_UNION_TYPE
1646 SqlStatement
= """ select Modifier, Name, Value, StartLine, EndLine, ID
1649 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_TYPEDEF
)
1650 TdSet
= Db
.TblFile
.Exec(SqlStatement
)
1654 # Check member variable name format that from typedefs of ONLY this file.
1656 Name
= Td
[1].strip()
1657 Value
= Td
[2].strip()
1658 if Value
.startswith('enum'):
1659 ValueModelId
= DataClass
.MODEL_IDENTIFIER_ENUMERATE
1660 elif Value
.startswith('struct'):
1661 ValueModelId
= DataClass
.MODEL_IDENTIFIER_STRUCTURE
1662 elif Value
.startswith('union'):
1663 ValueModelId
= DataClass
.MODEL_IDENTIFIER_UNION
1667 if ValueModelId
!= ModelId
:
1669 # Check member variable format.
1670 ErrMsgList
= CheckMemberVariableFormat(Name
, Value
, FileTable
, Td
[5], ModelId
)
1671 for ErrMsg
in ErrMsgList
:
1672 if EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME
, Name
+'.'+ErrMsg
):
1674 PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME
, 'Member variable [%s] NOT follow naming convention.' % (Name
+'.'+ErrMsg
), FileTable
, Td
[5])
1676 # First check in current file to see whether struct/union/enum is typedef-ed.
1677 UntypedefedList
= []
1678 for Result
in ResultList
:
1679 # Check member variable format.
1680 Name
= Result
[0].strip()
1681 Value
= Result
[4].strip()
1682 if Value
.startswith('enum'):
1683 ValueModelId
= DataClass
.MODEL_IDENTIFIER_ENUMERATE
1684 elif Value
.startswith('struct'):
1685 ValueModelId
= DataClass
.MODEL_IDENTIFIER_STRUCTURE
1686 elif Value
.startswith('union'):
1687 ValueModelId
= DataClass
.MODEL_IDENTIFIER_UNION
1691 if ValueModelId
!= ModelId
:
1693 ErrMsgList
= CheckMemberVariableFormat(Name
, Value
, FileTable
, Result
[3], ModelId
)
1694 for ErrMsg
in ErrMsgList
:
1695 if EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME
, Result
[0]+'.'+ErrMsg
):
1697 PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME
, 'Member variable [%s] NOT follow naming convention.' % (Result
[0]+'.'+ErrMsg
), FileTable
, Result
[3])
1698 # Check whether it is typedefed.
1701 # skip function pointer
1704 if Result
[1] >= Td
[3] and Td
[4] >= Result
[2]:
1706 if not Td
[1].isupper():
1707 PrintErrorMsg(ErrorType
, 'Typedef should be UPPER case', FileTable
, Td
[5])
1708 if Result
[0] in Td
[2].split():
1710 if not Td
[1].isupper():
1711 PrintErrorMsg(ErrorType
, 'Typedef should be UPPER case', FileTable
, Td
[5])
1716 UntypedefedList
.append(Result
)
1719 if len(UntypedefedList
) == 0:
1722 IncludeFileList
= GetAllIncludeFiles(FullFileName
)
1724 for F
in IncludeFileList
:
1725 FileID
= GetTableID(F
, ErrorMsgList
)
1729 IncludeFileTable
= 'Identifier' + str(FileID
)
1730 SqlStatement
= """ select Modifier, Name, Value, StartLine, EndLine, ID
1733 """ % (IncludeFileTable
, DataClass
.MODEL_IDENTIFIER_TYPEDEF
)
1734 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1735 TdList
.extend(ResultSet
)
1737 for Result
in UntypedefedList
:
1739 # Check whether it is typedefed.
1745 if Result
[1] >= Td
[3] and Td
[4] >= Result
[2]:
1747 if not Td
[1].isupper():
1748 PrintErrorMsg(ErrorType
, 'Typedef should be UPPER case', FileTable
, Td
[5])
1749 if Result
[0] in Td
[2].split():
1751 if not Td
[1].isupper():
1752 PrintErrorMsg(ErrorType
, 'Typedef should be UPPER case', FileTable
, Td
[5])
1757 PrintErrorMsg(ErrorType
, 'No Typedef for %s' % Result
[0], FileTable
, Result
[3])
1760 def CheckDeclStructTypedef(FullFileName
):
1761 CheckDeclTypedefFormat(FullFileName
, DataClass
.MODEL_IDENTIFIER_STRUCTURE
)
1763 def CheckDeclEnumTypedef(FullFileName
):
1764 CheckDeclTypedefFormat(FullFileName
, DataClass
.MODEL_IDENTIFIER_ENUMERATE
)
1766 def CheckDeclUnionTypedef(FullFileName
):
1767 CheckDeclTypedefFormat(FullFileName
, DataClass
.MODEL_IDENTIFIER_UNION
)
1769 def CheckDeclArgModifier(FullFileName
):
1772 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
1777 FileTable
= 'Identifier' + str(FileID
)
1778 SqlStatement
= """ select Modifier, Name, ID
1781 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_VARIABLE
)
1782 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1783 ModifierTuple
= ('IN', 'OUT', 'OPTIONAL', 'UNALIGNED')
1784 MAX_MODIFIER_LENGTH
= 100
1785 for Result
in ResultSet
:
1786 for Modifier
in ModifierTuple
:
1787 if PatternInModifier(Result
[0], Modifier
) and len(Result
[0]) < MAX_MODIFIER_LENGTH
:
1788 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER
, 'Variable Modifier %s' % Result
[0], FileTable
, Result
[2])
1791 SqlStatement
= """ select Modifier, Name, ID
1794 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_FUNCTION_DECLARATION
)
1795 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1796 for Result
in ResultSet
:
1797 for Modifier
in ModifierTuple
:
1798 if PatternInModifier(Result
[0], Modifier
):
1799 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER
, 'Return Type Modifier %s' % Result
[0], FileTable
, Result
[2])
1802 SqlStatement
= """ select Modifier, Header, ID
1804 where BelongsToFile = %d
1806 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1807 for Result
in ResultSet
:
1808 for Modifier
in ModifierTuple
:
1809 if PatternInModifier(Result
[0], Modifier
):
1810 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER
, 'Return Type Modifier %s' % Result
[0], FileTable
, Result
[2])
1813 def CheckDeclNoUseCType(FullFileName
):
1816 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
1821 FileTable
= 'Identifier' + str(FileID
)
1822 SqlStatement
= """ select Modifier, Name, ID
1825 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_VARIABLE
)
1826 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1827 CTypeTuple
= ('int', 'unsigned', 'char', 'void', 'static', 'long')
1828 for Result
in ResultSet
:
1829 for Type
in CTypeTuple
:
1830 if PatternInModifier(Result
[0], Type
):
1831 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE
, 'Variable type %s' % Type
, FileTable
, Result
[2])
1834 SqlStatement
= """ select Modifier, Name, ID, Value
1837 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_FUNCTION_DECLARATION
)
1838 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1839 for Result
in ResultSet
:
1840 ParamList
= GetParamList(Result
[1])
1841 FuncName
= Result
[3]
1842 if EccGlobalData
.gException
.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE
, FuncName
):
1844 for Type
in CTypeTuple
:
1845 if PatternInModifier(Result
[0], Type
):
1846 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE
, '%s Return type %s' % (FuncName
, Result
[0]), FileTable
, Result
[2])
1848 for Param
in ParamList
:
1849 if PatternInModifier(Param
.Modifier
, Type
):
1850 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE
, 'Parameter %s' % Param
.Name
, FileTable
, Result
[2])
1852 SqlStatement
= """ select Modifier, Header, ID, Name
1854 where BelongsToFile = %d
1856 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1857 for Result
in ResultSet
:
1858 ParamList
= GetParamList(Result
[1])
1859 FuncName
= Result
[3]
1860 if EccGlobalData
.gException
.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE
, FuncName
):
1862 for Type
in CTypeTuple
:
1863 if PatternInModifier(Result
[0], Type
):
1864 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE
, '[%s] Return type %s' % (FuncName
, Result
[0]), FileTable
, Result
[2])
1866 for Param
in ParamList
:
1867 if PatternInModifier(Param
.Modifier
, Type
):
1868 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE
, 'Parameter %s' % Param
.Name
, FileTable
, Result
[2])
1871 def CheckPointerNullComparison(FullFileName
):
1874 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
1878 # cache the found function return type to accelerate later checking in this file.
1879 FuncReturnTypeDict
= {}
1882 FileTable
= 'Identifier' + str(FileID
)
1883 SqlStatement
= """ select Value, StartLine, ID
1886 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_PREDICATE_EXPRESSION
)
1887 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1888 if len(ResultSet
) == 0:
1891 for Result
in ResultSet
:
1892 PSL
.append([Result
[0], Result
[1], Result
[2]])
1894 SqlStatement
= """ select BodyStartLine, EndLine, Header, Modifier, ID
1896 where BelongsToFile = %d
1898 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1900 for Result
in ResultSet
:
1901 FL
.append([Result
[0], Result
[1], Result
[2], Result
[3], Result
[4]])
1903 p
= GetFuncDeclPattern()
1905 FuncRecord
= GetFuncContainsPE(Str
[1], FL
)
1906 if FuncRecord
== None:
1909 for Exp
in GetPredicateListFromPredicateExpStr(Str
[0]):
1910 PredInfo
= SplitPredicateStr(Exp
)
1911 if PredInfo
[1] == None:
1912 PredVarStr
= PredInfo
[0][0].strip()
1914 SearchInCache
= False
1915 # PredVarStr may contain '.' or '->'
1916 TmpStr
= PredVarStr
.replace('.', '').replace('->', '')
1918 PredVarStr
= PredVarStr
[0:PredVarStr
.find('(')]
1919 SearchInCache
= True
1920 # Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable.
1921 if TmpStr
.startswith(PredVarStr
):
1924 if PredVarStr
.strip() in IgnoredKeywordList
:
1927 PredVarList
= GetCNameList(PredVarStr
, StarList
)
1928 # No variable found, maybe value first? like (0 == VarName)
1929 if len(PredVarList
) == 0:
1932 Type
= FuncReturnTypeDict
.get(PredVarStr
)
1934 if Type
.find('*') != -1:
1935 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE
, 'Predicate Expression: %s' % Exp
, FileTable
, Str
[2])
1938 if PredVarStr
in FuncReturnTypeDict
:
1941 Type
= GetVarInfo(PredVarList
, FuncRecord
, FullFileName
, IsFuncCall
, None, StarList
)
1943 FuncReturnTypeDict
[PredVarStr
] = Type
1946 Type
= GetTypeFromArray(Type
, PredVarStr
)
1947 if Type
.find('*') != -1:
1948 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE
, 'Predicate Expression: %s' % Exp
, FileTable
, Str
[2])
1950 def CheckNonBooleanValueComparison(FullFileName
):
1953 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
1957 # cache the found function return type to accelerate later checking in this file.
1958 FuncReturnTypeDict
= {}
1961 FileTable
= 'Identifier' + str(FileID
)
1962 SqlStatement
= """ select Value, StartLine, ID
1965 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_PREDICATE_EXPRESSION
)
1966 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1967 if len(ResultSet
) == 0:
1970 for Result
in ResultSet
:
1971 PSL
.append([Result
[0], Result
[1], Result
[2]])
1973 SqlStatement
= """ select BodyStartLine, EndLine, Header, Modifier, ID
1975 where BelongsToFile = %d
1977 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1979 for Result
in ResultSet
:
1980 FL
.append([Result
[0], Result
[1], Result
[2], Result
[3], Result
[4]])
1982 p
= GetFuncDeclPattern()
1984 FuncRecord
= GetFuncContainsPE(Str
[1], FL
)
1985 if FuncRecord
== None:
1988 for Exp
in GetPredicateListFromPredicateExpStr(Str
[0]):
1991 PredInfo
= SplitPredicateStr(Exp
)
1992 if PredInfo
[1] == None:
1993 PredVarStr
= PredInfo
[0][0].strip()
1995 SearchInCache
= False
1996 # PredVarStr may contain '.' or '->'
1997 TmpStr
= PredVarStr
.replace('.', '').replace('->', '')
1999 PredVarStr
= PredVarStr
[0:PredVarStr
.find('(')]
2000 SearchInCache
= True
2001 # Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable.
2002 if TmpStr
.startswith(PredVarStr
):
2005 if PredVarStr
.strip() in IgnoredKeywordList
:
2008 PredVarList
= GetCNameList(PredVarStr
, StarList
)
2009 # No variable found, maybe value first? like (0 == VarName)
2010 if len(PredVarList
) == 0:
2014 Type
= FuncReturnTypeDict
.get(PredVarStr
)
2016 if Type
.find('BOOLEAN') == -1:
2017 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR
, 'Predicate Expression: %s' % Exp
, FileTable
, Str
[2])
2020 if PredVarStr
in FuncReturnTypeDict
:
2023 Type
= GetVarInfo(PredVarList
, FuncRecord
, FullFileName
, IsFuncCall
, 'BOOLEAN', StarList
)
2025 FuncReturnTypeDict
[PredVarStr
] = Type
2028 if Type
.find('BOOLEAN') == -1:
2029 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR
, 'Predicate Expression: %s' % Exp
, FileTable
, Str
[2])
2032 def CheckBooleanValueComparison(FullFileName
):
2035 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
2039 # cache the found function return type to accelerate later checking in this file.
2040 FuncReturnTypeDict
= {}
2043 FileTable
= 'Identifier' + str(FileID
)
2044 SqlStatement
= """ select Value, StartLine, ID
2047 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_PREDICATE_EXPRESSION
)
2048 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
2049 if len(ResultSet
) == 0:
2052 for Result
in ResultSet
:
2053 PSL
.append([Result
[0], Result
[1], Result
[2]])
2055 SqlStatement
= """ select BodyStartLine, EndLine, Header, Modifier, ID
2057 where BelongsToFile = %d
2059 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
2061 for Result
in ResultSet
:
2062 FL
.append([Result
[0], Result
[1], Result
[2], Result
[3], Result
[4]])
2064 p
= GetFuncDeclPattern()
2066 FuncRecord
= GetFuncContainsPE(Str
[1], FL
)
2067 if FuncRecord
== None:
2070 for Exp
in GetPredicateListFromPredicateExpStr(Str
[0]):
2071 PredInfo
= SplitPredicateStr(Exp
)
2072 if PredInfo
[1] in ('==', '!=') and PredInfo
[0][1] in ('TRUE', 'FALSE'):
2073 PredVarStr
= PredInfo
[0][0].strip()
2075 SearchInCache
= False
2076 # PredVarStr may contain '.' or '->'
2077 TmpStr
= PredVarStr
.replace('.', '').replace('->', '')
2079 PredVarStr
= PredVarStr
[0:PredVarStr
.find('(')]
2080 SearchInCache
= True
2081 # Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable.
2082 if TmpStr
.startswith(PredVarStr
):
2085 if PredVarStr
.strip() in IgnoredKeywordList
:
2088 PredVarList
= GetCNameList(PredVarStr
, StarList
)
2089 # No variable found, maybe value first? like (0 == VarName)
2090 if len(PredVarList
) == 0:
2094 Type
= FuncReturnTypeDict
.get(PredVarStr
)
2096 if Type
.find('BOOLEAN') != -1:
2097 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE
, 'Predicate Expression: %s' % Exp
, FileTable
, Str
[2])
2100 if PredVarStr
in FuncReturnTypeDict
:
2103 Type
= GetVarInfo(PredVarList
, FuncRecord
, FullFileName
, IsFuncCall
, 'BOOLEAN', StarList
)
2105 FuncReturnTypeDict
[PredVarStr
] = Type
2108 if Type
.find('BOOLEAN') != -1:
2109 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE
, 'Predicate Expression: %s' % Exp
, FileTable
, Str
[2])
2112 def CheckHeaderFileData(FullFileName
):
2115 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
2120 FileTable
= 'Identifier' + str(FileID
)
2121 SqlStatement
= """ select ID, Modifier
2124 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_VARIABLE
)
2125 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
2126 for Result
in ResultSet
:
2127 if not Result
[1].startswith('extern'):
2128 PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_DATA
, 'Variable definition appears in header file', FileTable
, Result
[0])
2130 SqlStatement
= """ select ID
2132 where BelongsToFile = %d
2134 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
2135 for Result
in ResultSet
:
2136 PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_DATA
, 'Function definition appears in header file', 'Function', Result
[0])
2140 def CheckHeaderFileIfndef(FullFileName
):
2143 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
2148 FileTable
= 'Identifier' + str(FileID
)
2149 SqlStatement
= """ select Value, StartLine
2151 where Model = %d order by StartLine
2152 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_MACRO_IFNDEF
)
2153 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
2154 if len(ResultSet
) == 0:
2155 PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_1
, '', 'File', FileID
)
2157 for Result
in ResultSet
:
2158 SqlStatement
= """ select Value, EndLine
2161 """ % (FileTable
, Result
[1])
2162 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
2163 for Result
in ResultSet
:
2164 if not Result
[0].startswith('/*') and not Result
[0].startswith('//'):
2165 PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_2
, '', 'File', FileID
)
2168 SqlStatement
= """ select Value
2170 where StartLine > (select max(EndLine) from %s where Model = %d)
2171 """ % (FileTable
, FileTable
, DataClass
.MODEL_IDENTIFIER_MACRO_ENDIF
)
2172 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
2173 for Result
in ResultSet
:
2174 if not Result
[0].startswith('/*') and not Result
[0].startswith('//'):
2175 PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_3
, '', 'File', FileID
)
2178 def CheckDoxygenCommand(FullFileName
):
2181 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
2186 FileTable
= 'Identifier' + str(FileID
)
2187 SqlStatement
= """ select Value, ID
2189 where Model = %d or Model = %d
2190 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_COMMENT
, DataClass
.MODEL_IDENTIFIER_FUNCTION_HEADER
)
2191 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
2192 DoxygenCommandList
= ['bug', 'todo', 'example', 'file', 'attention', 'param', 'post', 'pre', 'retval', 'return', 'sa', 'since', 'test', 'note', 'par']
2193 for Result
in ResultSet
:
2194 CommentStr
= Result
[0]
2195 CommentPartList
= CommentStr
.split()
2196 for Part
in CommentPartList
:
2197 if Part
.upper() == 'BUGBUG':
2198 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND
, 'Bug should be marked with doxygen tag @bug', FileTable
, Result
[1])
2199 if Part
.upper() == 'TODO':
2200 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND
, 'ToDo should be marked with doxygen tag @todo', FileTable
, Result
[1])
2201 if Part
.startswith('@'):
2202 if EccGlobalData
.gException
.IsException(ERROR_DOXYGEN_CHECK_COMMAND
, Part
):
2204 if Part
.lstrip('@').isalpha():
2205 if Part
.lstrip('@') not in DoxygenCommandList
:
2206 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND
, 'Unknown doxygen command %s' % Part
, FileTable
, Result
[1])
2208 Index
= Part
.find('[')
2210 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND
, 'Unknown doxygen command %s' % Part
, FileTable
, Result
[1])
2211 RealCmd
= Part
[1:Index
]
2212 if RealCmd
not in DoxygenCommandList
:
2213 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND
, 'Unknown doxygen command %s' % Part
, FileTable
, Result
[1])
2216 def CheckDoxygenTripleForwardSlash(FullFileName
):
2219 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
2225 SqlStatement
= """ select ID, BodyStartLine, BodyStartColumn, EndLine, EndColumn
2227 where BelongsToFile = %d
2229 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
2230 if len(ResultSet
) == 0:
2234 for Result
in ResultSet
:
2235 FuncDefSet
.append(Result
)
2238 FileTable
= 'Identifier' + str(FileID
)
2239 SqlStatement
= """ select Value, ID, StartLine, StartColumn, EndLine, EndColumn
2243 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_COMMENT
)
2244 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
2247 for Result
in ResultSet
:
2248 CommentSet
.append(Result
)
2250 print 'Unrecognized chars in comment of file %s', FullFileName
2253 for Result
in CommentSet
:
2254 CommentStr
= Result
[0]
2255 StartLine
= Result
[2]
2256 StartColumn
= Result
[3]
2258 EndColumn
= Result
[5]
2259 if not CommentStr
.startswith('///<'):
2263 for FuncDef
in FuncDefSet
:
2264 if StartLine
== FuncDef
[1] and StartColumn
> FuncDef
[2] and EndLine
== FuncDef
[3] and EndColumn
< FuncDef
[4]:
2267 if StartLine
> FuncDef
[1] and EndLine
< FuncDef
[3]:
2270 if StartLine
== FuncDef
[1] and StartColumn
> FuncDef
[2] and EndLine
< FuncDef
[3]:
2273 if StartLine
> FuncDef
[1] and EndLine
== FuncDef
[3] and EndColumn
< FuncDef
[4]:
2277 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMENT_FORMAT
, '', FileTable
, Result
[1])
2280 def CheckFileHeaderDoxygenComments(FullFileName
):
2283 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
2288 FileTable
= 'Identifier' + str(FileID
)
2289 SqlStatement
= """ select Value, ID
2291 where Model = %d and StartLine = 1 and StartColumn = 0
2292 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_COMMENT
)
2293 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
2294 if len(ResultSet
) == 0:
2295 PrintErrorMsg(ERROR_HEADER_CHECK_FILE
, 'No Comment appear at the very beginning of file.', 'File', FileID
)
2298 for Result
in ResultSet
:
2299 CommentStr
= Result
[0]
2300 if not CommentStr
.startswith('/** @file'):
2301 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FILE_HEADER
, 'File header comment should begin with ""/** @file""', FileTable
, Result
[1])
2302 if not CommentStr
.endswith('**/'):
2303 PrintErrorMsg(ERROR_HEADER_CHECK_FILE
, 'File header comment should end with **/', FileTable
, Result
[1])
2304 if CommentStr
.find('.') == -1:
2305 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMENT_DESCRIPTION
, 'Comment description should end with period \'.\'', FileTable
, Result
[1])
2307 def CheckFuncHeaderDoxygenComments(FullFileName
):
2310 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
2315 FileTable
= 'Identifier' + str(FileID
)
2316 SqlStatement
= """ select Value, StartLine, EndLine, ID
2319 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_COMMENT
)
2321 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
2324 for Result
in ResultSet
:
2325 CommentSet
.append(Result
)
2327 print 'Unrecognized chars in comment of file %s', FullFileName
2330 SqlStatement
= """ select Modifier, Name, StartLine, ID, Value
2333 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_FUNCTION_DECLARATION
)
2334 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
2335 for Result
in ResultSet
:
2336 FuncName
= Result
[4]
2337 FunctionHeaderComment
= CheckCommentImmediatelyPrecedeFunctionHeader(Result
[1], Result
[2], CommentSet
)
2338 if FunctionHeaderComment
:
2339 CheckFunctionHeaderConsistentWithDoxygenComment(Result
[0], Result
[1], Result
[2], FunctionHeaderComment
[0], FunctionHeaderComment
[1], ErrorMsgList
, FunctionHeaderComment
[3], FileTable
)
2341 if EccGlobalData
.gException
.IsException(ERROR_HEADER_CHECK_FUNCTION
, FuncName
):
2343 ErrorMsgList
.append('Line %d :Function %s has NO comment immediately preceding it.' % (Result
[2], Result
[1]))
2344 PrintErrorMsg(ERROR_HEADER_CHECK_FUNCTION
, 'Function [%s] has NO comment immediately preceding it.' % (FuncName
), FileTable
, Result
[3])
2347 SqlStatement
= """ select Value, StartLine, EndLine, ID
2350 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_FUNCTION_HEADER
)
2352 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
2355 for Result
in ResultSet
:
2356 CommentSet
.append(Result
)
2358 print 'Unrecognized chars in comment of file %s', FullFileName
2360 SqlStatement
= """ select Modifier, Header, StartLine, ID, Name
2362 where BelongsToFile = %d
2364 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
2365 for Result
in ResultSet
:
2366 FuncName
= Result
[4]
2367 FunctionHeaderComment
= CheckCommentImmediatelyPrecedeFunctionHeader(Result
[1], Result
[2], CommentSet
)
2368 if FunctionHeaderComment
:
2369 CheckFunctionHeaderConsistentWithDoxygenComment(Result
[0], Result
[1], Result
[2], FunctionHeaderComment
[0], FunctionHeaderComment
[1], ErrorMsgList
, FunctionHeaderComment
[3], FileTable
)
2371 if EccGlobalData
.gException
.IsException(ERROR_HEADER_CHECK_FUNCTION
, FuncName
):
2373 ErrorMsgList
.append('Line %d :Function [%s] has NO comment immediately preceding it.' % (Result
[2], Result
[1]))
2374 PrintErrorMsg(ERROR_HEADER_CHECK_FUNCTION
, 'Function [%s] has NO comment immediately preceding it.' % (FuncName
), 'Function', Result
[3])
2377 def CheckCommentImmediatelyPrecedeFunctionHeader(FuncName
, FuncStartLine
, CommentSet
):
2379 for Comment
in CommentSet
:
2380 if Comment
[2] == FuncStartLine
- 1:
2384 def GetDoxygenStrFromComment(Str
):
2386 ParamTagList
= Str
.split('@param')
2387 if len(ParamTagList
) > 1:
2389 while i
< len(ParamTagList
):
2390 DoxygenStrList
.append('@param' + ParamTagList
[i
])
2393 Str
= ParamTagList
[0]
2395 RetvalTagList
= ParamTagList
[-1].split('@retval')
2396 if len(RetvalTagList
) > 1:
2397 if len(ParamTagList
) > 1:
2398 DoxygenStrList
[-1] = '@param' + RetvalTagList
[0]
2400 while i
< len(RetvalTagList
):
2401 DoxygenStrList
.append('@retval' + RetvalTagList
[i
])
2404 ReturnTagList
= RetvalTagList
[-1].split('@return')
2405 if len(ReturnTagList
) > 1:
2406 if len(RetvalTagList
) > 1:
2407 DoxygenStrList
[-1] = '@retval' + ReturnTagList
[0]
2408 elif len(ParamTagList
) > 1:
2409 DoxygenStrList
[-1] = '@param' + ReturnTagList
[0]
2411 while i
< len(ReturnTagList
):
2412 DoxygenStrList
.append('@return' + ReturnTagList
[i
])
2415 if len(DoxygenStrList
) > 0:
2416 DoxygenStrList
[-1] = DoxygenStrList
[-1].rstrip('--*/')
2418 return DoxygenStrList
2420 def CheckGeneralDoxygenCommentLayout(Str
, StartLine
, ErrorMsgList
, CommentId
= -1, TableName
= ''):
2421 #/** --*/ @retval after @param
2422 if not Str
.startswith('/**'):
2423 ErrorMsgList
.append('Line %d : Comment does NOT have prefix /** ' % StartLine
)
2424 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER
, 'Comment does NOT have prefix /** ', TableName
, CommentId
)
2425 if not Str
.endswith('**/'):
2426 ErrorMsgList
.append('Line %d : Comment does NOT have tail **/ ' % StartLine
)
2427 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER
, 'Comment does NOT have tail **/ ', TableName
, CommentId
)
2428 FirstRetvalIndex
= Str
.find('@retval')
2429 LastParamIndex
= Str
.rfind('@param')
2430 if (FirstRetvalIndex
> 0) and (LastParamIndex
> 0) and (FirstRetvalIndex
< LastParamIndex
):
2431 ErrorMsgList
.append('Line %d : @retval appear before @param ' % StartLine
)
2432 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER
, 'in Comment, @retval appear before @param ', TableName
, CommentId
)
2434 def CheckFunctionHeaderConsistentWithDoxygenComment(FuncModifier
, FuncHeader
, FuncStartLine
, CommentStr
, CommentStartLine
, ErrorMsgList
, CommentId
= -1, TableName
= ''):
2436 ParamList
= GetParamList(FuncHeader
)
2437 CheckGeneralDoxygenCommentLayout(CommentStr
, CommentStartLine
, ErrorMsgList
, CommentId
, TableName
)
2438 DescriptionStr
= CommentStr
2439 DoxygenStrList
= GetDoxygenStrFromComment(DescriptionStr
)
2440 if DescriptionStr
.find('.') == -1:
2441 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMENT_DESCRIPTION
, 'Comment description should end with period \'.\'', TableName
, CommentId
)
2442 DoxygenTagNumber
= len(DoxygenStrList
)
2443 ParamNumber
= len(ParamList
)
2444 for Param
in ParamList
:
2445 if Param
.Name
.upper() == 'VOID' and ParamNumber
== 1:
2448 if ParamNumber
> 0 and DoxygenTagNumber
> 0:
2449 while Index
< ParamNumber
and Index
< DoxygenTagNumber
:
2450 ParamModifier
= ParamList
[Index
].Modifier
2451 ParamName
= ParamList
[Index
].Name
.strip()
2452 Tag
= DoxygenStrList
[Index
].strip(' ')
2453 if (not Tag
[-1] == ('\n')) and (not Tag
[-1] == ('\r')):
2454 ErrorMsgList
.append('Line %d : in Comment, \"%s\" does NOT end with new line ' % (CommentStartLine
, Tag
.replace('\n', '').replace('\r', '')))
2455 PrintErrorMsg(ERROR_HEADER_CHECK_FUNCTION
, 'in Comment, \"%s\" does NOT end with new line ' % (Tag
.replace('\n', '').replace('\r', '')), TableName
, CommentId
)
2456 TagPartList
= Tag
.split()
2457 if len(TagPartList
) < 2:
2458 ErrorMsgList
.append('Line %d : in Comment, \"%s\" does NOT contain doxygen contents ' % (CommentStartLine
, Tag
.replace('\n', '').replace('\r', '')))
2459 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER
, 'in Comment, \"%s\" does NOT contain doxygen contents ' % (Tag
.replace('\n', '').replace('\r', '')), TableName
, CommentId
)
2462 LBPos
= Tag
.find('[')
2463 RBPos
= Tag
.find(']')
2464 ParamToLBContent
= Tag
[len('@param'):LBPos
].strip()
2465 if LBPos
> 0 and len(ParamToLBContent
)==0 and RBPos
> LBPos
:
2467 ModifierPartList
= ParamModifier
.split()
2468 for Part
in ModifierPartList
:
2469 if Part
.strip() == 'IN':
2471 if Part
.strip() == 'OUT':
2478 if Tag
.find('['+InOutStr
+']') == -1:
2479 ErrorMsgList
.append('Line %d : in Comment, \"%s\" does NOT have %s ' % (CommentStartLine
, (TagPartList
[0] + ' ' +TagPartList
[1]).replace('\n', '').replace('\r', ''), '['+InOutStr
+']'))
2480 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER
, 'in Comment, \"%s\" does NOT have %s ' % ((TagPartList
[0] + ' ' +TagPartList
[1]).replace('\n', '').replace('\r', ''), '['+InOutStr
+']'), TableName
, CommentId
)
2481 if Tag
.find(ParamName
) == -1 and ParamName
!= 'VOID' and ParamName
!= 'void':
2482 ErrorMsgList
.append('Line %d : in Comment, \"%s\" does NOT consistent with parameter name %s ' % (CommentStartLine
, (TagPartList
[0] + ' ' +TagPartList
[1]).replace('\n', '').replace('\r', ''), ParamName
))
2483 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
)
2486 if Index
< ParamNumber
:
2487 ErrorMsgList
.append('Line %d : Number of doxygen tags in comment less than number of function parameters' % CommentStartLine
)
2488 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER
, 'Number of doxygen tags in comment less than number of function parameters ', TableName
, CommentId
)
2489 # VOID return type, NOT VOID*. VOID* should be matched with a doxygen tag.
2490 if (FuncModifier
.find('VOID') != -1 or FuncModifier
.find('void') != -1) and FuncModifier
.find('*') == -1:
2492 # assume we allow a return description tag for void func. return. that's why 'DoxygenTagNumber - 1' is used instead of 'DoxygenTagNumber'
2493 if Index
< DoxygenTagNumber
- 1 or (Index
< DoxygenTagNumber
and DoxygenStrList
[Index
].startswith('@retval')):
2494 ErrorMsgList
.append('Line %d : VOID return type need NO doxygen tags in comment' % CommentStartLine
)
2495 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER
, 'VOID return type need no doxygen tags in comment ', TableName
, CommentId
)
2497 if Index
< DoxygenTagNumber
and not DoxygenStrList
[Index
].startswith('@retval') and not DoxygenStrList
[Index
].startswith('@return'):
2498 ErrorMsgList
.append('Line %d : Number of @param doxygen tags in comment does NOT match number of function parameters' % CommentStartLine
)
2499 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER
, 'Number of @param doxygen tags in comment does NOT match number of function parameters ', TableName
, CommentId
)
2501 if ParamNumber
== 0 and DoxygenTagNumber
!= 0 and ((FuncModifier
.find('VOID') != -1 or FuncModifier
.find('void') != -1) and FuncModifier
.find('*') == -1):
2502 ErrorMsgList
.append('Line %d : VOID return type need NO doxygen tags in comment' % CommentStartLine
)
2503 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER
, 'VOID return type need NO doxygen tags in comment ', TableName
, CommentId
)
2504 if ParamNumber
!= 0 and DoxygenTagNumber
== 0:
2505 ErrorMsgList
.append('Line %d : No doxygen tags in comment' % CommentStartLine
)
2506 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER
, 'No doxygen tags in comment ', TableName
, CommentId
)
2508 if __name__
== '__main__':
2510 # EdkLogger.Initialize()
2511 # EdkLogger.SetLevel(EdkLogger.QUIET)
2512 # CollectSourceCodeDataIntoDB(sys.argv[1])
2513 MsgList
= CheckFuncHeaderDoxygenComments('C:\\Combo\\R9\\LakeportX64Dev\\FlashDevicePkg\\Library\\SpiFlashChipM25P64\\SpiFlashChipM25P64.c')