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