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