]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/Workspace/MetaFileParser.py
BaseTools: fix imports
[mirror_edk2.git] / BaseTools / Source / Python / Workspace / MetaFileParser.py
index 470cfed5b6a35f9243196ef6288f6dfa0ec17e1a..02c8d7bbb58ca7f46bf1423d3a49394f1bb9baad 100644 (file)
@@ -15,6 +15,8 @@
 ##\r
 # Import Modules\r
 #\r
+from __future__ import print_function\r
+from __future__ import absolute_import\r
 import Common.LongFilePathOs as os\r
 import re\r
 import time\r
@@ -27,22 +29,24 @@ import Common.GlobalData as GlobalData
 from CommonDataClass.DataClass import *\r
 from Common.DataType import *\r
 from Common.StringUtils import *\r
-from Common.Misc import GuidStructureStringToGuidString, CheckPcdDatum, PathClass, AnalyzePcdData, AnalyzeDscPcd, AnalyzePcdExpression, ParseFieldValue\r
+from Common.Misc import GuidStructureStringToGuidString, CheckPcdDatum, PathClass, AnalyzePcdData, AnalyzeDscPcd, AnalyzePcdExpression, ParseFieldValue, StructPattern\r
 from Common.Expression import *\r
 from CommonDataClass.Exceptions import *\r
 from Common.LongFilePathSupport import OpenLongFilePath as open\r
 from collections import defaultdict\r
 from .MetaFileTable import MetaFileStorage\r
 from .MetaFileCommentParser import CheckInfComment\r
+from Common.DataType import TAB_COMMENT_EDK_START, TAB_COMMENT_EDK_END\r
 \r
 ## RegEx for finding file versions\r
 hexVersionPattern = re.compile(r'0[xX][\da-f-A-F]{5,8}')\r
 decVersionPattern = re.compile(r'\d+\.\d+')\r
+CODEPattern = re.compile(r"{CODE\([a-fA-F0-9Xx\{\},\s]*\)}")\r
 \r
 ## A decorator used to parse macro definition\r
 def ParseMacro(Parser):\r
     def MacroParser(self):\r
-        Match = gMacroDefPattern.match(self._CurrentLine)\r
+        Match = GlobalData.gMacroDefPattern.match(self._CurrentLine)\r
         if not Match:\r
             # Not 'DEFINE/EDK_GLOBAL' statement, call decorated method\r
             Parser(self)\r
@@ -63,7 +67,7 @@ def ParseMacro(Parser):
             EdkLogger.error('Parser', FORMAT_INVALID, "%s can only be defined via environment variable" % Name,\r
                             ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
         # Only upper case letters, digit and '_' are allowed\r
-        if not gMacroNamePattern.match(Name):\r
+        if not GlobalData.gMacroNamePattern.match(Name):\r
             EdkLogger.error('Parser', FORMAT_INVALID, "The macro name must be in the pattern [A-Z][A-Z0-9_]*",\r
                             ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
 \r
@@ -139,7 +143,7 @@ class MetaFileParser(object):
         if FilePath in Class.MetaFiles:\r
             return Class.MetaFiles[FilePath]\r
         else:\r
-            ParserObject = super().__new__(Class)\r
+            ParserObject = super(MetaFileParser, Class).__new__(Class)\r
             Class.MetaFiles[FilePath] = ParserObject\r
             return ParserObject\r
 \r
@@ -203,9 +207,7 @@ class MetaFileParser(object):
     ## Set parsing complete flag in both class and table\r
     def _Done(self):\r
         self._Finished = True\r
-        ## Do not set end flag when processing included files\r
-        if self._From == -1:\r
-            self._Table.SetEndFlag()\r
+        self._Table.SetEndFlag()\r
 \r
     def _PostProcess(self):\r
         self._PostProcessed = True\r
@@ -238,13 +240,7 @@ class MetaFileParser(object):
             DataInfo = (DataInfo,)\r
 \r
         # Parse the file first, if necessary\r
-        if not self._Finished:\r
-            if self._RawTable.IsIntegrity():\r
-                self._Finished = True\r
-            else:\r
-                self._Table = self._RawTable\r
-                self._PostProcessed = False\r
-                self.Start()\r
+        self.StartParse()\r
 \r
         # No specific ARCH or Platform given, use raw data\r
         if self._RawTable and (len(DataInfo) == 1 or DataInfo[1] is None):\r
@@ -256,6 +252,14 @@ class MetaFileParser(object):
 \r
         return self._FilterRecordList(self._Table.Query(*DataInfo), DataInfo[1])\r
 \r
+    def StartParse(self):\r
+        if not self._Finished:\r
+            if self._RawTable.IsIntegrity():\r
+                self._Finished = True\r
+            else:\r
+                self._Table = self._RawTable\r
+                self._PostProcessed = False\r
+                self.Start()\r
     ## Data parser for the common format in different type of file\r
     #\r
     #   The common format in the meatfile is like\r
@@ -559,10 +563,10 @@ class InfParser(MetaFileParser):
                     SectionComments.extend(Comments)\r
                     Comments = []\r
                 continue\r
-            if Line.find(DataType.TAB_COMMENT_EDK_START) > -1:\r
+            if Line.find(TAB_COMMENT_EDK_START) > -1:\r
                 IsFindBlockComment = True\r
                 continue\r
-            if Line.find(DataType.TAB_COMMENT_EDK_END) > -1:\r
+            if Line.find(TAB_COMMENT_EDK_END) > -1:\r
                 IsFindBlockComment = False\r
                 continue\r
             if IsFindBlockComment:\r
@@ -911,6 +915,11 @@ class DscParser(MetaFileParser):
         #\r
         self._IdMapping = {-1:-1}\r
 \r
+        self._PcdCodeValue = ""\r
+        self._PcdDataTypeCODE = False\r
+        self._CurrentPcdName = ""\r
+        self._Content = None\r
+\r
     ## Parser starter\r
     def Start(self):\r
         Content = ''\r
@@ -920,6 +929,9 @@ class DscParser(MetaFileParser):
             EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self.MetaFile)\r
 \r
         OwnerId = {}\r
+\r
+        Content = self.ProcessMultipleLineCODEValue(Content)\r
+\r
         for Index in range(0, len(Content)):\r
             Line = CleanString(Content[Index])\r
             # skip empty line\r
@@ -1131,6 +1143,41 @@ class DscParser(MetaFileParser):
     def _LibraryInstanceParser(self):\r
         self._ValueList[0] = self._CurrentLine\r
 \r
+    def ProcessMultipleLineCODEValue(self,Content):\r
+        CODEBegin = False\r
+        CODELine = ""\r
+        continuelinecount = 0\r
+        newContent = []\r
+        for Index in range(0, len(Content)):\r
+            Line = Content[Index]\r
+            if CODEBegin:\r
+                CODELine = CODELine + Line\r
+                continuelinecount +=1\r
+                if ")}" in Line:\r
+                    newContent.append(CODELine)\r
+                    for _ in range(continuelinecount):\r
+                        newContent.append("")\r
+                    CODEBegin = False\r
+                    CODELine = ""\r
+                    continuelinecount = 0\r
+            else:\r
+                if not Line:\r
+                    newContent.append(Line)\r
+                    continue\r
+                if "{CODE(" not in Line:\r
+                    newContent.append(Line)\r
+                    continue\r
+                elif CODEPattern.findall(Line):\r
+                    newContent.append(Line)\r
+                    continue\r
+                else:\r
+                    CODEBegin = True\r
+                    CODELine = Line\r
+\r
+        return newContent\r
+\r
+    def _DecodeCODEData(self):\r
+        pass\r
     ## PCD sections parser\r
     #\r
     #   [PcdsFixedAtBuild]\r
@@ -1147,7 +1194,28 @@ class DscParser(MetaFileParser):
     #\r
     @ParseMacro\r
     def _PcdParser(self):\r
+        if self._PcdDataTypeCODE:\r
+            self._PcdCodeValue = self._PcdCodeValue + "\n " + self._CurrentLine\r
+            if self._CurrentLine.endswith(")}"):\r
+                self._CurrentLine = "|".join((self._CurrentPcdName, self._PcdCodeValue))\r
+                self._PcdDataTypeCODE = False\r
+                self._PcdCodeValue = ""\r
+            else:\r
+                self._ValueList = None\r
+                return\r
         TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)\r
+        self._CurrentPcdName = TokenList[0]\r
+        if len(TokenList) == 2 and TokenList[1].strip().startswith("{CODE"):\r
+            self._PcdDataTypeCODE = True\r
+            self._PcdCodeValue = TokenList[1].strip()\r
+\r
+        if self._PcdDataTypeCODE:\r
+            if self._CurrentLine.endswith(")}"):\r
+                self._PcdDataTypeCODE = False\r
+                self._PcdCodeValue = ""\r
+            else:\r
+                self._ValueList = None\r
+                return\r
         self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT)\r
         PcdNameTockens = GetSplitValueList(TokenList[0], TAB_SPLIT)\r
         if len(PcdNameTockens) == 2:\r
@@ -1306,8 +1374,7 @@ class DscParser(MetaFileParser):
             MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR     :   self._ProcessError,\r
         }\r
 \r
-        self._Table = MetaFileStorage(self._RawTable.Cur, self.MetaFile, MODEL_FILE_DSC, True)\r
-        self._Table.Create()\r
+        self._Table = MetaFileStorage(self._RawTable.DB, self.MetaFile, MODEL_FILE_DSC, True)\r
         self._DirectiveStack = []\r
         self._DirectiveEvalStack = []\r
         self._FileWithError = self.MetaFile\r
@@ -1566,7 +1633,7 @@ class DscParser(MetaFileParser):
                 Owner = self._Content[self._ContentIndex - 1][8]\r
             else:\r
                 Owner = self._Content[self._ContentIndex - 1][0]\r
-            IncludedFileTable = MetaFileStorage(self._Table.Cur, IncludedFile1, MODEL_FILE_DSC, False, FromItem=FromItem)\r
+            IncludedFileTable = MetaFileStorage(self._RawTable.DB, IncludedFile1, MODEL_FILE_DSC, False, FromItem=FromItem)\r
             Parser = DscParser(IncludedFile1, self._FileType, self._Arch, IncludedFileTable,\r
                                Owner=Owner, From=FromItem)\r
 \r
@@ -1580,9 +1647,7 @@ class DscParser(MetaFileParser):
             Parser._Scope = self._Scope\r
             Parser._Enabled = self._Enabled\r
             # Parse the included file\r
-            Parser.Start()\r
-\r
-\r
+            Parser.StartParse()\r
             # Insert all records in the table for the included file into dsc file table\r
             Records = IncludedFileTable.GetAll()\r
             if Records:\r
@@ -1612,8 +1677,8 @@ class DscParser(MetaFileParser):
         ValList, Valid, Index = AnalyzeDscPcd(self._ValueList[2], self._ItemType)\r
         if not Valid:\r
             if self._ItemType in (MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT, MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE):\r
-                if ValList[1] != TAB_VOID and ValList[2]:\r
-                    EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect. Only VOID* type PCD need the maxsize info.", File=self._FileWithError,\r
+                if ValList[1] != TAB_VOID and StructPattern.match(ValList[1]) is None and ValList[2]:\r
+                    EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect. The datum type info should be VOID* or a valid struct name.", File=self._FileWithError,\r
                                     Line=self._LineIndex + 1, ExtraData="%s.%s|%s" % (self._ValueList[0], self._ValueList[1], self._ValueList[2]))\r
             EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self._FileWithError, Line=self._LineIndex + 1,\r
                             ExtraData="%s.%s|%s" % (self._ValueList[0], self._ValueList[1], self._ValueList[2]))\r
@@ -1905,6 +1970,17 @@ class DecParser(MetaFileParser):
         if self._ValueList[0] not in self._GuidDict:\r
             self._GuidDict[self._ValueList[0]] = self._ValueList[1]\r
 \r
+    def ParsePcdName(self,namelist):\r
+        if "[" in namelist[1]:\r
+            pcdname = namelist[1][:namelist[1].index("[")]\r
+            arrayindex = namelist[1][namelist[1].index("["):]\r
+            namelist[1] = pcdname\r
+            if len(namelist) == 2:\r
+                namelist.append(arrayindex)\r
+            else:\r
+                namelist[2] = ".".join((arrayindex,namelist[2]))\r
+        return namelist\r
+\r
     ## PCD sections parser\r
     #\r
     #   [PcdsFixedAtBuild]\r
@@ -1931,10 +2007,10 @@ class DecParser(MetaFileParser):
                     return\r
 \r
                 if self._include_flag:\r
-                    self._ValueList[1] = "<HeaderFiles>_" + md5(self._CurrentLine.encode('utf-8')).hexdigest()\r
+                    self._ValueList[1] = "<HeaderFiles>_" + md5(self._CurrentLine).hexdigest()\r
                     self._ValueList[2] = self._CurrentLine\r
                 if self._package_flag and "}" != self._CurrentLine:\r
-                    self._ValueList[1] = "<Packages>_" + md5(self._CurrentLine.encode('utf-8')).hexdigest()\r
+                    self._ValueList[1] = "<Packages>_" + md5(self._CurrentLine).hexdigest()\r
                     self._ValueList[2] = self._CurrentLine\r
                 if self._CurrentLine == "}":\r
                     self._package_flag = False\r
@@ -1943,9 +2019,16 @@ class DecParser(MetaFileParser):
                     return\r
             else:\r
                 PcdTockens = self._CurrentLine.split(TAB_VALUE_SPLIT)\r
-                PcdNames = PcdTockens[0].split(TAB_SPLIT)\r
+                PcdNames = self.ParsePcdName(PcdTockens[0].split(TAB_SPLIT))\r
                 if len(PcdNames) == 2:\r
-                    self._CurrentStructurePcdName = ""\r
+                    if PcdNames[1].strip().endswith("]"):\r
+                        PcdName = PcdNames[1][:PcdNames[1].index('[')]\r
+                        Index = PcdNames[1][PcdNames[1].index('['):]\r
+                        self._ValueList[0] = TAB_SPLIT.join((PcdNames[0],PcdName))\r
+                        self._ValueList[1] = Index\r
+                        self._ValueList[2] = PcdTockens[1]\r
+                    else:\r
+                        self._CurrentStructurePcdName = ""\r
                 else:\r
                     if self._CurrentStructurePcdName != TAB_SPLIT.join(PcdNames[:2]):\r
                         EdkLogger.error('Parser', FORMAT_INVALID, "Pcd Name does not match: %s and %s " % (self._CurrentStructurePcdName, TAB_SPLIT.join(PcdNames[:2])),\r