# # @file\r
# This file is used to parse and evaluate range expression in Pcd declaration.\r
#\r
-# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
# This program and the accompanying materials\r
# are licensed and made available under the terms and conditions of the BSD License\r
# which accompanies this distribution. The full text of the license may be found at\r
from CommonDataClass.Exceptions import BadExpression\r
from CommonDataClass.Exceptions import WrnExpression\r
import uuid\r
+from Common.Expression import PcdPattern\r
+from Common.DataType import *\r
\r
ERR_STRING_EXPR = 'This operator cannot be used in string expression: [%s].'\r
ERR_SNYTAX = 'Syntax error, the rest of expression cannot be evaluated: [%s].'\r
ERR_EMPTY_EXPR = 'Empty expression is not allowed.'\r
ERR_IN_OPERAND = 'Macro after IN operator can only be: $(FAMILY), $(ARCH), $(TOOL_CHAIN_TAG) and $(TARGET).'\r
\r
-def MaxOfType(DataType):\r
- if DataType == 'UINT8':\r
- return int('0xFF', 16)\r
- if DataType == 'UINT16':\r
- return int('0xFFFF', 16)\r
- if DataType == 'UINT32':\r
- return int('0xFFFFFFFF', 16)\r
- if DataType == 'UINT64':\r
- return int('0xFFFFFFFFFFFFFFFF', 16)\r
-\r
class RangeObject(object):\r
def __init__(self, start, end, empty = False):\r
\r
rangeId = str(uuid.uuid1())\r
rangeContainer = RangeContainer()\r
rangeContainer.push(RangeObject(0, int(Operand) - 1))\r
- rangeContainer.push(RangeObject(int(Operand) + 1, MaxOfType(DataType)))\r
+ rangeContainer.push(RangeObject(int(Operand) + 1, MAX_VAL_TYPE[DataType]))\r
SymbolTable[rangeId] = rangeContainer\r
return rangeId\r
\r
raise BadExpression(ERR_SNYTAX % Expr)\r
rangeId1 = str(uuid.uuid1())\r
rangeContainer = RangeContainer()\r
- rangeContainer.push(RangeObject(int(Operand), MaxOfType(DataType)))\r
+ rangeContainer.push(RangeObject(int(Operand), MAX_VAL_TYPE[DataType]))\r
SymbolTable[rangeId1] = rangeContainer\r
return rangeId1 \r
\r
raise BadExpression(ERR_SNYTAX % Expr)\r
rangeId1 = str(uuid.uuid1())\r
rangeContainer = RangeContainer()\r
- rangeContainer.push(RangeObject(int(Operand) + 1, MaxOfType(DataType)))\r
+ rangeContainer.push(RangeObject(int(Operand) + 1, MAX_VAL_TYPE[DataType]))\r
SymbolTable[rangeId1] = rangeContainer\r
return rangeId1 \r
\r
\r
NonLetterOpLst = ['+', '-', '&', '|', '^', '!', '=', '>', '<']\r
\r
- PcdPattern = re.compile(r'[_a-zA-Z][0-9A-Za-z_]*\.[_a-zA-Z][0-9A-Za-z_]*$')\r
- HexPattern = re.compile(r'0[xX][0-9a-fA-F]+')\r
- RegGuidPattern = re.compile(r'[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}')\r
- ExRegGuidPattern = re.compile(r'[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$')\r
- \r
- SymbolPattern = re.compile("("\r
- "\$\([A-Z][A-Z0-9_]*\)|\$\(\w+\.\w+\)|\w+\.\w+|"\r
- "&&|\|\||!(?!=)|"\r
- "(?<=\W)AND(?=\W)|(?<=\W)OR(?=\W)|(?<=\W)NOT(?=\W)|(?<=\W)XOR(?=\W)|"\r
- "(?<=\W)EQ(?=\W)|(?<=\W)NE(?=\W)|(?<=\W)GT(?=\W)|(?<=\W)LT(?=\W)|(?<=\W)GE(?=\W)|(?<=\W)LE(?=\W)"\r
- ")")\r
- \r
RangePattern = re.compile(r'[0-9]+ - [0-9]+')\r
\r
def preProcessRangeExpr(self, expr):\r
# convert interval to object index. ex. 1 - 10 to a GUID\r
expr = expr.strip()\r
NumberDict = {}\r
- for HexNumber in self.HexPattern.findall(expr):\r
+ for HexNumber in gHexPattern.findall(expr):\r
Number = str(int(HexNumber, 16))\r
NumberDict[HexNumber] = Number\r
for HexNum in NumberDict:\r
rangeContainer = RangeContainer()\r
for range1 in rangeContainer1.pop():\r
for range2 in rangeContainer2.pop():\r
- if range1.start >= range2.start:\r
- start = range1.start\r
- end = range1.end\r
- range1.start = range2.start\r
- range1.end = range2.end\r
- range2.start = start\r
- range2.end = end\r
+ start1 = range1.start\r
+ end1 = range1.end\r
+ start2 = range2.start\r
+ end2 = range2.end\r
+ if start1 >= start2:\r
+ start1, start2 = start2, start1\r
+ end1, end2 = end2, end1\r
if range1.empty:\r
rangeid = str(uuid.uuid1())\r
rangeContainer.push(RangeObject(0, 0, True))\r
- if range1.end < range2.start:\r
+ if end1 < start2:\r
rangeid = str(uuid.uuid1())\r
rangeContainer.push(RangeObject(0, 0, True))\r
- elif range1.end == range2.start:\r
+ elif end1 == start2:\r
rangeid = str(uuid.uuid1())\r
- rangeContainer.push(RangeObject(range1.end, range1.end))\r
- elif range1.end <= range2.end and range1.end > range2.start:\r
+ rangeContainer.push(RangeObject(end1, end1))\r
+ elif end1 <= end2 and end1 > start2:\r
rangeid = str(uuid.uuid1())\r
- rangeContainer.push(RangeObject(range2.start, range1.end))\r
- elif range1.end >= range2.end:\r
+ rangeContainer.push(RangeObject(start2, end1))\r
+ elif end1 >= end2:\r
rangeid = str(uuid.uuid1())\r
- rangeContainer.push(RangeObject(range2.start, range2.end))\r
+ rangeContainer.push(RangeObject(start2, end2))\r
\r
self.operanddict[rangeid] = rangeContainer\r
# rangeContainer.dump()\r
rangeContainer = RangeContainer()\r
rangeid = str(uuid.uuid1())\r
if rangeobj.empty:\r
- rangeContainer.push(RangeObject(0, MaxOfType(self.PcdDataType)))\r
+ rangeContainer.push(RangeObject(0, MAX_VAL_TYPE[self.PcdDataType]))\r
else:\r
if rangeobj.start > 0:\r
rangeContainer.push(RangeObject(0, rangeobj.start - 1))\r
- if rangeobj.end < MaxOfType(self.PcdDataType):\r
- rangeContainer.push(RangeObject(rangeobj.end + 1, MaxOfType(self.PcdDataType)))\r
+ if rangeobj.end < MAX_VAL_TYPE[self.PcdDataType]:\r
+ rangeContainer.push(RangeObject(rangeobj.end + 1, MAX_VAL_TYPE[self.PcdDataType]))\r
self.operanddict[rangeid] = rangeContainer\r
rangeids.append(rangeid)\r
\r
if len(rangeids) == 0:\r
rangeContainer = RangeContainer()\r
- rangeContainer.push(RangeObject(0, MaxOfType(self.PcdDataType)))\r
+ rangeContainer.push(RangeObject(0, MAX_VAL_TYPE[self.PcdDataType]))\r
rangeid = str(uuid.uuid1())\r
self.operanddict[rangeid] = rangeContainer\r
return rangeid\r
def Eval(self, Operator, Oprand1, Oprand2 = None):\r
\r
if Operator in ["!", "NOT", "not"]:\r
- if not self.RegGuidPattern.match(Oprand1.strip()):\r
+ if not gGuidPattern.match(Oprand1.strip()):\r
raise BadExpression(ERR_STRING_EXPR % Operator)\r
return self.NegtiveRange(Oprand1)\r
else:\r
if Operator in ["==", ">=", "<=", ">", "<", '^']:\r
return self.EvalRange(Operator, Oprand1)\r
elif Operator == 'and' :\r
- if not self.ExRegGuidPattern.match(Oprand1.strip()) or not self.ExRegGuidPattern.match(Oprand2.strip()):\r
+ if not gGuidPatternEnd.match(Oprand1.strip()) or not gGuidPatternEnd.match(Oprand2.strip()):\r
raise BadExpression(ERR_STRING_EXPR % Operator)\r
return self.Rangeintersection(Oprand1, Oprand2) \r
elif Operator == 'or':\r
- if not self.ExRegGuidPattern.match(Oprand1.strip()) or not self.ExRegGuidPattern.match(Oprand2.strip()):\r
+ if not gGuidPatternEnd.match(Oprand1.strip()) or not gGuidPatternEnd.match(Oprand2.strip()):\r
raise BadExpression(ERR_STRING_EXPR % Operator)\r
return self.Rangecollections(Oprand1, Oprand2)\r
else:\r
# check if the expression does not need to evaluate\r
if RealValue and Depth == 0:\r
self._Token = self._Expr\r
- if self.ExRegGuidPattern.match(self._Expr):\r
+ if gGuidPatternEnd.match(self._Expr):\r
return [self.operanddict[self._Expr] ]\r
\r
self._Idx = 0\r
raise BadExpression(ERR_EMPTY_TOKEN)\r
\r
# PCD token\r
- if self.PcdPattern.match(self._Token):\r
+ if PcdPattern.match(self._Token):\r
if self._Token not in self._Symb:\r
Ex = BadExpression(ERR_PCD_RESOLVE % self._Token)\r
Ex.Pcd = self._Token\r
self._LiteralToken.endswith('}'):\r
return True\r
\r
- if self.HexPattern.match(self._LiteralToken):\r
+ if gHexPattern.match(self._LiteralToken):\r
Token = self._LiteralToken[2:]\r
Token = Token.lstrip('0')\r
if not Token:\r
self._Token = ''\r
if Expr:\r
Ch = Expr[0]\r
- Match = self.RegGuidPattern.match(Expr)\r
+ Match = gGuidPattern.match(Expr)\r
if Match and not Expr[Match.end():Match.end() + 1].isalnum() \\r
and Expr[Match.end():Match.end() + 1] != '_':\r
self._Idx += Match.end()\r