summaryrefslogtreecommitdiff
path: root/BaseTools/Source/Python/UPT/Library/ExpressionValidate.py
diff options
context:
space:
mode:
Diffstat (limited to 'BaseTools/Source/Python/UPT/Library/ExpressionValidate.py')
-rw-r--r--BaseTools/Source/Python/UPT/Library/ExpressionValidate.py167
1 files changed, 125 insertions, 42 deletions
diff --git a/BaseTools/Source/Python/UPT/Library/ExpressionValidate.py b/BaseTools/Source/Python/UPT/Library/ExpressionValidate.py
index 3b476b4c48..090c7eb957 100644
--- a/BaseTools/Source/Python/UPT/Library/ExpressionValidate.py
+++ b/BaseTools/Source/Python/UPT/Library/ExpressionValidate.py
@@ -1,7 +1,7 @@
## @file
# This file is used to check PCD logical expression
#
-# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials are licensed and made available
# under the terms and conditions of the BSD License which accompanies this
@@ -106,16 +106,21 @@ class _ExprBase:
'>' : '=',
'<' : '='
}
+
for Operator in OpList:
if not self.Token[self.Index:].startswith(Operator):
continue
+
self.Index += len(Operator)
Char = self.Token[self.Index : self.Index + 1]
+
if (Operator in LetterOp and (Char == '_' or Char.isalnum())) \
or (Operator in OpMap and OpMap[Operator] == Char):
self.Index -= len(Operator)
break
+
return True
+
return False
## _LogicalExpressionParser
@@ -166,6 +171,7 @@ class _LogicalExpressionParser(_ExprBase):
return False
return True
+
return False
def IsAtomicNumVal(self):
@@ -216,32 +222,32 @@ class _LogicalExpressionParser(_ExprBase):
#
def LogicalExpression(self):
Ret = self.SpecNot()
- while self.IsCurrentOp(['||', 'OR', 'or', '&&', 'AND', 'and', 'XOR']):
+ while self.IsCurrentOp(['||', 'OR', 'or', '&&', 'AND', 'and', 'XOR', 'xor', '^']):
if self.Token[self.Index-1] == '|' and self.Parens <= 0:
- raise _ExprError(ST.ERR_EXPR_OR)
- if Ret == self.ARITH:
+ raise _ExprError(ST.ERR_EXPR_OR % self.Token)
+ if Ret not in [self.ARITH, self.LOGICAL, self.REALLOGICAL, self.STRINGITEM]:
raise _ExprError(ST.ERR_EXPR_LOGICAL % self.Token)
Ret = self.SpecNot()
- if Ret == self.ARITH:
+ if Ret not in [self.ARITH, self.LOGICAL, self.REALLOGICAL, self.STRINGITEM]:
raise _ExprError(ST.ERR_EXPR_LOGICAL % self.Token)
Ret = self.REALLOGICAL
return Ret
def SpecNot(self):
- if self.IsCurrentOp(["NOT", "!"]):
+ if self.IsCurrentOp(["NOT", "!", "not"]):
return self.SpecNot()
return self.Rel()
- ## A < B, A > B, A <= B, A >= b
+ ## A < B, A > B, A <= B, A >= B
#
def Rel(self):
Ret = self.Expr()
if self.IsCurrentOp(["<=", ">=", ">", "<", "GT", "LT", "GE", "LE",
"==", "EQ", "!=", "NE"]):
- if Ret == self.STRINGITEM or Ret == self.REALLOGICAL:
+ if Ret == self.STRINGITEM:
raise _ExprError(ST.ERR_EXPR_LOGICAL % self.Token)
Ret = self.Expr()
- if Ret == self.STRINGITEM or Ret == self.REALLOGICAL:
+ if Ret == self.REALLOGICAL:
raise _ExprError(ST.ERR_EXPR_LOGICAL % self.Token)
Ret = self.REALLOGICAL
return Ret
@@ -250,7 +256,7 @@ class _LogicalExpressionParser(_ExprBase):
#
def Expr(self):
Ret = self.Factor()
- while self.IsCurrentOp(["+", "-", "&", "|", "^"]):
+ while self.IsCurrentOp(["+", "-", "&", "|", "^", "XOR", "xor"]):
if self.Token[self.Index-1] == '|' and self.Parens <= 0:
raise _ExprError(ST.ERR_EXPR_OR)
if Ret == self.STRINGITEM or Ret == self.REALLOGICAL:
@@ -281,15 +287,15 @@ class _LogicalExpressionParser(_ExprBase):
return self.ARITH
else:
raise _ExprError(ST.ERR_EXPR_FACTOR % \
- (self.Token, self.Token[self.Index:]))
+ (self.Token[self.Index:], self.Token))
## IsValidLogicalExpression
#
def IsValidLogicalExpression(self):
if self.Len == 0:
- return False, ST.ERR_EXPR_EMPTY
+ return False, ST.ERR_EXPRESS_EMPTY
try:
- if self.LogicalExpression() == self.ARITH:
+ if self.LogicalExpression() not in [self.ARITH, self.LOGICAL, self.REALLOGICAL, self.STRINGITEM]:
return False, ST.ERR_EXPR_LOGICAL % self.Token
except _ExprError, XExcept:
return False, XExcept.Error
@@ -307,55 +313,84 @@ class _ValidRangeExpressionParser(_ExprBase):
'[\t\s]*0[xX][a-fA-F0-9]+[\t\s]*-[\t\s]*0[xX][a-fA-F0-9]+'
def __init__(self, Token):
_ExprBase.__init__(self, Token)
+ self.Parens = 0
+ self.HEX = 1
+ self.INT = 2
+ self.IsParenHappen = False
+ self.IsLogicalOpHappen = False
## IsValidRangeExpression
#
def IsValidRangeExpression(self):
if self.Len == 0:
- return False
+ return False, ST.ERR_EXPR_RANGE_EMPTY
try:
- self.RangeExpression()
- except _ExprError:
- return False
+ if self.RangeExpression() not in [self.HEX, self.INT]:
+ return False, ST.ERR_EXPR_RANGE % self.Token
+ except _ExprError, XExcept:
+ return False, XExcept.Error
+
self.SkipWhitespace()
if self.Index != self.Len:
- return False
- return True
+ return False, (ST.ERR_EXPR_RANGE % self.Token)
+ return True, ''
## RangeExpression
#
def RangeExpression(self):
- self.Unary()
- while self.IsCurrentOp(['OR', 'AND', 'XOR']):
- self.Unary()
+ Ret = self.Unary()
+ while self.IsCurrentOp(['OR', 'AND', 'and', 'or']):
+ self.IsLogicalOpHappen = True
+ if not self.IsParenHappen:
+ raise _ExprError(ST.ERR_PAREN_NOT_USED % self.Token)
+ self.IsParenHappen = False
+ Ret = self.Unary()
+
+ if self.IsCurrentOp(['XOR']):
+ Ret = self.Unary()
+
+ return Ret
## Unary
#
def Unary(self):
- if self.IsCurrentOp(["NOT", "-"]):
+ if self.IsCurrentOp(["NOT"]):
return self.Unary()
+
return self.ValidRange()
## ValidRange
#
def ValidRange(self):
+ Ret = -1
if self.IsCurrentOp(["("]):
- self.RangeExpression()
+ self.IsLogicalOpHappen = False
+ self.IsParenHappen = True
+ self.Parens += 1
+ if self.Parens > 1:
+ raise _ExprError(ST.ERR_EXPR_RANGE_DOUBLE_PAREN_NESTED % self.Token)
+ Ret = self.RangeExpression()
if not self.IsCurrentOp([")"]):
- raise _ExprError('')
- return
+ raise _ExprError(ST.ERR_EXPR_RIGHT_PAREN % self.Token)
+ self.Parens -= 1
+ return Ret
+
+ if self.IsLogicalOpHappen:
+ raise _ExprError(ST.ERR_PAREN_NOT_USED % self.Token)
- if self.IsCurrentOp(["LT", "GT", "LE", "GE", "EQ"]):
+ if self.IsCurrentOp(["LT", "GT", "LE", "GE", "EQ", "XOR"]):
IntMatch = \
re.compile(self.INT_PATTERN).match(self.Token[self.Index:])
HexMatch = \
re.compile(self.HEX_PATTERN).match(self.Token[self.Index:])
if HexMatch and HexMatch.start() == 0:
self.Index += HexMatch.end()
+ Ret = self.HEX
elif IntMatch and IntMatch.start() == 0:
self.Index += IntMatch.end()
+ Ret = self.INT
else:
- raise _ExprError('')
+ raise _ExprError(ST.ERR_EXPR_RANGE_FACTOR % (self.Token[self.Index:], self.Token))
else:
IntRangeMatch = re.compile(
self.INT_RANGE_PATTERN).match(self.Token[self.Index:]
@@ -365,15 +400,50 @@ class _ValidRangeExpressionParser(_ExprBase):
)
if HexRangeMatch and HexRangeMatch.start() == 0:
self.Index += HexRangeMatch.end()
+ Ret = self.HEX
elif IntRangeMatch and IntRangeMatch.start() == 0:
self.Index += IntRangeMatch.end()
+ Ret = self.INT
else:
- raise _ExprError('')
+ raise _ExprError(ST.ERR_EXPR_RANGE % self.Token)
+
+ return Ret
+
+## _ValidListExpressionParser
+#
+class _ValidListExpressionParser(_ExprBase):
+ VALID_LIST_PATTERN = '(0[xX][0-9a-fA-F]+|[0-9]+)([\t\s]*,[\t\s]*(0[xX][0-9a-fA-F]+|[0-9]+))*'
+ def __init__(self, Token):
+ _ExprBase.__init__(self, Token)
+ self.NUM = 1
- if self.Token[self.Index:self.Index+1] == '_' or \
- self.Token[self.Index:self.Index+1].isalnum():
- raise _ExprError('')
+ def IsValidListExpression(self):
+ if self.Len == 0:
+ return False, ST.ERR_EXPR_LIST_EMPTY
+ try:
+ if self.ListExpression() not in [self.NUM]:
+ return False, ST.ERR_EXPR_LIST % self.Token
+ except _ExprError, XExcept:
+ return False, XExcept.Error
+ self.SkipWhitespace()
+ if self.Index != self.Len:
+ return False, (ST.ERR_EXPR_LIST % self.Token)
+
+ return True, ''
+
+ def ListExpression(self):
+ Ret = -1
+ self.SkipWhitespace()
+ ListMatch = re.compile(self.VALID_LIST_PATTERN).match(self.Token[self.Index:])
+ if ListMatch and ListMatch.start() == 0:
+ self.Index += ListMatch.end()
+ Ret = self.NUM
+ else:
+ raise _ExprError(ST.ERR_EXPR_LIST % self.Token)
+
+ return Ret
+
## _StringTestParser
#
class _StringTestParser(_ExprBase):
@@ -423,37 +493,38 @@ class _StringTestParser(_ExprBase):
self.StringItem()
if not self.IsCurrentOp(["==", "EQ", "!=", "NE"]):
raise _ExprError(ST.ERR_EXPR_EQUALITY % \
- (self.Token, self.Token[self.Index:]))
+ (self.Token[self.Index:], self.Token))
self.StringItem()
if self.Index != self.Len:
raise _ExprError(ST.ERR_EXPR_BOOLEAN % \
(self.Token[self.Index:], self.Token))
##
-# Check syntax of logical expression
+# Check syntax of string test
#
-# @param Token: expression token
+# @param Token: string test token
#
-def IsValidLogicalExpr(Token, Flag=False):
+def IsValidStringTest(Token, Flag=False):
#
# Not do the check right now, keep the implementation for future enhancement.
#
if not Flag:
return True, ""
- return _LogicalExpressionParser(Token).IsValidLogicalExpression()
+ return _StringTestParser(Token).IsValidStringTest()
+
##
-# Check syntax of string test
+# Check syntax of logical expression
#
-# @param Token: string test token
+# @param Token: expression token
#
-def IsValidStringTest(Token, Flag=False):
+def IsValidLogicalExpr(Token, Flag=False):
#
# Not do the check right now, keep the implementation for future enhancement.
#
if not Flag:
return True, ""
- return _StringTestParser(Token).IsValidStringTest()
+ return _LogicalExpressionParser(Token).IsValidLogicalExpression()
##
# Check syntax of range expression
@@ -464,6 +535,14 @@ def IsValidRangeExpr(Token):
return _ValidRangeExpressionParser(Token).IsValidRangeExpression()
##
+# Check syntax of value list expression token
+#
+# @param Token: value list expression token
+#
+def IsValidListExpr(Token):
+ return _ValidListExpressionParser(Token).IsValidListExpression()
+
+##
# Check whether the feature flag expression is valid or not
#
# @param Token: feature flag expression
@@ -486,4 +565,8 @@ def IsValidFeatureFlagExp(Token, Flag=False):
return True, ""
if __name__ == '__main__':
- print _LogicalExpressionParser('a ^ b > a + b').IsValidLogicalExpression()
+# print IsValidRangeExpr('LT 9')
+ print _LogicalExpressionParser('gCrownBayTokenSpaceGuid.PcdPciDevice1BridgeAddressLE0').IsValidLogicalExpression()
+
+
+