|
From: <js...@us...> - 2011-10-13 08:47:22
|
Revision: 2369
http://edk2-buildtools.svn.sourceforge.net/edk2-buildtools/?rev=2369&view=rev
Author: jsu1
Date: 2011-10-13 08:47:16 +0000 (Thu, 13 Oct 2011)
Log Message:
-----------
Update expression evaluation according following rule:
1. +/- with Boolean involved will be evaluated but report warning message, and the result will be same as regarding TRUE as 1 and FALSE as 0.
2. Comparison between string and number/Boolean:
== will always return FALSE, and warning message given
!= will always return TRUE, and warning message given
Others are not supported and error message given
3. Comparison between number and Boolean will be evaluated success, and the result will be same as regarding TRUE as 1 and FALSE as 0.
Reviewed-by: yingke
Signed-off-by: jsu1
Modified Paths:
--------------
trunk/BaseTools/Source/Python/Common/Expression.py
trunk/BaseTools/Source/Python/CommonDataClass/Exceptions.py
trunk/BaseTools/Source/Python/GenFds/FdfParser.py
trunk/BaseTools/Source/Python/Workspace/MetaFileParser.py
Modified: trunk/BaseTools/Source/Python/Common/Expression.py
===================================================================
--- trunk/BaseTools/Source/Python/Common/Expression.py 2011-10-13 05:20:11 UTC (rev 2368)
+++ trunk/BaseTools/Source/Python/Common/Expression.py 2011-10-13 08:47:16 UTC (rev 2369)
@@ -15,6 +15,7 @@
from Common.GlobalData import *
from CommonDataClass.Exceptions import BadExpression
from CommonDataClass.Exceptions import SymbolNotFound
+from CommonDataClass.Exceptions import WrnExpression
from Misc import GuidStringToGuidStructureString
ERR_STRING_EXPR = 'This operator cannot be used in string expression: [%s].'
@@ -28,7 +29,10 @@
ERR_EXPR_TYPE = 'Different types found in expression.'
ERR_OPERATOR_UNSUPPORT = 'Unsupported operator: [%s]'
ERR_REL_NOT_IN = 'Expect "IN" after "not" operator.'
-ERR_BOOL_EXPR = 'Operand of boolean type cannot be used in arithmetic expression.'
+WRN_BOOL_EXPR = 'Operand of boolean type cannot be used in arithmetic expression.'
+WRN_EQCMP_STR_OTHERS = '== Comparison between Operand of string type and Boolean/Number Type always return False.'
+WRN_NECMP_STR_OTHERS = '!= Comparison between Operand of string type and Boolean/Number Type always return True.'
+ERR_RELCMP_STR_OTHERS = 'Operator taking Operand of string type and Boolean/Number Type is not allowed: [%s].'
ERR_STRING_CMP = 'Unicode string and general string cannot be compared: [%s %s %s]'
ERR_ARRAY_TOKEN = 'Bad C array or C format GUID token: [%s].'
ERR_ARRAY_ELE = 'This must be HEX value for NList or Array: [%s].'
@@ -128,13 +132,12 @@
@staticmethod
def Eval(Operator, Oprand1, Oprand2 = None):
+ WrnExp = None
+
if Operator not in ["==", "!=", ">=", "<=", ">", "<", "in", "not in"] and \
(type(Oprand1) == type('') or type(Oprand2) == type('')):
raise BadExpression(ERR_STRING_EXPR % Operator)
- if type(Oprand1) == type(True) and Operator in ['+', '-', '&', '|', '^']:
- raise BadExpression(ERR_BOOL_EXPR)
-
TypeDict = {
type(0) : 0,
type(0L) : 0,
@@ -148,9 +151,31 @@
raise BadExpression(ERR_STRING_EXPR % Operator)
EvalStr = 'not Oprand1'
else:
- if TypeDict[type(Oprand1)] != TypeDict[type(Oprand2)]:
- raise BadExpression(ERR_EXPR_TYPE)
- if type(Oprand1) == type(''):
+ if Operator in ["+", "-"] and (type(True) in [type(Oprand1), type(Oprand2)]):
+ # Boolean in '+'/'-' will be evaluated but raise warning
+ WrnExp = WrnExpression(WRN_BOOL_EXPR)
+ elif type('') in [type(Oprand1), type(Oprand2)] and type(Oprand1)!= type(Oprand2):
+ # == between string and number/boolean will always return False, != return True
+ if Operator == "==":
+ WrnExp = WrnExpression(WRN_EQCMP_STR_OTHERS)
+ WrnExp.result = False
+ raise WrnExp
+ elif Operator == "!=":
+ WrnExp = WrnExpression(WRN_EQCMP_STR_OTHERS)
+ WrnExp.result = True
+ raise WrnExp
+ else:
+ raise BadExpression(ERR_RELCMP_STR_OTHERS % Operator)
+ elif TypeDict[type(Oprand1)] != TypeDict[type(Oprand2)]:
+ if Operator in ["==", "!=", ">=", "<=", ">", "<"] and set((TypeDict[type(Oprand1)], TypeDict[type(Oprand2)])) == set((TypeDict[type(True)], TypeDict[type(0)])):
+ # comparison between number and boolean is allowed
+ pass
+ if Operator in ['&', '|', '^', "&&", "||"] and set((TypeDict[type(Oprand1)], TypeDict[type(Oprand2)])) == set((TypeDict[type(True)], TypeDict[type(0)])):
+ # bitwise and logical operation between number and boolean is allowed
+ pass
+ else:
+ raise BadExpression(ERR_EXPR_TYPE)
+ if type(Oprand1) == type('') and type(Oprand2) == type(''):
if (Oprand1.startswith('L"') and not Oprand2.startswith('L"')) or \
(not Oprand1.startswith('L"') and Oprand2.startswith('L"')):
raise BadExpression(ERR_STRING_CMP % (Oprand1, Operator, Oprand2))
@@ -173,6 +198,10 @@
Val = True
else:
Val = False
+
+ if WrnExp:
+ WrnExp.result = Val
+ raise WrnExp
return Val
def __init__(self, Expression, SymbolTable={}):
Modified: trunk/BaseTools/Source/Python/CommonDataClass/Exceptions.py
===================================================================
--- trunk/BaseTools/Source/Python/CommonDataClass/Exceptions.py 2011-10-13 05:20:11 UTC (rev 2368)
+++ trunk/BaseTools/Source/Python/CommonDataClass/Exceptions.py 2011-10-13 08:47:16 UTC (rev 2369)
@@ -10,12 +10,6 @@
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-##
-# Import Modules
-#
-import Common.EdkLogger as EdkLogger
-
-
## Exceptions used in Expression
class EvaluationException(Exception):
pass
@@ -23,6 +17,9 @@
class BadExpression(EvaluationException):
pass
+class WrnExpression(Exception):
+ pass
+
## Exceptions used in macro replacements
class MacroException(Exception):
pass
Modified: trunk/BaseTools/Source/Python/GenFds/FdfParser.py
===================================================================
--- trunk/BaseTools/Source/Python/GenFds/FdfParser.py 2011-10-13 05:20:11 UTC (rev 2368)
+++ trunk/BaseTools/Source/Python/GenFds/FdfParser.py 2011-10-13 08:47:16 UTC (rev 2369)
@@ -712,6 +712,15 @@
return ValueExpression(Expression, InputMacroDict)()
except SymbolNotFound:
return False
+ except WrnExpression, Excpt:
+ #
+ # Catch expression evaluation warning here. We need to report
+ # the precise number of line and return the evaluation result
+ #
+ EdkLogger.warn('Parser', "Suspicious expression: %s" % str(Excpt),
+ File=self.FileName, ExtraData=self.__CurrentLine(),
+ Line=Line)
+ return Excpt.result
except Exception, Excpt:
raise Warning("Invalid expression", *FileLineTuple)
else:
Modified: trunk/BaseTools/Source/Python/Workspace/MetaFileParser.py
===================================================================
--- trunk/BaseTools/Source/Python/Workspace/MetaFileParser.py 2011-10-13 05:20:11 UTC (rev 2368)
+++ trunk/BaseTools/Source/Python/Workspace/MetaFileParser.py 2011-10-13 08:47:16 UTC (rev 2369)
@@ -1182,6 +1182,15 @@
except SymbolNotFound, Exc:
EdkLogger.debug(EdkLogger.DEBUG_5, str(Exc), self._ValueList[1])
Result = False
+ except WrnExpression, Excpt:
+ #
+ # Catch expression evaluation warning here. We need to report
+ # the precise number of line and return the evaluation result
+ #
+ EdkLogger.warn('Parser', "Suspicious expression: %s" % str(Excpt),
+ File=self._FileWithError, ExtraData=' '.join(self._ValueList),
+ Line=self._LineIndex+1)
+ Result = Excpt.result
if self._ItemType in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF,
MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF,
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|