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