]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/Workspace/MetaFileParser.py
BaseTools: enhance error handling for DSC file
[mirror_edk2.git] / BaseTools / Source / Python / Workspace / MetaFileParser.py
index bc45a66e49e5126d12e1383331351e65d090a1f2..2811fd1ba31e62bdb0cb5330cbac6f999266f20c 100644 (file)
@@ -1,7 +1,8 @@
 ## @file\r
 # This file is used to parse meta files\r
 #\r
-# Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2015, Hewlett Packard Enterprise Development, L.P.<BR>\r
 # 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
@@ -14,7 +15,7 @@
 ##\r
 # Import Modules\r
 #\r
-import os\r
+import Common.LongFilePathOs as os\r
 import re\r
 import time\r
 import copy\r
@@ -28,8 +29,10 @@ from Common.String import *
 from Common.Misc import GuidStructureStringToGuidString, CheckPcdDatum, PathClass, AnalyzePcdData, AnalyzeDscPcd\r
 from Common.Expression import *\r
 from CommonDataClass.Exceptions import *\r
+from Common.LongFilePathSupport import OpenLongFilePath as open\r
 \r
 from MetaFileTable import MetaFileStorage\r
+from MetaFileCommentParser import CheckInfComment\r
 \r
 ## A decorator used to parse macro definition\r
 def ParseMacro(Parser):\r
@@ -265,6 +268,10 @@ class MetaFileParser(object):
                         Line=self._LineIndex + 1, ExtraData=self._CurrentLine);\r
         self._ValueList[0:1] = [self._CurrentLine]\r
 \r
+    ## Skip unsupported data for UserExtension Section\r
+    def _SkipUserExtension(self):\r
+        self._ValueList[0:1] = [self._CurrentLine]\r
+\r
     ## Section header parser\r
     #\r
     #   The section header is always in following format:\r
@@ -336,9 +343,14 @@ class MetaFileParser(object):
         Name, Value = self._ValueList[1], self._ValueList[2]\r
         # Sometimes, we need to make differences between EDK and EDK2 modules \r
         if Name == 'INF_VERSION':\r
-            try:\r
-                self._Version = int(Value, 0)\r
-            except:\r
+            if re.match(r'0[xX][\da-f-A-F]{5,8}', Value):\r
+                self._Version = int(Value, 0)   \r
+            elif re.match(r'\d+\.\d+', Value):\r
+                ValueList = Value.split('.')\r
+                Major = '%04o' % int(ValueList[0], 0)\r
+                Minor = '%04o' % int(ValueList[1], 0)\r
+                self._Version = int('0x' + Major + Minor, 0)\r
+            else:\r
                 EdkLogger.error('Parser', FORMAT_INVALID, "Invalid version number",\r
                                 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
 \r
@@ -370,7 +382,8 @@ class MetaFileParser(object):
                 File=self.MetaFile,\r
                 Line=self._LineIndex + 1\r
                 )\r
-\r
+    def GetValidExpression(self, TokenSpaceGuid, PcdCName):\r
+        return self._Table.GetValidExpression(TokenSpaceGuid, PcdCName)\r
     def _GetMacros(self):\r
         Macros = {}\r
         Macros.update(self._FileLocalMacros)\r
@@ -590,6 +603,8 @@ class InfParser(MetaFileParser):
                 continue\r
             if Comment:\r
                 Comments.append((Comment, Index + 1))\r
+            if GlobalData.gOptions and GlobalData.gOptions.CheckUsage:\r
+                CheckInfComment(self._SectionType, Comments, str(self.MetaFile), Index + 1, self._ValueList)\r
             #\r
             # Model, Value1, Value2, Value3, Arch, Platform, BelongsToItem=-1,\r
             # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1\r
@@ -755,7 +770,7 @@ class InfParser(MetaFileParser):
         MODEL_EFI_PPI                   :   MetaFileParser._CommonParser,\r
         MODEL_EFI_DEPEX                 :   _DepexParser,\r
         MODEL_EFI_BINARY_FILE           :   _BinaryFileParser,\r
-        MODEL_META_DATA_USER_EXTENSION  :   MetaFileParser._Skip,\r
+        MODEL_META_DATA_USER_EXTENSION  :   MetaFileParser._SkipUserExtension,\r
     }\r
 \r
 ## DSC file parser class\r
@@ -795,6 +810,7 @@ class DscParser(MetaFileParser):
         TAB_ELSE_IF.upper()                         :   MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF,\r
         TAB_ELSE.upper()                            :   MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE,\r
         TAB_END_IF.upper()                          :   MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF,\r
+        TAB_USER_EXTENSIONS.upper()                 :   MODEL_META_DATA_USER_EXTENSION,\r
     }\r
 \r
     # Valid names in define section\r
@@ -805,6 +821,7 @@ class DscParser(MetaFileParser):
         "PLATFORM_VERSION",\r
         "SKUID_IDENTIFIER",\r
         "PCD_INFO_GENERATION",\r
+        "PCD_VAR_CHECK_GENERATION",\r
         "SUPPORTED_ARCHITECTURES",\r
         "BUILD_TARGETS",\r
         "OUTPUT_DIRECTORY",\r
@@ -814,7 +831,13 @@ class DscParser(MetaFileParser):
         "ISO_LANGUAGES",\r
         "TIME_STAMP_FILE",\r
         "VPD_TOOL_GUID",\r
-        "FIX_LOAD_TOP_MEMORY_ADDRESS"\r
+        "FIX_LOAD_TOP_MEMORY_ADDRESS",\r
+        "PREBUILD",\r
+        "POSTBUILD"\r
+    ]\r
+\r
+    SubSectionDefineKeywords = [\r
+        "FILE_GUID"\r
     ]\r
 \r
     SymbolPattern = ValueExpression.SymbolPattern\r
@@ -892,6 +915,8 @@ class DscParser(MetaFileParser):
             elif Line[0] == '!':\r
                 self._DirectiveParser()\r
                 continue\r
+            if Line[0] == TAB_OPTION_START and not self._InSubsection:\r
+                EdkLogger.error("Parser", FILE_READ_FAILURE, "Missing the '{' before %s in Line %s" % (Line, Index+1),ExtraData=self.MetaFile)\r
 \r
             if self._InSubsection:\r
                 SectionType = self._SubsectionType\r
@@ -995,11 +1020,6 @@ class DscParser(MetaFileParser):
                                 File=self.MetaFile, Line=self._LineIndex + 1,\r
                                 ExtraData=self._CurrentLine)\r
             self._DirectiveStack.append((ItemType, self._LineIndex + 1, self._CurrentLine))\r
-        elif self._From > 0:\r
-            EdkLogger.error('Parser', FORMAT_INVALID,\r
-                            "No '!include' allowed in included file",\r
-                            ExtraData=self._CurrentLine, File=self.MetaFile,\r
-                            Line=self._LineIndex + 1)\r
 \r
         #\r
         # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,\r
@@ -1035,13 +1055,15 @@ class DscParser(MetaFileParser):
         if not self._ValueList[2]:\r
             EdkLogger.error('Parser', FORMAT_INVALID, "No value specified",\r
                             ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
-        if not self._ValueList[1] in self.DefineKeywords:\r
+        if (not self._ValueList[1] in self.DefineKeywords and\r
+            (self._InSubsection and self._ValueList[1] not in self.SubSectionDefineKeywords)):\r
             EdkLogger.error('Parser', FORMAT_INVALID,\r
                             "Unknown keyword found: %s. "\r
                             "If this is a macro you must "\r
                             "add it as a DEFINE in the DSC" % self._ValueList[1],\r
                             ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
-        self._Defines[self._ValueList[1]] = self._ValueList[2]\r
+        if not self._InSubsection:\r
+            self._Defines[self._ValueList[1]] = self._ValueList[2]\r
         self._ItemType = self.DataType[TAB_DSC_DEFINES.upper()]\r
 \r
     @ParseMacro\r
@@ -1204,7 +1226,7 @@ class DscParser(MetaFileParser):
             MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH  :   self.__ProcessSourceOverridePath,\r
             MODEL_META_DATA_BUILD_OPTION                    :   self.__ProcessBuildOption,\r
             MODEL_UNKNOWN                                   :   self._Skip,\r
-            MODEL_META_DATA_USER_EXTENSION                  :   self._Skip,\r
+            MODEL_META_DATA_USER_EXTENSION                  :   self._SkipUserExtension,\r
         }\r
 \r
         self._Table = MetaFileStorage(self._RawTable.Cur, self.MetaFile, MODEL_FILE_DSC, True)\r
@@ -1220,6 +1242,7 @@ class DscParser(MetaFileParser):
         self.__RetrievePcdValue()\r
         self._Content = self._RawTable.GetAll()\r
         self._ContentIndex = 0\r
+        self._InSubsection = False\r
         while self._ContentIndex < len(self._Content) :\r
             Id, self._ItemType, V1, V2, V3, S1, S2, Owner, self._From, \\r
                 LineStart, ColStart, LineEnd, ColEnd, Enabled = self._Content[self._ContentIndex]\r
@@ -1248,6 +1271,10 @@ class DscParser(MetaFileParser):
             self._LineIndex = LineStart - 1\r
             self._ValueList = [V1, V2, V3]\r
 \r
+            if Owner > 0 and Owner in self._IdMapping:\r
+                self._InSubsection = True\r
+            else:\r
+                self._InSubsection = False\r
             try:\r
                 Processer[self._ItemType]()\r
             except EvaluationException, Excpt:\r
@@ -1318,18 +1345,6 @@ class DscParser(MetaFileParser):
             self._SubsectionType = MODEL_UNKNOWN\r
 \r
     def __RetrievePcdValue(self):\r
-        Records = self._RawTable.Query(MODEL_PCD_FEATURE_FLAG, BelongsToItem= -1.0)\r
-        for TokenSpaceGuid, PcdName, Value, Dummy2, Dummy3, ID, Line in Records:\r
-            Name = TokenSpaceGuid + '.' + PcdName\r
-            ValList, Valid, Index = AnalyzeDscPcd(Value, MODEL_PCD_FEATURE_FLAG)\r
-            self._Symbols[Name] = ValList[Index]\r
-\r
-        Records = self._RawTable.Query(MODEL_PCD_FIXED_AT_BUILD, BelongsToItem= -1.0)\r
-        for TokenSpaceGuid, PcdName, Value, Dummy2, Dummy3, ID, Line in Records:\r
-            Name = TokenSpaceGuid + '.' + PcdName\r
-            ValList, Valid, Index = AnalyzeDscPcd(Value, MODEL_PCD_FIXED_AT_BUILD)\r
-            self._Symbols[Name] = ValList[Index]\r
-\r
         Content = open(str(self.MetaFile), 'r').readlines()\r
         GlobalData.gPlatformOtherPcds['DSCFILE'] = str(self.MetaFile)\r
         for PcdType in (MODEL_PCD_PATCHABLE_IN_MODULE, MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_HII,\r
@@ -1350,6 +1365,13 @@ class DscParser(MetaFileParser):
 \r
         Type, Name, Value = self._ValueList\r
         Value = ReplaceMacro(Value, self._Macros, False)\r
+        #\r
+        # If it is <Defines>, return\r
+        #\r
+        if self._InSubsection:\r
+            self._ValueList = [Type, Name, Value]\r
+            return\r
+\r
         if self._ItemType == MODEL_META_DATA_DEFINE:\r
             if self._SectionType == MODEL_META_DATA_HEADER:\r
                 self._FileLocalMacros[Name] = Value\r
@@ -1462,6 +1484,12 @@ class DscParser(MetaFileParser):
             Parser = DscParser(IncludedFile1, self._FileType, IncludedFileTable,\r
                                Owner=Owner, From=Owner)\r
 \r
+            # Does not allow lower level included file to include upper level included file\r
+            if Parser._From != Owner and int(Owner) > int (Parser._From):\r
+                EdkLogger.error('parser', FILE_ALREADY_EXIST, File=self._FileWithError,\r
+                    Line=self._LineIndex + 1, ExtraData="{0} is already included at a higher level.".format(IncludedFile1))\r
+\r
+\r
             # set the parser status with current status\r
             Parser._SectionName = self._SectionName\r
             Parser._SectionType = self._SectionType\r
@@ -1501,7 +1529,7 @@ class DscParser(MetaFileParser):
 \r
         ValList, Valid, Index = AnalyzeDscPcd(self._ValueList[2], self._ItemType)\r
         if not Valid:\r
-            EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self._FileWithError, Line=self._LineIndex+1,\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
         PcdValue = ValList[Index]\r
         if PcdValue:\r
@@ -1515,7 +1543,9 @@ class DscParser(MetaFileParser):
         if ValList[Index] == 'False':\r
             ValList[Index] = '0'\r
 \r
-        GlobalData.gPlatformPcds[TAB_SPLIT.join(self._ValueList[0:2])] = PcdValue\r
+        if (not self._DirectiveEvalStack) or (False not in self._DirectiveEvalStack):\r
+            GlobalData.gPlatformPcds[TAB_SPLIT.join(self._ValueList[0:2])] = PcdValue\r
+            self._Symbols[TAB_SPLIT.join(self._ValueList[0:2])] = PcdValue\r
         self._ValueList[2] = '|'.join(ValList)\r
 \r
     def __ProcessComponent(self):\r
@@ -1546,7 +1576,7 @@ class DscParser(MetaFileParser):
         MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH  :   _CompponentSourceOverridePathParser,\r
         MODEL_META_DATA_BUILD_OPTION                    :   _BuildOptionParser,\r
         MODEL_UNKNOWN                                   :   MetaFileParser._Skip,\r
-        MODEL_META_DATA_USER_EXTENSION                  :   MetaFileParser._Skip,\r
+        MODEL_META_DATA_USER_EXTENSION                  :   MetaFileParser._SkipUserExtension,\r
         MODEL_META_DATA_SECTION_HEADER                  :   MetaFileParser._SectionHeaderParser,\r
         MODEL_META_DATA_SUBSECTION_HEADER               :   _SubsectionHeaderParser,\r
     }\r
@@ -1575,6 +1605,7 @@ class DecParser(MetaFileParser):
         TAB_PCDS_FEATURE_FLAG_NULL.upper()          :   MODEL_PCD_FEATURE_FLAG,\r
         TAB_PCDS_DYNAMIC_NULL.upper()               :   MODEL_PCD_DYNAMIC,\r
         TAB_PCDS_DYNAMIC_EX_NULL.upper()            :   MODEL_PCD_DYNAMIC_EX,\r
+        TAB_USER_EXTENSIONS.upper()                 :   MODEL_META_DATA_USER_EXTENSION,\r
     }\r
 \r
     ## Constructor of DecParser\r
@@ -1859,7 +1890,7 @@ class DecParser(MetaFileParser):
         MODEL_PCD_DYNAMIC               :   _PcdParser,\r
         MODEL_PCD_DYNAMIC_EX            :   _PcdParser,\r
         MODEL_UNKNOWN                   :   MetaFileParser._Skip,\r
-        MODEL_META_DATA_USER_EXTENSION  :   MetaFileParser._Skip,\r
+        MODEL_META_DATA_USER_EXTENSION  :   MetaFileParser._SkipUserExtension,\r
     }\r
 \r
 ##\r