[edk2] [Patch] BaseTools: introduce !error statement

Yonghong Zhu posted 1 patch 5 years, 10 months ago
Failed in applying to current master (apply log)
BaseTools/Source/Python/Common/BuildToolError.py    |  2 ++
BaseTools/Source/Python/Common/DataType.py          |  2 +-
BaseTools/Source/Python/GenFds/FdfParser.py         | 12 ++++++++++++
BaseTools/Source/Python/Workspace/MetaFileParser.py | 10 +++++++++-
4 files changed, 24 insertions(+), 2 deletions(-)
[edk2] [Patch] BaseTools: introduce !error statement
Posted by Yonghong Zhu 5 years, 10 months ago
From: Yunhua Feng <yunhuax.feng@intel.com>

The DSC and FDF file can use `!error` statement. The argument of this
statement is an error message, it causes build tool to stop at the
location where the statement is encountered and error message following
the `!error` statement is output as a message.

Fixes: https://bugzilla.tianocore.org/show_bug.cgi?id=701
Cc: Liming Gao <liming.gao@intel.com>
Cc: Yonghong Zhu <yonghong.zhu@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Yunhua Feng <yunhuax.feng@intel.com>
---
 BaseTools/Source/Python/Common/BuildToolError.py    |  2 ++
 BaseTools/Source/Python/Common/DataType.py          |  2 +-
 BaseTools/Source/Python/GenFds/FdfParser.py         | 12 ++++++++++++
 BaseTools/Source/Python/Workspace/MetaFileParser.py | 10 +++++++++-
 4 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/BaseTools/Source/Python/Common/BuildToolError.py b/BaseTools/Source/Python/Common/BuildToolError.py
index 27779c5..fc2503e 100644
--- a/BaseTools/Source/Python/Common/BuildToolError.py
+++ b/BaseTools/Source/Python/Common/BuildToolError.py
@@ -87,10 +87,11 @@ PCD_VALIDATION_INFO_ERROR = 0xF011
 PCD_VARIABLE_ATTRIBUTES_ERROR = 0xF012
 PCD_VARIABLE_INFO_ERROR = 0xF016
 PCD_VARIABLE_ATTRIBUTES_CONFLICT_ERROR = 0xF013
 PCD_STRUCTURE_PCD_INVALID_FIELD_ERROR = 0xF014
 PCD_STRUCTURE_PCD_ERROR = 0xF015
+ERROR_STATEMENT = 0xFFFD
 ABORT_ERROR = 0xFFFE
 UNKNOWN_ERROR = 0xFFFF
 
 ## Error message of each error code
 gErrorMessage = {
@@ -149,10 +150,11 @@ gErrorMessage = {
     IO_NOT_READY            :   "Not ready",
     IO_BUSY                 :   "Busy",
     IO_TIMEOUT              :   "Timeout",
     IO_UNKNOWN_ERROR        :   "Unknown error in IO operation",
 
+    ERROR_STATEMENT         :   "!error statement",
     UNKNOWN_ERROR           :   "Unknown error",
 }
 
 ## Exception indicating a fatal error
 class FatalError(Exception):
diff --git a/BaseTools/Source/Python/Common/DataType.py b/BaseTools/Source/Python/Common/DataType.py
index a72c7e6..154245c 100644
--- a/BaseTools/Source/Python/Common/DataType.py
+++ b/BaseTools/Source/Python/Common/DataType.py
@@ -469,11 +469,11 @@ TAB_END_IF = '!endif'
 TAB_ELSE_IF = '!elseif'
 TAB_ELSE = '!else'
 TAB_IF_DEF = '!ifdef'
 TAB_IF_N_DEF = '!ifndef'
 TAB_IF_EXIST = '!if exist'
-TAB_ERROR = '!ERROR'
+TAB_ERROR = '!error'
 
 #
 # Unknown section
 #
 TAB_UNKNOWN = 'UNKNOWN'
diff --git a/BaseTools/Source/Python/GenFds/FdfParser.py b/BaseTools/Source/Python/GenFds/FdfParser.py
index 78cb049..023cd72 100644
--- a/BaseTools/Source/Python/GenFds/FdfParser.py
+++ b/BaseTools/Source/Python/GenFds/FdfParser.py
@@ -1359,10 +1359,11 @@ class FdfParser:
     #
     def ParseFile(self):
 
         try:
             self.Preprocess()
+            self.__GetError()
             #
             # Keep processing sections of the FDF until no new sections or a syntax error is found
             #
             while self.__GetFd() or self.__GetFv() or self.__GetFmp() or self.__GetCapsule() or self.__GetVtf() or self.__GetRule() or self.__GetOptionRom():
                 pass
@@ -1439,10 +1440,21 @@ class FdfParser:
                 raise Warning("expected MACRO value", self.FileName, self.CurrentLineNumber)
             Value = self.__Token
 
         return False
 
+    ##__GetError() method
+    def __GetError(self):
+        #save the Current information
+        CurrentLine = self.CurrentLineNumber
+        CurrentOffset = self.CurrentOffsetWithinLine
+        while self.__GetNextToken():
+            if self.__Token == TAB_ERROR:
+                EdkLogger.error('FdfParser', ERROR_STATEMENT, self.__CurrentLine().replace(TAB_ERROR, '', 1), File=self.FileName, Line=self.CurrentLineNumber)
+        self.CurrentLineNumber = CurrentLine
+        self.CurrentOffsetWithinLine = CurrentOffset
+
     ## __GetFd() method
     #
     #   Get FD section contents and store its data into FD dictionary of self.Profile
     #
     #   @param  self        The object pointer
diff --git a/BaseTools/Source/Python/Workspace/MetaFileParser.py b/BaseTools/Source/Python/Workspace/MetaFileParser.py
index a2ded0c..51a788b 100644
--- a/BaseTools/Source/Python/Workspace/MetaFileParser.py
+++ b/BaseTools/Source/Python/Workspace/MetaFileParser.py
@@ -836,10 +836,11 @@ class DscParser(MetaFileParser):
         TAB_IF_N_DEF.upper()                        :   MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF,
         TAB_ELSE_IF.upper()                         :   MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF,
         TAB_ELSE.upper()                            :   MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE,
         TAB_END_IF.upper()                          :   MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF,
         TAB_USER_EXTENSIONS.upper()                 :   MODEL_META_DATA_USER_EXTENSION,
+        TAB_ERROR.upper()                           :   MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR,
     }
 
     # Valid names in define section
     DefineKeywords = [
         "DSC_SPECIFICATION",
@@ -1026,10 +1027,12 @@ class DscParser(MetaFileParser):
 
         ItemType = self.DataType[DirectiveName]
         Scope = [[TAB_COMMON, TAB_COMMON, TAB_COMMON]]
         if ItemType == MODEL_META_DATA_INCLUDE:
             Scope = self._Scope
+        elif ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR:
+            Scope = self._Scope
         if ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF:
             # Remove all directives between !if and !endif, including themselves
             while self._DirectiveStack:
                 # Remove any !else or !elseif
                 DirectiveInfo = self._DirectiveStack.pop()
@@ -1039,11 +1042,11 @@ class DscParser(MetaFileParser):
                     break
             else:
                 EdkLogger.error("Parser", FORMAT_INVALID, "Redundant '!endif'",
                                 File=self.MetaFile, Line=self._LineIndex + 1,
                                 ExtraData=self._CurrentLine)
-        elif ItemType != MODEL_META_DATA_INCLUDE:
+        elif ItemType not in {MODEL_META_DATA_INCLUDE, MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR}:
             # Break if there's a !else is followed by a !elseif
             if ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF and \
                self._DirectiveStack and \
                self._DirectiveStack[-1][0] == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE:
                 EdkLogger.error("Parser", FORMAT_INVALID, "'!elseif' after '!else'",
@@ -1285,10 +1288,11 @@ class DscParser(MetaFileParser):
             MODEL_META_DATA_COMPONENT                       :   self.__ProcessComponent,
             MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH  :   self.__ProcessSourceOverridePath,
             MODEL_META_DATA_BUILD_OPTION                    :   self.__ProcessBuildOption,
             MODEL_UNKNOWN                                   :   self._Skip,
             MODEL_META_DATA_USER_EXTENSION                  :   self._SkipUserExtension,
+            MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR     :   self._ProcessError,
         }
 
         self._Table = MetaFileStorage(self._RawTable.Cur, self.MetaFile, MODEL_FILE_DSC, True)
         self._Table.Create()
         self._DirectiveStack = []
@@ -1388,10 +1392,14 @@ class DscParser(MetaFileParser):
             self._IdMapping[Id] = self._LastItem
 
         GlobalData.gPlatformDefines.update(self._FileLocalMacros)
         self._PostProcessed = True
         self._Content = None
+    def _ProcessError(self):
+        if not self._Enabled:
+            return
+        EdkLogger.error('Parser', ERROR_STATEMENT, self._ValueList[1], File=self.MetaFile, Line=self._LineIndex + 1)
 
     def __ProcessSectionHeader(self):
         self._SectionName = self._ValueList[0]
         if self._SectionName in self.DataType:
             self._SectionType = self.DataType[self._SectionName]
-- 
2.6.1.windows.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [Patch] BaseTools: introduce !error statement
Posted by Zhu, Yonghong 5 years, 10 months ago
Reviewed-by: Yonghong Zhu <yonghong.zhu@intel.com> 

Best Regards,
Zhu Yonghong


-----Original Message-----
From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Yonghong Zhu
Sent: Tuesday, June 19, 2018 11:07 AM
To: edk2-devel@lists.01.org
Cc: Feng, YunhuaX <yunhuax.feng@intel.com>; Gao, Liming <liming.gao@intel.com>
Subject: [edk2] [Patch] BaseTools: introduce !error statement

From: Yunhua Feng <yunhuax.feng@intel.com>

The DSC and FDF file can use `!error` statement. The argument of this statement is an error message, it causes build tool to stop at the location where the statement is encountered and error message following the `!error` statement is output as a message.

Fixes: https://bugzilla.tianocore.org/show_bug.cgi?id=701
Cc: Liming Gao <liming.gao@intel.com>
Cc: Yonghong Zhu <yonghong.zhu@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Yunhua Feng <yunhuax.feng@intel.com>
---
 BaseTools/Source/Python/Common/BuildToolError.py    |  2 ++
 BaseTools/Source/Python/Common/DataType.py          |  2 +-
 BaseTools/Source/Python/GenFds/FdfParser.py         | 12 ++++++++++++
 BaseTools/Source/Python/Workspace/MetaFileParser.py | 10 +++++++++-
 4 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/BaseTools/Source/Python/Common/BuildToolError.py b/BaseTools/Source/Python/Common/BuildToolError.py
index 27779c5..fc2503e 100644
--- a/BaseTools/Source/Python/Common/BuildToolError.py
+++ b/BaseTools/Source/Python/Common/BuildToolError.py
@@ -87,10 +87,11 @@ PCD_VALIDATION_INFO_ERROR = 0xF011  PCD_VARIABLE_ATTRIBUTES_ERROR = 0xF012  PCD_VARIABLE_INFO_ERROR = 0xF016  PCD_VARIABLE_ATTRIBUTES_CONFLICT_ERROR = 0xF013  PCD_STRUCTURE_PCD_INVALID_FIELD_ERROR = 0xF014  PCD_STRUCTURE_PCD_ERROR = 0xF015
+ERROR_STATEMENT = 0xFFFD
 ABORT_ERROR = 0xFFFE
 UNKNOWN_ERROR = 0xFFFF
 
 ## Error message of each error code
 gErrorMessage = {
@@ -149,10 +150,11 @@ gErrorMessage = {
     IO_NOT_READY            :   "Not ready",
     IO_BUSY                 :   "Busy",
     IO_TIMEOUT              :   "Timeout",
     IO_UNKNOWN_ERROR        :   "Unknown error in IO operation",
 
+    ERROR_STATEMENT         :   "!error statement",
     UNKNOWN_ERROR           :   "Unknown error",
 }
 
 ## Exception indicating a fatal error
 class FatalError(Exception):
diff --git a/BaseTools/Source/Python/Common/DataType.py b/BaseTools/Source/Python/Common/DataType.py
index a72c7e6..154245c 100644
--- a/BaseTools/Source/Python/Common/DataType.py
+++ b/BaseTools/Source/Python/Common/DataType.py
@@ -469,11 +469,11 @@ TAB_END_IF = '!endif'
 TAB_ELSE_IF = '!elseif'
 TAB_ELSE = '!else'
 TAB_IF_DEF = '!ifdef'
 TAB_IF_N_DEF = '!ifndef'
 TAB_IF_EXIST = '!if exist'
-TAB_ERROR = '!ERROR'
+TAB_ERROR = '!error'
 
 #
 # Unknown section
 #
 TAB_UNKNOWN = 'UNKNOWN'
diff --git a/BaseTools/Source/Python/GenFds/FdfParser.py b/BaseTools/Source/Python/GenFds/FdfParser.py
index 78cb049..023cd72 100644
--- a/BaseTools/Source/Python/GenFds/FdfParser.py
+++ b/BaseTools/Source/Python/GenFds/FdfParser.py
@@ -1359,10 +1359,11 @@ class FdfParser:
     #
     def ParseFile(self):
 
         try:
             self.Preprocess()
+            self.__GetError()
             #
             # Keep processing sections of the FDF until no new sections or a syntax error is found
             #
             while self.__GetFd() or self.__GetFv() or self.__GetFmp() or self.__GetCapsule() or self.__GetVtf() or self.__GetRule() or self.__GetOptionRom():
                 pass
@@ -1439,10 +1440,21 @@ class FdfParser:
                 raise Warning("expected MACRO value", self.FileName, self.CurrentLineNumber)
             Value = self.__Token
 
         return False
 
+    ##__GetError() method
+    def __GetError(self):
+        #save the Current information
+        CurrentLine = self.CurrentLineNumber
+        CurrentOffset = self.CurrentOffsetWithinLine
+        while self.__GetNextToken():
+            if self.__Token == TAB_ERROR:
+                EdkLogger.error('FdfParser', ERROR_STATEMENT, self.__CurrentLine().replace(TAB_ERROR, '', 1), File=self.FileName, Line=self.CurrentLineNumber)
+        self.CurrentLineNumber = CurrentLine
+        self.CurrentOffsetWithinLine = CurrentOffset
+
     ## __GetFd() method
     #
     #   Get FD section contents and store its data into FD dictionary of self.Profile
     #
     #   @param  self        The object pointer
diff --git a/BaseTools/Source/Python/Workspace/MetaFileParser.py b/BaseTools/Source/Python/Workspace/MetaFileParser.py
index a2ded0c..51a788b 100644
--- a/BaseTools/Source/Python/Workspace/MetaFileParser.py
+++ b/BaseTools/Source/Python/Workspace/MetaFileParser.py
@@ -836,10 +836,11 @@ class DscParser(MetaFileParser):
         TAB_IF_N_DEF.upper()                        :   MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF,
         TAB_ELSE_IF.upper()                         :   MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF,
         TAB_ELSE.upper()                            :   MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE,
         TAB_END_IF.upper()                          :   MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF,
         TAB_USER_EXTENSIONS.upper()                 :   MODEL_META_DATA_USER_EXTENSION,
+        TAB_ERROR.upper()                           :   MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR,
     }
 
     # Valid names in define section
     DefineKeywords = [
         "DSC_SPECIFICATION",
@@ -1026,10 +1027,12 @@ class DscParser(MetaFileParser):
 
         ItemType = self.DataType[DirectiveName]
         Scope = [[TAB_COMMON, TAB_COMMON, TAB_COMMON]]
         if ItemType == MODEL_META_DATA_INCLUDE:
             Scope = self._Scope
+        elif ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR:
+            Scope = self._Scope
         if ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF:
             # Remove all directives between !if and !endif, including themselves
             while self._DirectiveStack:
                 # Remove any !else or !elseif
                 DirectiveInfo = self._DirectiveStack.pop() @@ -1039,11 +1042,11 @@ class DscParser(MetaFileParser):
                     break
             else:
                 EdkLogger.error("Parser", FORMAT_INVALID, "Redundant '!endif'",
                                 File=self.MetaFile, Line=self._LineIndex + 1,
                                 ExtraData=self._CurrentLine)
-        elif ItemType != MODEL_META_DATA_INCLUDE:
+        elif ItemType not in {MODEL_META_DATA_INCLUDE, MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR}:
             # Break if there's a !else is followed by a !elseif
             if ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF and \
                self._DirectiveStack and \
                self._DirectiveStack[-1][0] == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE:
                 EdkLogger.error("Parser", FORMAT_INVALID, "'!elseif' after '!else'", @@ -1285,10 +1288,11 @@ class DscParser(MetaFileParser):
             MODEL_META_DATA_COMPONENT                       :   self.__ProcessComponent,
             MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH  :   self.__ProcessSourceOverridePath,
             MODEL_META_DATA_BUILD_OPTION                    :   self.__ProcessBuildOption,
             MODEL_UNKNOWN                                   :   self._Skip,
             MODEL_META_DATA_USER_EXTENSION                  :   self._SkipUserExtension,
+            MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR     :   self._ProcessError,
         }
 
         self._Table = MetaFileStorage(self._RawTable.Cur, self.MetaFile, MODEL_FILE_DSC, True)
         self._Table.Create()
         self._DirectiveStack = []
@@ -1388,10 +1392,14 @@ class DscParser(MetaFileParser):
             self._IdMapping[Id] = self._LastItem
 
         GlobalData.gPlatformDefines.update(self._FileLocalMacros)
         self._PostProcessed = True
         self._Content = None
+    def _ProcessError(self):
+        if not self._Enabled:
+            return
+        EdkLogger.error('Parser', ERROR_STATEMENT, self._ValueList[1], 
+ File=self.MetaFile, Line=self._LineIndex + 1)
 
     def __ProcessSectionHeader(self):
         self._SectionName = self._ValueList[0]
         if self._SectionName in self.DataType:
             self._SectionType = self.DataType[self._SectionName]
--
2.6.1.windows.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel