コード例 #1
0
    def Eval(Operator, Oprand1, Oprand2=None):
        WrnExp = None

        if Operator not in {"==", "!=", ">=", "<=", ">", "<", "in", "not in"} and \
            (isinstance(Oprand1, type('')) or isinstance(Oprand2, type(''))):
            raise BadExpression(ERR_STRING_EXPR % Operator)
        if Operator in {'in', 'not in'}:
            if not isinstance(Oprand1, type('')):
                Oprand1 = IntToStr(Oprand1)
            if not isinstance(Oprand2, type('')):
                Oprand2 = IntToStr(Oprand2)
        TypeDict = {
            type(0): 0,
            # For python2 long type
            type(sys.maxsize + 1): 0,
            type(''): 1,
            type(True): 2
        }

        EvalStr = ''
        if Operator in {"!", "NOT", "not"}:
            if isinstance(Oprand1, type('')):
                raise BadExpression(ERR_STRING_EXPR % Operator)
            EvalStr = 'not Oprand1'
        elif Operator in {"~"}:
            if isinstance(Oprand1, type('')):
                raise BadExpression(ERR_STRING_EXPR % Operator)
            EvalStr = '~ Oprand1'
        else:
            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 not isinstance(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_NECMP_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
                elif Operator in {'&', '|', '^', "and", "or"} 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 isinstance(Oprand1, type('')) and isinstance(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))
            if 'in' in Operator and isinstance(Oprand2, type('')):
                Oprand2 = Oprand2.split()
            EvalStr = 'Oprand1 ' + Operator + ' Oprand2'

        # Local symbols used by built in eval function
        Dict = {'Oprand1': Oprand1, 'Oprand2': Oprand2}
        try:
            Val = eval(EvalStr, {}, Dict)
        except Exception as Excpt:
            raise BadExpression(str(Excpt))

        if Operator in {'and', 'or'}:
            if Val:
                Val = True
            else:
                Val = False

        if WrnExp:
            WrnExp.result = Val
            raise WrnExp
        return Val
コード例 #2
0
ファイル: Expression.py プロジェクト: lersek/edk2
    def Eval(Operator, Oprand1, Oprand2 = None):
        WrnExp = None

        if Operator not in {"==", "!=", ">=", "<=", ">", "<", "in", "not in"} and \
            (isinstance(Oprand1, type('')) or isinstance(Oprand2, type(''))):
            raise BadExpression(ERR_STRING_EXPR % Operator)
        if Operator in {'in', 'not in'}:
            if not isinstance(Oprand1, type('')):
                Oprand1 = IntToStr(Oprand1)
            if not isinstance(Oprand2, type('')):
                Oprand2 = IntToStr(Oprand2)
        TypeDict = {
            type(0)  : 0,
            # For python2 long type
            type(sys.maxsize + 1) : 0,
            type('') : 1,
            type(True) : 2
        }

        EvalStr = ''
        if Operator in {"!", "NOT", "not"}:
            if isinstance(Oprand1, type('')):
                raise BadExpression(ERR_STRING_EXPR % Operator)
            EvalStr = 'not Oprand1'
        elif Operator in {"~"}:
            if isinstance(Oprand1, type('')):
                raise BadExpression(ERR_STRING_EXPR % Operator)
            EvalStr = '~ Oprand1'
        else:
            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 not isinstance(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_NECMP_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
                elif Operator in {'&', '|', '^', "and", "or"} 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 isinstance(Oprand1, type('')) and isinstance(Oprand2, type('')):
                if ((Oprand1.startswith('L"') or Oprand1.startswith("L'")) and (not Oprand2.startswith('L"')) and (not Oprand2.startswith("L'"))) or \
                        (((not Oprand1.startswith('L"')) and (not Oprand1.startswith("L'"))) and (Oprand2.startswith('L"') or Oprand2.startswith("L'"))):
                    raise BadExpression(ERR_STRING_CMP % (Oprand1, Operator, Oprand2))
            if 'in' in Operator and isinstance(Oprand2, type('')):
                Oprand2 = Oprand2.split()
            EvalStr = 'Oprand1 ' + Operator + ' Oprand2'

        # Local symbols used by built in eval function
        Dict = {
            'Oprand1' : Oprand1,
            'Oprand2' : Oprand2
        }
        try:
            Val = eval(EvalStr, {}, Dict)
        except Exception as Excpt:
            raise BadExpression(str(Excpt))

        if Operator in {'and', 'or'}:
            if Val:
                Val = True
            else:
                Val = False

        if WrnExp:
            WrnExp.result = Val
            raise WrnExp
        return Val