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