BaseTools: introduce !error statement

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>
Reviewed-by: Yonghong Zhu <yonghong.zhu@intel.com>
This commit is contained in:
Yunhua Feng 2018-06-17 17:22:21 +08:00 committed by Yonghong Zhu
parent 58cf30f71f
commit 09ef8e9258
4 changed files with 24 additions and 2 deletions

View File

@ -89,6 +89,7 @@ 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
@ -151,6 +152,7 @@ gErrorMessage = {
IO_TIMEOUT : "Timeout",
IO_UNKNOWN_ERROR : "Unknown error in IO operation",
ERROR_STATEMENT : "!error statement",
UNKNOWN_ERROR : "Unknown error",
}

View File

@ -471,7 +471,7 @@ 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

View File

@ -1361,6 +1361,7 @@ class FdfParser:
try:
self.Preprocess()
self.__GetError()
#
# Keep processing sections of the FDF until no new sections or a syntax error is found
#
@ -1441,6 +1442,17 @@ class FdfParser:
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

View File

@ -838,6 +838,7 @@ class DscParser(MetaFileParser):
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
@ -1028,6 +1029,8 @@ class DscParser(MetaFileParser):
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:
@ -1041,7 +1044,7 @@ class DscParser(MetaFileParser):
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 \
@ -1287,6 +1290,7 @@ class DscParser(MetaFileParser):
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)
@ -1390,6 +1394,10 @@ class DscParser(MetaFileParser):
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]