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