]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/Eot/c.py
Sync EDKII BaseTools to BaseTools project r1903.
[mirror_edk2.git] / BaseTools / Source / Python / Eot / c.py
diff --git a/BaseTools/Source/Python/Eot/c.py b/BaseTools/Source/Python/Eot/c.py
new file mode 100644 (file)
index 0000000..71d2b62
--- /dev/null
@@ -0,0 +1,394 @@
+## @file\r
+# preprocess source file\r
+#\r
+#  Copyright (c) 2007 - 2010, Intel Corporation\r
+#\r
+#  All rights reserved. This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution.  The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+\r
+##\r
+# Import Modules\r
+#\r
+import sys\r
+import os\r
+import re\r
+import CodeFragmentCollector\r
+import FileProfile\r
+from CommonDataClass import DataClass\r
+from Common import EdkLogger\r
+from EotToolError import *\r
+import EotGlobalData\r
+\r
+# Global Dicts\r
+IncludeFileListDict = {}\r
+IncludePathListDict = {}\r
+ComplexTypeDict = {}\r
+SUDict = {}\r
+\r
+## GetIgnoredDirListPattern() method\r
+#\r
+#  Get the pattern of ignored direction list\r
+#\r
+#  @return p:    the pattern of ignored direction list\r
+#\r
+def GetIgnoredDirListPattern():\r
+    p = re.compile(r'.*[\\/](?:BUILD|INTELRESTRICTEDTOOLS|INTELRESTRICTEDPKG|PCCTS)[\\/].*')\r
+    return p\r
+\r
+## GetFuncDeclPattern() method\r
+#\r
+#  Get the pattern of function declaration\r
+#\r
+#  @return p:    the pattern of function declaration\r
+#\r
+def GetFuncDeclPattern():\r
+    p = re.compile(r'(EFIAPI|EFI_BOOT_SERVICE|EFI_RUNTIME_SERVICE)?\s*[_\w]+\s*\(.*\).*', re.DOTALL)\r
+    return p\r
+\r
+## GetArrayPattern() method\r
+#\r
+#  Get the pattern of array\r
+#\r
+#  @return p:    the pattern of array\r
+#\r
+def GetArrayPattern():\r
+    p = re.compile(r'[_\w]*\s*[\[.*\]]+')\r
+    return p\r
+\r
+## GetTypedefFuncPointerPattern() method\r
+#\r
+#  Get the pattern of function pointer\r
+#\r
+#  @return p:    the pattern of function pointer\r
+#\r
+def GetTypedefFuncPointerPattern():\r
+    p = re.compile('[_\w\s]*\([\w\s]*\*+\s*[_\w]+\s*\)\s*\(.*\)', re.DOTALL)\r
+    return p\r
+\r
+## GetDB() method\r
+#\r
+#  Get global database instance\r
+#\r
+#  @return EotGlobalData.gDb:    the global database instance\r
+#\r
+def GetDB():\r
+    return EotGlobalData.gDb\r
+\r
+## PrintErrorMsg() method\r
+#\r
+#  print error message\r
+#\r
+#  @param ErrorType: Type of error\r
+#  @param Msg: Error message\r
+#  @param TableName: table name of error found\r
+#  @param ItemId: id of item\r
+#\r
+def PrintErrorMsg(ErrorType, Msg, TableName, ItemId):\r
+    Msg = Msg.replace('\n', '').replace('\r', '')\r
+    MsgPartList = Msg.split()\r
+    Msg = ''\r
+    for Part in MsgPartList:\r
+        Msg += Part\r
+        Msg += ' '\r
+    GetDB().TblReport.Insert(ErrorType, OtherMsg = Msg, BelongsToTable = TableName, BelongsToItem = ItemId)\r
+\r
+## GetIdType() method\r
+#\r
+#  Find type of input string\r
+#\r
+#  @param Str: String to be parsed\r
+#\r
+#  @return Type: The type of the string\r
+#\r
+def GetIdType(Str):\r
+    Type = DataClass.MODEL_UNKNOWN\r
+    Str = Str.replace('#', '# ')\r
+    List = Str.split()\r
+    if List[1] == 'include':\r
+        Type = DataClass.MODEL_IDENTIFIER_INCLUDE\r
+    elif List[1] == 'define':\r
+        Type = DataClass.MODEL_IDENTIFIER_MACRO_DEFINE\r
+    elif List[1] == 'ifdef':\r
+        Type = DataClass.MODEL_IDENTIFIER_MACRO_IFDEF\r
+    elif List[1] == 'ifndef':\r
+        Type = DataClass.MODEL_IDENTIFIER_MACRO_IFNDEF\r
+    elif List[1] == 'endif':\r
+        Type = DataClass.MODEL_IDENTIFIER_MACRO_ENDIF\r
+    elif List[1] == 'pragma':\r
+        Type = DataClass.MODEL_IDENTIFIER_MACRO_PROGMA\r
+    else:\r
+        Type = DataClass.MODEL_UNKNOWN\r
+    return Type\r
+\r
+## GetIdentifierList() method\r
+#\r
+#  Get id of all files\r
+#\r
+#  @return IdList: The list of all id of files\r
+#\r
+def GetIdentifierList():\r
+    IdList = []\r
+\r
+    for pp in FileProfile.PPDirectiveList:\r
+        Type = GetIdType(pp.Content)\r
+        IdPP = DataClass.IdentifierClass(-1, '', '', '', pp.Content, Type, -1, -1, pp.StartPos[0],pp.StartPos[1],pp.EndPos[0],pp.EndPos[1])\r
+        IdList.append(IdPP)\r
+\r
+    for ae in FileProfile.AssignmentExpressionList:\r
+        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
+        IdList.append(IdAE)\r
+\r
+    FuncDeclPattern = GetFuncDeclPattern()\r
+    ArrayPattern = GetArrayPattern()\r
+    for var in FileProfile.VariableDeclarationList:\r
+        DeclText = var.Declarator.strip()\r
+        while DeclText.startswith('*'):\r
+            var.Modifier += '*'\r
+            DeclText = DeclText.lstrip('*').strip()\r
+        var.Declarator = DeclText\r
+        if FuncDeclPattern.match(var.Declarator):\r
+            DeclSplitList = var.Declarator.split('(')\r
+            FuncName = DeclSplitList[0]\r
+            FuncNamePartList = FuncName.split()\r
+            if len(FuncNamePartList) > 1:\r
+                FuncName = FuncNamePartList[-1]\r
+                Index = 0\r
+                while Index < len(FuncNamePartList) - 1:\r
+                    var.Modifier += ' ' + FuncNamePartList[Index]\r
+                    var.Declarator = var.Declarator.lstrip().lstrip(FuncNamePartList[Index])\r
+                    Index += 1\r
+            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
+            IdList.append(IdVar)\r
+            continue\r
+\r
+        if var.Declarator.find('{') == -1:\r
+            for decl in var.Declarator.split(','):\r
+                DeclList = decl.split('=')\r
+                Name = DeclList[0].strip()\r
+                if ArrayPattern.match(Name):\r
+                    LSBPos = var.Declarator.find('[')\r
+                    var.Modifier += ' ' + Name[LSBPos:]\r
+                    Name = Name[0:LSBPos]\r
+\r
+                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
+                IdList.append(IdVar)\r
+        else:\r
+            DeclList = var.Declarator.split('=')\r
+            Name = DeclList[0].strip()\r
+            if ArrayPattern.match(Name):\r
+                LSBPos = var.Declarator.find('[')\r
+                var.Modifier += ' ' + Name[LSBPos:]\r
+                Name = Name[0:LSBPos]\r
+            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
+            IdList.append(IdVar)\r
+\r
+    for enum in FileProfile.EnumerationDefinitionList:\r
+        LBPos = enum.Content.find('{')\r
+        RBPos = enum.Content.find('}')\r
+        Name = enum.Content[4:LBPos].strip()\r
+        Value = enum.Content[LBPos+1:RBPos]\r
+        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
+        IdList.append(IdEnum)\r
+\r
+    for su in FileProfile.StructUnionDefinitionList:\r
+        Type = DataClass.MODEL_IDENTIFIER_STRUCTURE\r
+        SkipLen = 6\r
+        if su.Content.startswith('union'):\r
+            Type = DataClass.MODEL_IDENTIFIER_UNION\r
+            SkipLen = 5\r
+        LBPos = su.Content.find('{')\r
+        RBPos = su.Content.find('}')\r
+        if LBPos == -1 or RBPos == -1:\r
+            Name = su.Content[SkipLen:].strip()\r
+            Value = ''\r
+        else:\r
+            Name = su.Content[SkipLen:LBPos].strip()\r
+            Value = su.Content[LBPos+1:RBPos]\r
+        IdPE = DataClass.IdentifierClass(-1, '', '', Name, Value, Type, -1, -1, su.StartPos[0],su.StartPos[1],su.EndPos[0],su.EndPos[1])\r
+        IdList.append(IdPE)\r
+\r
+    TdFuncPointerPattern = GetTypedefFuncPointerPattern()\r
+    for td in FileProfile.TypedefDefinitionList:\r
+        Modifier = ''\r
+        Name = td.ToType\r
+        Value = td.FromType\r
+        if TdFuncPointerPattern.match(td.ToType):\r
+            Modifier = td.FromType\r
+            LBPos = td.ToType.find('(')\r
+            TmpStr = td.ToType[LBPos+1:].strip()\r
+            StarPos = TmpStr.find('*')\r
+            if StarPos != -1:\r
+                Modifier += ' ' + TmpStr[0:StarPos]\r
+            while TmpStr[StarPos] == '*':\r
+                Modifier += ' ' + '*'\r
+                StarPos += 1\r
+            TmpStr = TmpStr[StarPos:].strip()\r
+            RBPos = TmpStr.find(')')\r
+            Name = TmpStr[0:RBPos]\r
+            Value = 'FP' + TmpStr[RBPos + 1:]\r
+\r
+        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
+        IdList.append(IdTd)\r
+\r
+    for funcCall in FileProfile.FunctionCallingList:\r
+        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
+        IdList.append(IdFC)\r
+    return IdList\r
+\r
+## GetParamList() method\r
+#\r
+#  Get a list of parameters\r
+#\r
+#  @param FuncDeclarator: Function declarator\r
+#  @param FuncNameLine: Line number of function name\r
+#  @param FuncNameOffset: Offset of function name\r
+#\r
+#  @return ParamIdList: A list of parameters\r
+#\r
+def GetParamList(FuncDeclarator, FuncNameLine = 0, FuncNameOffset = 0):\r
+    ParamIdList = []\r
+    DeclSplitList = FuncDeclarator.split('(')\r
+    if len(DeclSplitList) < 2:\r
+        return ParamIdList\r
+    FuncName = DeclSplitList[0]\r
+    ParamStr = DeclSplitList[1].rstrip(')')\r
+    LineSkipped = 0\r
+    OffsetSkipped = 0\r
+    Start = 0\r
+    while FuncName.find('\n', Start) != -1:\r
+        LineSkipped += 1\r
+        OffsetSkipped = 0\r
+        Start += FuncName.find('\n', Start)\r
+        Start += 1\r
+    OffsetSkipped += len(FuncName[Start:])\r
+    OffsetSkipped += 1 #skip '('\r
+    ParamBeginLine = FuncNameLine + LineSkipped\r
+    ParamBeginOffset = OffsetSkipped\r
+    for p in ParamStr.split(','):\r
+        ListP = p.split()\r
+        if len(ListP) == 0:\r
+            continue\r
+        ParamName = ListP[-1]\r
+        DeclText = ParamName.strip()\r
+        RightSpacePos = p.rfind(ParamName)\r
+        ParamModifier = p[0:RightSpacePos]\r
+        if ParamName == 'OPTIONAL':\r
+            if ParamModifier == '':\r
+                ParamModifier += ' ' + 'OPTIONAL'\r
+                DeclText = ''\r
+            else:\r
+                ParamName = ListP[-2]\r
+                DeclText = ParamName.strip()\r
+                RightSpacePos = p.rfind(ParamName)\r
+                ParamModifier = p[0:RightSpacePos]\r
+                ParamModifier += 'OPTIONAL'\r
+        while DeclText.startswith('*'):\r
+            ParamModifier += ' ' + '*'\r
+            DeclText = DeclText.lstrip('*').strip()\r
+        ParamName = DeclText\r
+\r
+        Start = 0\r
+        while p.find('\n', Start) != -1:\r
+            LineSkipped += 1\r
+            OffsetSkipped = 0\r
+            Start += p.find('\n', Start)\r
+            Start += 1\r
+        OffsetSkipped += len(p[Start:])\r
+\r
+        ParamEndLine = ParamBeginLine + LineSkipped\r
+        ParamEndOffset = OffsetSkipped\r
+        IdParam = DataClass.IdentifierClass(-1, ParamModifier, '', ParamName, '', DataClass.MODEL_IDENTIFIER_PARAMETER, -1, -1, ParamBeginLine, ParamBeginOffset, ParamEndLine, ParamEndOffset)\r
+        ParamIdList.append(IdParam)\r
+        ParamBeginLine = ParamEndLine\r
+        ParamBeginOffset = OffsetSkipped + 1 #skip ','\r
+\r
+    return ParamIdList\r
+\r
+## GetFunctionList()\r
+#\r
+#  Get a list of functions\r
+#\r
+#  @return FuncObjList: A list of function objects\r
+#\r
+def GetFunctionList():\r
+    FuncObjList = []\r
+    for FuncDef in FileProfile.FunctionDefinitionList:\r
+        ParamIdList = []\r
+        DeclText = FuncDef.Declarator.strip()\r
+        while DeclText.startswith('*'):\r
+            FuncDef.Modifier += '*'\r
+            DeclText = DeclText.lstrip('*').strip()\r
+\r
+        FuncDef.Declarator = FuncDef.Declarator.lstrip('*')\r
+        DeclSplitList = FuncDef.Declarator.split('(')\r
+        if len(DeclSplitList) < 2:\r
+            continue\r
+\r
+        FuncName = DeclSplitList[0]\r
+        FuncNamePartList = FuncName.split()\r
+        if len(FuncNamePartList) > 1:\r
+            FuncName = FuncNamePartList[-1]\r
+            Index = 0\r
+            while Index < len(FuncNamePartList) - 1:\r
+                FuncDef.Modifier += ' ' + FuncNamePartList[Index]\r
+                Index += 1\r
+\r
+        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
+        FuncObjList.append(FuncObj)\r
+\r
+    return FuncObjList\r
+\r
+## CreateCCodeDB() method\r
+#\r
+#  Create database for all c code\r
+#\r
+#  @param FileNameList: A list of all c code file names\r
+#\r
+def CreateCCodeDB(FileNameList):\r
+    FileObjList = []\r
+    ParseErrorFileList = []\r
+\r
+    for FullName in FileNameList:\r
+        if os.path.splitext(FullName)[1] in ('.h', '.c'):\r
+            EdkLogger.info("Parsing " + FullName)\r
+            model = FullName.endswith('c') and DataClass.MODEL_FILE_C or DataClass.MODEL_FILE_H\r
+            collector = CodeFragmentCollector.CodeFragmentCollector(FullName)\r
+            try:\r
+                collector.ParseFile()\r
+            except UnicodeError:\r
+                ParseErrorFileList.append(FullName)\r
+            BaseName = os.path.basename(FullName)\r
+            DirName = os.path.dirname(FullName)\r
+            Ext = os.path.splitext(BaseName)[1].lstrip('.')\r
+            ModifiedTime = os.path.getmtime(FullName)\r
+            FileObj = DataClass.FileClass(-1, BaseName, Ext, DirName, FullName, model, ModifiedTime, GetFunctionList(), GetIdentifierList(), [])\r
+            FileObjList.append(FileObj)\r
+            collector.CleanFileProfileBuffer()\r
+\r
+    if len(ParseErrorFileList) > 0:\r
+        EdkLogger.info("Found unrecoverable error during parsing:\n\t%s\n" % "\n\t".join(ParseErrorFileList))\r
+\r
+    Db = EotGlobalData.gDb\r
+    for file in FileObjList:\r
+        Db.InsertOneFile(file)\r
+\r
+    Db.UpdateIdentifierBelongsToFunction()\r
+\r
+##\r
+#\r
+# This acts like the main() function for the script, unless it is 'import'ed into another\r
+# script.\r
+#\r
+if __name__ == '__main__':\r
+\r
+    EdkLogger.Initialize()\r
+    EdkLogger.SetLevel(EdkLogger.QUIET)\r
+    CollectSourceCodeDataIntoDB(sys.argv[1])\r
+\r
+    print 'Done!'\r