diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-11 08:17:27 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-11 08:17:27 +0000 |
commit | f215e02bf85f68d3a6106c2a1f4f7f063f819064 (patch) | |
tree | 6bb5b92c046312c4e95ac2620b10ddf482d3fa8b /src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/c.py | |
parent | Initial commit. (diff) | |
download | virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.tar.xz virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.zip |
Adding upstream version 7.0.14-dfsg.upstream/7.0.14-dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rwxr-xr-x | src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/c.py | 383 |
1 files changed, 383 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/c.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/c.py new file mode 100755 index 00000000..8aa45d72 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/c.py @@ -0,0 +1,383 @@ +## @file +# preprocess source file +# +# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +from __future__ import print_function +from __future__ import absolute_import +import sys +import Common.LongFilePathOs as os +import re +from . import CodeFragmentCollector +from . import FileProfile +from CommonDataClass import DataClass +from Common import EdkLogger +from .EotToolError import * +from . import EotGlobalData + +# Global Dicts +IncludeFileListDict = {} +IncludePathListDict = {} +ComplexTypeDict = {} +SUDict = {} + +## GetFuncDeclPattern() method +# +# Get the pattern of function declaration +# +# @return p: the pattern of function declaration +# +def GetFuncDeclPattern(): + p = re.compile(r'(EFIAPI|EFI_BOOT_SERVICE|EFI_RUNTIME_SERVICE)?\s*[_\w]+\s*\(.*\).*', re.DOTALL) + return p + +## GetArrayPattern() method +# +# Get the pattern of array +# +# @return p: the pattern of array +# +def GetArrayPattern(): + p = re.compile(r'[_\w]*\s*[\[.*\]]+') + return p + +## GetTypedefFuncPointerPattern() method +# +# Get the pattern of function pointer +# +# @return p: the pattern of function pointer +# +def GetTypedefFuncPointerPattern(): + p = re.compile('[_\w\s]*\([\w\s]*\*+\s*[_\w]+\s*\)\s*\(.*\)', re.DOTALL) + return p + +## GetDB() method +# +# Get global database instance +# +# @return EotGlobalData.gDb: the global database instance +# +def GetDB(): + return EotGlobalData.gDb + +## PrintErrorMsg() method +# +# print error message +# +# @param ErrorType: Type of error +# @param Msg: Error message +# @param TableName: table name of error found +# @param ItemId: id of item +# +def PrintErrorMsg(ErrorType, Msg, TableName, ItemId): + Msg = Msg.replace('\n', '').replace('\r', '') + MsgPartList = Msg.split() + Msg = '' + for Part in MsgPartList: + Msg += Part + Msg += ' ' + GetDB().TblReport.Insert(ErrorType, OtherMsg = Msg, BelongsToTable = TableName, BelongsToItem = ItemId) + +## GetIdType() method +# +# Find type of input string +# +# @param Str: String to be parsed +# +# @return Type: The type of the string +# +def GetIdType(Str): + Type = DataClass.MODEL_UNKNOWN + Str = Str.replace('#', '# ') + List = Str.split() + if List[1] == 'include': + Type = DataClass.MODEL_IDENTIFIER_INCLUDE + elif List[1] == 'define': + Type = DataClass.MODEL_IDENTIFIER_MACRO_DEFINE + elif List[1] == 'ifdef': + Type = DataClass.MODEL_IDENTIFIER_MACRO_IFDEF + elif List[1] == 'ifndef': + Type = DataClass.MODEL_IDENTIFIER_MACRO_IFNDEF + elif List[1] == 'endif': + Type = DataClass.MODEL_IDENTIFIER_MACRO_ENDIF + elif List[1] == 'pragma': + Type = DataClass.MODEL_IDENTIFIER_MACRO_PROGMA + else: + Type = DataClass.MODEL_UNKNOWN + return Type + +## GetIdentifierList() method +# +# Get id of all files +# +# @return IdList: The list of all id of files +# +def GetIdentifierList(): + IdList = [] + + for pp in FileProfile.PPDirectiveList: + Type = GetIdType(pp.Content) + IdPP = DataClass.IdentifierClass(-1, '', '', '', pp.Content, Type, -1, -1, pp.StartPos[0], pp.StartPos[1], pp.EndPos[0], pp.EndPos[1]) + IdList.append(IdPP) + + for ae in FileProfile.AssignmentExpressionList: + 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]) + IdList.append(IdAE) + + FuncDeclPattern = GetFuncDeclPattern() + ArrayPattern = GetArrayPattern() + for var in FileProfile.VariableDeclarationList: + DeclText = var.Declarator.strip() + while DeclText.startswith('*'): + var.Modifier += '*' + DeclText = DeclText.lstrip('*').strip() + var.Declarator = DeclText + if FuncDeclPattern.match(var.Declarator): + DeclSplitList = var.Declarator.split('(') + FuncName = DeclSplitList[0] + FuncNamePartList = FuncName.split() + if len(FuncNamePartList) > 1: + FuncName = FuncNamePartList[-1] + Index = 0 + while Index < len(FuncNamePartList) - 1: + var.Modifier += ' ' + FuncNamePartList[Index] + var.Declarator = var.Declarator.lstrip().lstrip(FuncNamePartList[Index]) + Index += 1 + 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]) + IdList.append(IdVar) + continue + + if var.Declarator.find('{') == -1: + for decl in var.Declarator.split(','): + DeclList = decl.split('=') + Name = DeclList[0].strip() + if ArrayPattern.match(Name): + LSBPos = var.Declarator.find('[') + var.Modifier += ' ' + Name[LSBPos:] + Name = Name[0:LSBPos] + + 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]) + IdList.append(IdVar) + else: + DeclList = var.Declarator.split('=') + Name = DeclList[0].strip() + if ArrayPattern.match(Name): + LSBPos = var.Declarator.find('[') + var.Modifier += ' ' + Name[LSBPos:] + Name = Name[0:LSBPos] + 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]) + IdList.append(IdVar) + + for enum in FileProfile.EnumerationDefinitionList: + LBPos = enum.Content.find('{') + RBPos = enum.Content.find('}') + Name = enum.Content[4:LBPos].strip() + Value = enum.Content[LBPos+1:RBPos] + IdEnum = DataClass.IdentifierClass(-1, '', '', Name, Value, DataClass.MODEL_IDENTIFIER_ENUMERATE, -1, -1, enum.StartPos[0], enum.StartPos[1], enum.EndPos[0], enum.EndPos[1]) + IdList.append(IdEnum) + + for su in FileProfile.StructUnionDefinitionList: + Type = DataClass.MODEL_IDENTIFIER_STRUCTURE + SkipLen = 6 + if su.Content.startswith('union'): + Type = DataClass.MODEL_IDENTIFIER_UNION + SkipLen = 5 + LBPos = su.Content.find('{') + RBPos = su.Content.find('}') + if LBPos == -1 or RBPos == -1: + Name = su.Content[SkipLen:].strip() + Value = '' + else: + Name = su.Content[SkipLen:LBPos].strip() + Value = su.Content[LBPos+1:RBPos] + IdPE = DataClass.IdentifierClass(-1, '', '', Name, Value, Type, -1, -1, su.StartPos[0], su.StartPos[1], su.EndPos[0], su.EndPos[1]) + IdList.append(IdPE) + + TdFuncPointerPattern = GetTypedefFuncPointerPattern() + for td in FileProfile.TypedefDefinitionList: + Modifier = '' + Name = td.ToType + Value = td.FromType + if TdFuncPointerPattern.match(td.ToType): + Modifier = td.FromType + LBPos = td.ToType.find('(') + TmpStr = td.ToType[LBPos+1:].strip() + StarPos = TmpStr.find('*') + if StarPos != -1: + Modifier += ' ' + TmpStr[0:StarPos] + while TmpStr[StarPos] == '*': + Modifier += ' ' + '*' + StarPos += 1 + TmpStr = TmpStr[StarPos:].strip() + RBPos = TmpStr.find(')') + Name = TmpStr[0:RBPos] + Value = 'FP' + TmpStr[RBPos + 1:] + + 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]) + IdList.append(IdTd) + + for funcCall in FileProfile.FunctionCallingList: + 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]) + IdList.append(IdFC) + return IdList + +## GetParamList() method +# +# Get a list of parameters +# +# @param FuncDeclarator: Function declarator +# @param FuncNameLine: Line number of function name +# @param FuncNameOffset: Offset of function name +# +# @return ParamIdList: A list of parameters +# +def GetParamList(FuncDeclarator, FuncNameLine = 0, FuncNameOffset = 0): + ParamIdList = [] + DeclSplitList = FuncDeclarator.split('(') + if len(DeclSplitList) < 2: + return ParamIdList + FuncName = DeclSplitList[0] + ParamStr = DeclSplitList[1].rstrip(')') + LineSkipped = 0 + OffsetSkipped = 0 + Start = 0 + while FuncName.find('\n', Start) != -1: + LineSkipped += 1 + OffsetSkipped = 0 + Start += FuncName.find('\n', Start) + Start += 1 + OffsetSkipped += len(FuncName[Start:]) + OffsetSkipped += 1 #skip '(' + ParamBeginLine = FuncNameLine + LineSkipped + ParamBeginOffset = OffsetSkipped + for p in ParamStr.split(','): + ListP = p.split() + if len(ListP) == 0: + continue + ParamName = ListP[-1] + DeclText = ParamName.strip() + RightSpacePos = p.rfind(ParamName) + ParamModifier = p[0:RightSpacePos] + if ParamName == 'OPTIONAL': + if ParamModifier == '': + ParamModifier += ' ' + 'OPTIONAL' + DeclText = '' + else: + ParamName = ListP[-2] + DeclText = ParamName.strip() + RightSpacePos = p.rfind(ParamName) + ParamModifier = p[0:RightSpacePos] + ParamModifier += 'OPTIONAL' + while DeclText.startswith('*'): + ParamModifier += ' ' + '*' + DeclText = DeclText.lstrip('*').strip() + ParamName = DeclText + + Start = 0 + while p.find('\n', Start) != -1: + LineSkipped += 1 + OffsetSkipped = 0 + Start += p.find('\n', Start) + Start += 1 + OffsetSkipped += len(p[Start:]) + + ParamEndLine = ParamBeginLine + LineSkipped + ParamEndOffset = OffsetSkipped + IdParam = DataClass.IdentifierClass(-1, ParamModifier, '', ParamName, '', DataClass.MODEL_IDENTIFIER_PARAMETER, -1, -1, ParamBeginLine, ParamBeginOffset, ParamEndLine, ParamEndOffset) + ParamIdList.append(IdParam) + ParamBeginLine = ParamEndLine + ParamBeginOffset = OffsetSkipped + 1 #skip ',' + + return ParamIdList + +## GetFunctionList() +# +# Get a list of functions +# +# @return FuncObjList: A list of function objects +# +def GetFunctionList(): + FuncObjList = [] + for FuncDef in FileProfile.FunctionDefinitionList: + ParamIdList = [] + DeclText = FuncDef.Declarator.strip() + while DeclText.startswith('*'): + FuncDef.Modifier += '*' + DeclText = DeclText.lstrip('*').strip() + + FuncDef.Declarator = FuncDef.Declarator.lstrip('*') + DeclSplitList = FuncDef.Declarator.split('(') + if len(DeclSplitList) < 2: + continue + + FuncName = DeclSplitList[0] + FuncNamePartList = FuncName.split() + if len(FuncNamePartList) > 1: + FuncName = FuncNamePartList[-1] + Index = 0 + while Index < len(FuncNamePartList) - 1: + FuncDef.Modifier += ' ' + FuncNamePartList[Index] + Index += 1 + + 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, []) + FuncObjList.append(FuncObj) + + return FuncObjList + +## CreateCCodeDB() method +# +# Create database for all c code +# +# @param FileNameList: A list of all c code file names +# +def CreateCCodeDB(FileNameList): + FileObjList = [] + ParseErrorFileList = [] + ParsedFiles = {} + for FullName in FileNameList: + if os.path.splitext(FullName)[1] in ('.h', '.c'): + if FullName.lower() in ParsedFiles: + continue + ParsedFiles[FullName.lower()] = 1 + EdkLogger.info("Parsing " + FullName) + model = FullName.endswith('c') and DataClass.MODEL_FILE_C or DataClass.MODEL_FILE_H + collector = CodeFragmentCollector.CodeFragmentCollector(FullName) + try: + collector.ParseFile() + except: + ParseErrorFileList.append(FullName) + BaseName = os.path.basename(FullName) + DirName = os.path.dirname(FullName) + Ext = os.path.splitext(BaseName)[1].lstrip('.') + ModifiedTime = os.path.getmtime(FullName) + FileObj = DataClass.FileClass(-1, BaseName, Ext, DirName, FullName, model, ModifiedTime, GetFunctionList(), GetIdentifierList(), []) + FileObjList.append(FileObj) + collector.CleanFileProfileBuffer() + + if len(ParseErrorFileList) > 0: + EdkLogger.info("Found unrecoverable error during parsing:\n\t%s\n" % "\n\t".join(ParseErrorFileList)) + + Db = EotGlobalData.gDb + for file in FileObjList: + Db.InsertOneFile(file) + + Db.UpdateIdentifierBelongsToFunction() + +## +# +# This acts like the main() function for the script, unless it is 'import'ed into another +# script. +# +if __name__ == '__main__': + + EdkLogger.Initialize() + EdkLogger.SetLevel(EdkLogger.QUIET) + CollectSourceCodeDataIntoDB(sys.argv[1]) + + print('Done!') |