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