X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=BaseTools%2FSource%2FPython%2FCommon%2FRangeExpression.py;h=e9296e03f6a1d7101714634d13eb65bd7df3dea8;hb=2e351cbe8e190271b3716284fc1076551d005472;hp=014c75b8cebde26893395b38f15203da6e00d662;hpb=0d1f5b2b5dc3c1cf381be0a1ec8f960dc6029a93;p=mirror_edk2.git diff --git a/BaseTools/Source/Python/Common/RangeExpression.py b/BaseTools/Source/Python/Common/RangeExpression.py index 014c75b8ce..e9296e03f6 100644 --- a/BaseTools/Source/Python/Common/RangeExpression.py +++ b/BaseTools/Source/Python/Common/RangeExpression.py @@ -2,13 +2,7 @@ # This file is used to parse and evaluate range expression in Pcd declaration. # # Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
-# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# SPDX-License-Identifier: BSD-2-Clause-Patent # # Import Modules # @@ -19,6 +13,7 @@ from CommonDataClass.Exceptions import WrnExpression import uuid from Common.Expression import PcdPattern, BaseExpression from Common.DataType import * +from re import compile ERR_STRING_EXPR = 'This operator cannot be used in string expression: [%s].' ERR_SNYTAX = 'Syntax error, the rest of expression cannot be evaluated: [%s].' @@ -26,7 +21,7 @@ ERR_MATCH = 'No matching right parenthesis.' ERR_STRING_TOKEN = 'Bad string token: [%s].' ERR_MACRO_TOKEN = 'Bad macro token: [%s].' ERR_EMPTY_TOKEN = 'Empty token is not allowed.' -ERR_PCD_RESOLVE = 'PCD token cannot be resolved: [%s].' +ERR_PCD_RESOLVE = 'The PCD should be FeatureFlag type or FixedAtBuild type: [%s].' ERR_VALID_TOKEN = 'No more valid token found from rest of string: [%s].' ERR_EXPR_TYPE = 'Different types found in expression.' ERR_OPERATOR_UNSUPPORT = 'Unsupported operator: [%s]' @@ -43,7 +38,7 @@ ERR_IN_OPERAND = 'Macro after IN operator can only be: $(FAMILY), $(ARCH), $(TOO class RangeObject(object): def __init__(self, start, end, empty = False): - + if int(start) < int(end): self.start = int(start) self.end = int(end) @@ -55,24 +50,24 @@ class RangeObject(object): class RangeContainer(object): def __init__(self): self.rangelist = [] - + def push(self, RangeObject): self.rangelist.append(RangeObject) self.rangelist = sorted(self.rangelist, key = lambda rangeobj : rangeobj.start) self.merge() - + def pop(self): for item in self.rangelist: yield item - - def __clean__(self): + + def __clean__(self): newrangelist = [] for rangeobj in self.rangelist: if rangeobj.empty == True: continue else: newrangelist.append(rangeobj) - self.rangelist = newrangelist + self.rangelist = newrangelist def merge(self): self.__clean__() for i in range(0, len(self.rangelist) - 1): @@ -80,23 +75,23 @@ class RangeContainer(object): continue else: self.rangelist[i + 1].start = self.rangelist[i].start - self.rangelist[i + 1].end = self.rangelist[i + 1].end > self.rangelist[i].end and self.rangelist[i + 1].end or self.rangelist[i].end + self.rangelist[i + 1].end = self.rangelist[i + 1].end > self.rangelist[i].end and self.rangelist[i + 1].end or self.rangelist[i].end self.rangelist[i].empty = True self.__clean__() - + def dump(self): print("----------------------") rangelist = "" for object in self.rangelist: rangelist = rangelist + "[%d , %d]" % (object.start, object.end) print(rangelist) - - -class XOROperatorObject(object): - def __init__(self): + + +class XOROperatorObject(object): + def __init__(self): pass - def Calculate(self, Operand, DataType, SymbolTable): + def Calculate(self, Operand, DataType, SymbolTable): if isinstance(Operand, type('')) and not Operand.isalnum(): Expr = "XOR ..." raise BadExpression(ERR_SNYTAX % Expr) @@ -108,9 +103,9 @@ class XOROperatorObject(object): return rangeId class LEOperatorObject(object): - def __init__(self): + def __init__(self): pass - def Calculate(self, Operand, DataType, SymbolTable): + def Calculate(self, Operand, DataType, SymbolTable): if isinstance(Operand, type('')) and not Operand.isalnum(): Expr = "LE ..." raise BadExpression(ERR_SNYTAX % Expr) @@ -120,22 +115,22 @@ class LEOperatorObject(object): SymbolTable[rangeId1] = rangeContainer return rangeId1 class LTOperatorObject(object): - def __init__(self): + def __init__(self): pass def Calculate(self, Operand, DataType, SymbolTable): if isinstance(Operand, type('')) and not Operand.isalnum(): - Expr = "LT ..." - raise BadExpression(ERR_SNYTAX % Expr) + Expr = "LT ..." + raise BadExpression(ERR_SNYTAX % Expr) rangeId1 = str(uuid.uuid1()) rangeContainer = RangeContainer() rangeContainer.push(RangeObject(0, int(Operand) - 1)) SymbolTable[rangeId1] = rangeContainer - return rangeId1 + return rangeId1 class GEOperatorObject(object): - def __init__(self): + def __init__(self): pass - def Calculate(self, Operand, DataType, SymbolTable): + def Calculate(self, Operand, DataType, SymbolTable): if isinstance(Operand, type('')) and not Operand.isalnum(): Expr = "GE ..." raise BadExpression(ERR_SNYTAX % Expr) @@ -143,12 +138,12 @@ class GEOperatorObject(object): rangeContainer = RangeContainer() rangeContainer.push(RangeObject(int(Operand), MAX_VAL_TYPE[DataType])) SymbolTable[rangeId1] = rangeContainer - return rangeId1 - + return rangeId1 + class GTOperatorObject(object): - def __init__(self): + def __init__(self): pass - def Calculate(self, Operand, DataType, SymbolTable): + def Calculate(self, Operand, DataType, SymbolTable): if isinstance(Operand, type('')) and not Operand.isalnum(): Expr = "GT ..." raise BadExpression(ERR_SNYTAX % Expr) @@ -156,12 +151,12 @@ class GTOperatorObject(object): rangeContainer = RangeContainer() rangeContainer.push(RangeObject(int(Operand) + 1, MAX_VAL_TYPE[DataType])) SymbolTable[rangeId1] = rangeContainer - return rangeId1 - + return rangeId1 + class EQOperatorObject(object): - def __init__(self): + def __init__(self): pass - def Calculate(self, Operand, DataType, SymbolTable): + def Calculate(self, Operand, DataType, SymbolTable): if isinstance(Operand, type('')) and not Operand.isalnum(): Expr = "EQ ..." raise BadExpression(ERR_SNYTAX % Expr) @@ -169,8 +164,8 @@ class EQOperatorObject(object): rangeContainer = RangeContainer() rangeContainer.push(RangeObject(int(Operand), int(Operand))) SymbolTable[rangeId1] = rangeContainer - return rangeId1 - + return rangeId1 + def GetOperatorObject(Operator): if Operator == '>': return GTOperatorObject() @@ -202,7 +197,7 @@ class RangeExpression(BaseExpression): NonLetterOpLst = ['+', '-', '&', '|', '^', '!', '=', '>', '<'] - RangePattern = re.compile(r'[0-9]+ - [0-9]+') + RangePattern = compile(r'[0-9]+ - [0-9]+') def preProcessRangeExpr(self, expr): # convert hex to int @@ -214,8 +209,8 @@ class RangeExpression(BaseExpression): NumberDict[HexNumber] = Number for HexNum in NumberDict: expr = expr.replace(HexNum, NumberDict[HexNum]) - - rangedict = {} + + rangedict = {} for validrange in self.RangePattern.findall(expr): start, end = validrange.split(" - ") start = start.strip() @@ -225,19 +220,19 @@ class RangeExpression(BaseExpression): rangeContainer.push(RangeObject(start, end)) self.operanddict[str(rangeid)] = rangeContainer rangedict[validrange] = str(rangeid) - + for validrange in rangedict: expr = expr.replace(validrange, rangedict[validrange]) - - self._Expr = expr + + self._Expr = expr return expr - - + + def EvalRange(self, Operator, Oprand): operatorobj = GetOperatorObject(Operator) return operatorobj.Calculate(Oprand, self.PcdDataType, self.operanddict) - + def Rangeintersection(self, Oprand1, Oprand2): rangeContainer1 = self.operanddict[Oprand1] rangeContainer2 = self.operanddict[Oprand2] @@ -266,35 +261,35 @@ class RangeExpression(BaseExpression): elif end1 >= end2: rangeid = str(uuid.uuid1()) rangeContainer.push(RangeObject(start2, end2)) - + self.operanddict[rangeid] = rangeContainer # rangeContainer.dump() return rangeid - + def Rangecollections(self, Oprand1, Oprand2): rangeContainer1 = self.operanddict[Oprand1] rangeContainer2 = self.operanddict[Oprand2] rangeContainer = RangeContainer() - + for rangeobj in rangeContainer2.pop(): rangeContainer.push(rangeobj) for rangeobj in rangeContainer1.pop(): rangeContainer.push(rangeobj) - + rangeid = str(uuid.uuid1()) self.operanddict[rangeid] = rangeContainer - + # rangeContainer.dump() return rangeid - - - def NegtiveRange(self, Oprand1): + + + def NegativeRange(self, Oprand1): rangeContainer1 = self.operanddict[Oprand1] - - + + rangeids = [] - + for rangeobj in rangeContainer1.pop(): rangeContainer = RangeContainer() rangeid = str(uuid.uuid1()) @@ -321,24 +316,24 @@ class RangeExpression(BaseExpression): re = self.Rangeintersection(rangeids[0], rangeids[1]) for i in range(2, len(rangeids)): re = self.Rangeintersection(re, rangeids[i]) - + rangeid2 = str(uuid.uuid1()) self.operanddict[rangeid2] = self.operanddict[re] return rangeid2 - + def Eval(self, Operator, Oprand1, Oprand2 = None): - + if Operator in ["!", "NOT", "not"]: if not gGuidPattern.match(Oprand1.strip()): raise BadExpression(ERR_STRING_EXPR % Operator) - return self.NegtiveRange(Oprand1) + return self.NegativeRange(Oprand1) else: if Operator in ["==", ">=", "<=", ">", "<", '^']: return self.EvalRange(Operator, Oprand1) elif Operator == 'and' : if not gGuidPatternEnd.match(Oprand1.strip()) or not gGuidPatternEnd.match(Oprand2.strip()): raise BadExpression(ERR_STRING_EXPR % Operator) - return self.Rangeintersection(Oprand1, Oprand2) + return self.Rangeintersection(Oprand1, Oprand2) elif Operator == 'or': if not gGuidPatternEnd.match(Oprand1.strip()) or not gGuidPatternEnd.match(Oprand2.strip()): raise BadExpression(ERR_STRING_EXPR % Operator) @@ -369,11 +364,11 @@ class RangeExpression(BaseExpression): self._Len = len(self._Expr) self._Token = '' self._WarnExcept = None - + # Literal token without any conversion self._LiteralToken = '' - + # store the operand object self.operanddict = {} # The Pcd max value depends on PcdDataType @@ -393,9 +388,9 @@ class RangeExpression(BaseExpression): self._Depth = Depth self._Expr = self._Expr.strip() - + self.preProcessRangeExpr(self._Expr) - + # check if the expression does not need to evaluate if RealValue and Depth == 0: self._Token = self._Expr @@ -407,12 +402,12 @@ class RangeExpression(BaseExpression): Val = self._OrExpr() RealVal = Val - + RangeIdList = RealVal.split("or") RangeList = [] for rangeid in RangeIdList: RangeList.append(self.operanddict[rangeid.strip()]) - + return RangeList # Template function to parse binary operators which have same precedence