]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Eot/c.py
Sync EDKII BaseTools to BaseTools project r1971
[mirror_edk2.git] / BaseTools / Source / Python / Eot / c.py
CommitLineData
52302d4d
LG
1## @file\r
2# preprocess source file\r
3#\r
40d841f6 4# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>\r
52302d4d 5#\r
40d841f6 6# This program and the accompanying materials\r
52302d4d
LG
7# are licensed and made available under the terms and conditions of the BSD License\r
8# which accompanies this distribution. The full text of the license may be found at\r
9# http://opensource.org/licenses/bsd-license.php\r
10#\r
11# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13#\r
14\r
15##\r
16# Import Modules\r
17#\r
18import sys\r
19import os\r
20import re\r
21import CodeFragmentCollector\r
22import FileProfile\r
23from CommonDataClass import DataClass\r
24from Common import EdkLogger\r
25from EotToolError import *\r
26import EotGlobalData\r
27\r
28# Global Dicts\r
29IncludeFileListDict = {}\r
30IncludePathListDict = {}\r
31ComplexTypeDict = {}\r
32SUDict = {}\r
33\r
34## GetIgnoredDirListPattern() method\r
35#\r
36# Get the pattern of ignored direction list\r
37#\r
38# @return p: the pattern of ignored direction list\r
39#\r
40def GetIgnoredDirListPattern():\r
41 p = re.compile(r'.*[\\/](?:BUILD|INTELRESTRICTEDTOOLS|INTELRESTRICTEDPKG|PCCTS)[\\/].*')\r
42 return p\r
43\r
44## GetFuncDeclPattern() method\r
45#\r
46# Get the pattern of function declaration\r
47#\r
48# @return p: the pattern of function declaration\r
49#\r
50def GetFuncDeclPattern():\r
51 p = re.compile(r'(EFIAPI|EFI_BOOT_SERVICE|EFI_RUNTIME_SERVICE)?\s*[_\w]+\s*\(.*\).*', re.DOTALL)\r
52 return p\r
53\r
54## GetArrayPattern() method\r
55#\r
56# Get the pattern of array\r
57#\r
58# @return p: the pattern of array\r
59#\r
60def GetArrayPattern():\r
61 p = re.compile(r'[_\w]*\s*[\[.*\]]+')\r
62 return p\r
63\r
64## GetTypedefFuncPointerPattern() method\r
65#\r
66# Get the pattern of function pointer\r
67#\r
68# @return p: the pattern of function pointer\r
69#\r
70def GetTypedefFuncPointerPattern():\r
71 p = re.compile('[_\w\s]*\([\w\s]*\*+\s*[_\w]+\s*\)\s*\(.*\)', re.DOTALL)\r
72 return p\r
73\r
74## GetDB() method\r
75#\r
76# Get global database instance\r
77#\r
78# @return EotGlobalData.gDb: the global database instance\r
79#\r
80def GetDB():\r
81 return EotGlobalData.gDb\r
82\r
83## PrintErrorMsg() method\r
84#\r
85# print error message\r
86#\r
87# @param ErrorType: Type of error\r
88# @param Msg: Error message\r
89# @param TableName: table name of error found\r
90# @param ItemId: id of item\r
91#\r
92def PrintErrorMsg(ErrorType, Msg, TableName, ItemId):\r
93 Msg = Msg.replace('\n', '').replace('\r', '')\r
94 MsgPartList = Msg.split()\r
95 Msg = ''\r
96 for Part in MsgPartList:\r
97 Msg += Part\r
98 Msg += ' '\r
99 GetDB().TblReport.Insert(ErrorType, OtherMsg = Msg, BelongsToTable = TableName, BelongsToItem = ItemId)\r
100\r
101## GetIdType() method\r
102#\r
103# Find type of input string\r
104#\r
105# @param Str: String to be parsed\r
106#\r
107# @return Type: The type of the string\r
108#\r
109def GetIdType(Str):\r
110 Type = DataClass.MODEL_UNKNOWN\r
111 Str = Str.replace('#', '# ')\r
112 List = Str.split()\r
113 if List[1] == 'include':\r
114 Type = DataClass.MODEL_IDENTIFIER_INCLUDE\r
115 elif List[1] == 'define':\r
116 Type = DataClass.MODEL_IDENTIFIER_MACRO_DEFINE\r
117 elif List[1] == 'ifdef':\r
118 Type = DataClass.MODEL_IDENTIFIER_MACRO_IFDEF\r
119 elif List[1] == 'ifndef':\r
120 Type = DataClass.MODEL_IDENTIFIER_MACRO_IFNDEF\r
121 elif List[1] == 'endif':\r
122 Type = DataClass.MODEL_IDENTIFIER_MACRO_ENDIF\r
123 elif List[1] == 'pragma':\r
124 Type = DataClass.MODEL_IDENTIFIER_MACRO_PROGMA\r
125 else:\r
126 Type = DataClass.MODEL_UNKNOWN\r
127 return Type\r
128\r
129## GetIdentifierList() method\r
130#\r
131# Get id of all files\r
132#\r
133# @return IdList: The list of all id of files\r
134#\r
135def GetIdentifierList():\r
136 IdList = []\r
137\r
138 for pp in FileProfile.PPDirectiveList:\r
139 Type = GetIdType(pp.Content)\r
140 IdPP = DataClass.IdentifierClass(-1, '', '', '', pp.Content, Type, -1, -1, pp.StartPos[0],pp.StartPos[1],pp.EndPos[0],pp.EndPos[1])\r
141 IdList.append(IdPP)\r
142\r
143 for ae in FileProfile.AssignmentExpressionList:\r
144 IdAE = DataClass.IdentifierClass(-1, ae.Operator, '', ae.Name, ae.Value, DataClass.MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION, -1, -1, ae.StartPos[0],ae.StartPos[1],ae.EndPos[0],ae.EndPos[1])\r
145 IdList.append(IdAE)\r
146\r
147 FuncDeclPattern = GetFuncDeclPattern()\r
148 ArrayPattern = GetArrayPattern()\r
149 for var in FileProfile.VariableDeclarationList:\r
150 DeclText = var.Declarator.strip()\r
151 while DeclText.startswith('*'):\r
152 var.Modifier += '*'\r
153 DeclText = DeclText.lstrip('*').strip()\r
154 var.Declarator = DeclText\r
155 if FuncDeclPattern.match(var.Declarator):\r
156 DeclSplitList = var.Declarator.split('(')\r
157 FuncName = DeclSplitList[0]\r
158 FuncNamePartList = FuncName.split()\r
159 if len(FuncNamePartList) > 1:\r
160 FuncName = FuncNamePartList[-1]\r
161 Index = 0\r
162 while Index < len(FuncNamePartList) - 1:\r
163 var.Modifier += ' ' + FuncNamePartList[Index]\r
164 var.Declarator = var.Declarator.lstrip().lstrip(FuncNamePartList[Index])\r
165 Index += 1\r
166 IdVar = DataClass.IdentifierClass(-1, var.Modifier, '', var.Declarator, '', DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION, -1, -1, var.StartPos[0],var.StartPos[1],var.EndPos[0],var.EndPos[1])\r
167 IdList.append(IdVar)\r
168 continue\r
169\r
170 if var.Declarator.find('{') == -1:\r
171 for decl in var.Declarator.split(','):\r
172 DeclList = decl.split('=')\r
173 Name = DeclList[0].strip()\r
174 if ArrayPattern.match(Name):\r
175 LSBPos = var.Declarator.find('[')\r
176 var.Modifier += ' ' + Name[LSBPos:]\r
177 Name = Name[0:LSBPos]\r
178\r
179 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],var.EndPos[0],var.EndPos[1])\r
180 IdList.append(IdVar)\r
181 else:\r
182 DeclList = var.Declarator.split('=')\r
183 Name = DeclList[0].strip()\r
184 if ArrayPattern.match(Name):\r
185 LSBPos = var.Declarator.find('[')\r
186 var.Modifier += ' ' + Name[LSBPos:]\r
187 Name = Name[0:LSBPos]\r
188 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],var.EndPos[0],var.EndPos[1])\r
189 IdList.append(IdVar)\r
190\r
191 for enum in FileProfile.EnumerationDefinitionList:\r
192 LBPos = enum.Content.find('{')\r
193 RBPos = enum.Content.find('}')\r
194 Name = enum.Content[4:LBPos].strip()\r
195 Value = enum.Content[LBPos+1:RBPos]\r
196 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
197 IdList.append(IdEnum)\r
198\r
199 for su in FileProfile.StructUnionDefinitionList:\r
200 Type = DataClass.MODEL_IDENTIFIER_STRUCTURE\r
201 SkipLen = 6\r
202 if su.Content.startswith('union'):\r
203 Type = DataClass.MODEL_IDENTIFIER_UNION\r
204 SkipLen = 5\r
205 LBPos = su.Content.find('{')\r
206 RBPos = su.Content.find('}')\r
207 if LBPos == -1 or RBPos == -1:\r
208 Name = su.Content[SkipLen:].strip()\r
209 Value = ''\r
210 else:\r
211 Name = su.Content[SkipLen:LBPos].strip()\r
212 Value = su.Content[LBPos+1:RBPos]\r
213 IdPE = DataClass.IdentifierClass(-1, '', '', Name, Value, Type, -1, -1, su.StartPos[0],su.StartPos[1],su.EndPos[0],su.EndPos[1])\r
214 IdList.append(IdPE)\r
215\r
216 TdFuncPointerPattern = GetTypedefFuncPointerPattern()\r
217 for td in FileProfile.TypedefDefinitionList:\r
218 Modifier = ''\r
219 Name = td.ToType\r
220 Value = td.FromType\r
221 if TdFuncPointerPattern.match(td.ToType):\r
222 Modifier = td.FromType\r
223 LBPos = td.ToType.find('(')\r
224 TmpStr = td.ToType[LBPos+1:].strip()\r
225 StarPos = TmpStr.find('*')\r
226 if StarPos != -1:\r
227 Modifier += ' ' + TmpStr[0:StarPos]\r
228 while TmpStr[StarPos] == '*':\r
229 Modifier += ' ' + '*'\r
230 StarPos += 1\r
231 TmpStr = TmpStr[StarPos:].strip()\r
232 RBPos = TmpStr.find(')')\r
233 Name = TmpStr[0:RBPos]\r
234 Value = 'FP' + TmpStr[RBPos + 1:]\r
235\r
236 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
237 IdList.append(IdTd)\r
238\r
239 for funcCall in FileProfile.FunctionCallingList:\r
240 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
241 IdList.append(IdFC)\r
242 return IdList\r
243\r
244## GetParamList() method\r
245#\r
246# Get a list of parameters\r
247#\r
248# @param FuncDeclarator: Function declarator\r
249# @param FuncNameLine: Line number of function name\r
250# @param FuncNameOffset: Offset of function name\r
251#\r
252# @return ParamIdList: A list of parameters\r
253#\r
254def GetParamList(FuncDeclarator, FuncNameLine = 0, FuncNameOffset = 0):\r
255 ParamIdList = []\r
256 DeclSplitList = FuncDeclarator.split('(')\r
257 if len(DeclSplitList) < 2:\r
258 return ParamIdList\r
259 FuncName = DeclSplitList[0]\r
260 ParamStr = DeclSplitList[1].rstrip(')')\r
261 LineSkipped = 0\r
262 OffsetSkipped = 0\r
263 Start = 0\r
264 while FuncName.find('\n', Start) != -1:\r
265 LineSkipped += 1\r
266 OffsetSkipped = 0\r
267 Start += FuncName.find('\n', Start)\r
268 Start += 1\r
269 OffsetSkipped += len(FuncName[Start:])\r
270 OffsetSkipped += 1 #skip '('\r
271 ParamBeginLine = FuncNameLine + LineSkipped\r
272 ParamBeginOffset = OffsetSkipped\r
273 for p in ParamStr.split(','):\r
274 ListP = p.split()\r
275 if len(ListP) == 0:\r
276 continue\r
277 ParamName = ListP[-1]\r
278 DeclText = ParamName.strip()\r
279 RightSpacePos = p.rfind(ParamName)\r
280 ParamModifier = p[0:RightSpacePos]\r
281 if ParamName == 'OPTIONAL':\r
282 if ParamModifier == '':\r
283 ParamModifier += ' ' + 'OPTIONAL'\r
284 DeclText = ''\r
285 else:\r
286 ParamName = ListP[-2]\r
287 DeclText = ParamName.strip()\r
288 RightSpacePos = p.rfind(ParamName)\r
289 ParamModifier = p[0:RightSpacePos]\r
290 ParamModifier += 'OPTIONAL'\r
291 while DeclText.startswith('*'):\r
292 ParamModifier += ' ' + '*'\r
293 DeclText = DeclText.lstrip('*').strip()\r
294 ParamName = DeclText\r
295\r
296 Start = 0\r
297 while p.find('\n', Start) != -1:\r
298 LineSkipped += 1\r
299 OffsetSkipped = 0\r
300 Start += p.find('\n', Start)\r
301 Start += 1\r
302 OffsetSkipped += len(p[Start:])\r
303\r
304 ParamEndLine = ParamBeginLine + LineSkipped\r
305 ParamEndOffset = OffsetSkipped\r
306 IdParam = DataClass.IdentifierClass(-1, ParamModifier, '', ParamName, '', DataClass.MODEL_IDENTIFIER_PARAMETER, -1, -1, ParamBeginLine, ParamBeginOffset, ParamEndLine, ParamEndOffset)\r
307 ParamIdList.append(IdParam)\r
308 ParamBeginLine = ParamEndLine\r
309 ParamBeginOffset = OffsetSkipped + 1 #skip ','\r
310\r
311 return ParamIdList\r
312\r
313## GetFunctionList()\r
314#\r
315# Get a list of functions\r
316#\r
317# @return FuncObjList: A list of function objects\r
318#\r
319def GetFunctionList():\r
320 FuncObjList = []\r
321 for FuncDef in FileProfile.FunctionDefinitionList:\r
322 ParamIdList = []\r
323 DeclText = FuncDef.Declarator.strip()\r
324 while DeclText.startswith('*'):\r
325 FuncDef.Modifier += '*'\r
326 DeclText = DeclText.lstrip('*').strip()\r
327\r
328 FuncDef.Declarator = FuncDef.Declarator.lstrip('*')\r
329 DeclSplitList = FuncDef.Declarator.split('(')\r
330 if len(DeclSplitList) < 2:\r
331 continue\r
332\r
333 FuncName = DeclSplitList[0]\r
334 FuncNamePartList = FuncName.split()\r
335 if len(FuncNamePartList) > 1:\r
336 FuncName = FuncNamePartList[-1]\r
337 Index = 0\r
338 while Index < len(FuncNamePartList) - 1:\r
339 FuncDef.Modifier += ' ' + FuncNamePartList[Index]\r
340 Index += 1\r
341\r
342 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, [])\r
343 FuncObjList.append(FuncObj)\r
344\r
345 return FuncObjList\r
346\r
347## CreateCCodeDB() method\r
348#\r
349# Create database for all c code\r
350#\r
351# @param FileNameList: A list of all c code file names\r
352#\r
353def CreateCCodeDB(FileNameList):\r
354 FileObjList = []\r
355 ParseErrorFileList = []\r
40d841f6 356 ParsedFiles = {}\r
52302d4d
LG
357 for FullName in FileNameList:\r
358 if os.path.splitext(FullName)[1] in ('.h', '.c'):\r
40d841f6
LG
359 if FullName.lower() in ParsedFiles:\r
360 continue\r
361 ParsedFiles[FullName.lower()] = 1\r
52302d4d
LG
362 EdkLogger.info("Parsing " + FullName)\r
363 model = FullName.endswith('c') and DataClass.MODEL_FILE_C or DataClass.MODEL_FILE_H\r
364 collector = CodeFragmentCollector.CodeFragmentCollector(FullName)\r
365 try:\r
366 collector.ParseFile()\r
79714906 367 except:\r
52302d4d
LG
368 ParseErrorFileList.append(FullName)\r
369 BaseName = os.path.basename(FullName)\r
370 DirName = os.path.dirname(FullName)\r
371 Ext = os.path.splitext(BaseName)[1].lstrip('.')\r
372 ModifiedTime = os.path.getmtime(FullName)\r
373 FileObj = DataClass.FileClass(-1, BaseName, Ext, DirName, FullName, model, ModifiedTime, GetFunctionList(), GetIdentifierList(), [])\r
374 FileObjList.append(FileObj)\r
375 collector.CleanFileProfileBuffer()\r
376\r
377 if len(ParseErrorFileList) > 0:\r
378 EdkLogger.info("Found unrecoverable error during parsing:\n\t%s\n" % "\n\t".join(ParseErrorFileList))\r
379\r
380 Db = EotGlobalData.gDb\r
381 for file in FileObjList:\r
382 Db.InsertOneFile(file)\r
383\r
384 Db.UpdateIdentifierBelongsToFunction()\r
385\r
386##\r
387#\r
388# This acts like the main() function for the script, unless it is 'import'ed into another\r
389# script.\r
390#\r
391if __name__ == '__main__':\r
392\r
393 EdkLogger.Initialize()\r
394 EdkLogger.SetLevel(EdkLogger.QUIET)\r
395 CollectSourceCodeDataIntoDB(sys.argv[1])\r
396\r
397 print 'Done!'\r