diff --git a/muparser-2.2.5/src/muParser.cpp b/muparser-2.2.5/src/muParser.cpp index 96af93de9..9b6271b94 100644 --- a/muparser-2.2.5/src/muParser.cpp +++ b/muparser-2.2.5/src/muParser.cpp @@ -272,6 +272,14 @@ void Parser::InitFun() { } } +/// assert that the given optional error \p oerr is not an error. +/// This is used only during initialization, when it ought to be impossible +/// to generate an error. +static void assertNoError(OptionalError oerr) { + assert(!oerr.has_error() && "Unexpected error during initialization"); + (void)oerr; +} + //--------------------------------------------------------------------------- /** \brief Initialize constants. @@ -279,13 +287,8 @@ void Parser::InitFun() { number ("_e"). */ void Parser::InitConst() { - OptionalError oerr; - oerr = DefineConst(_T("_pi"), (value_type)PARSER_CONST_PI); - assert(!oerr.has_error() && "Error defining _pi constant"); - (void)oerr; - oerr = DefineConst(_T("_e"), (value_type)PARSER_CONST_E); - assert(!oerr.has_error() && "Error defining _e constant"); - (void)oerr; + assertNoError(DefineConst(_T("_pi"), (value_type)PARSER_CONST_PI)); + assertNoError(DefineConst(_T("_e"), (value_type)PARSER_CONST_E)); } //--------------------------------------------------------------------------- @@ -294,8 +297,8 @@ void Parser::InitConst() { By default only the unary minus operator is added. */ void Parser::InitOprt() { - DefineInfixOprt(_T("-"), UnaryMinus); - DefineInfixOprt(_T("+"), UnaryPlus); + assertNoError(DefineInfixOprt(_T("-"), UnaryMinus)); + assertNoError(DefineInfixOprt(_T("+"), UnaryPlus)); } //--------------------------------------------------------------------------- diff --git a/muparser-2.2.5/src/muParserInt.cpp b/muparser-2.2.5/src/muParserInt.cpp index aa9ee6a01..d5c47380e 100644 --- a/muparser-2.2.5/src/muParserInt.cpp +++ b/muparser-2.2.5/src/muParserInt.cpp @@ -207,6 +207,14 @@ void ParserInt::InitFun() { DefineFun(_T("max"), Max); } +/// assert that the given optional error \p oerr is not an error. +/// This is used only during initialization, when it ought to be impossible +/// to generate an error. +static void assertNoError(OptionalError oerr) { + assert(!oerr.has_error() && "Unexpected error during initialization"); + (void)oerr; +} + //--------------------------------------------------------------------------- /** \brief Initialize operators. */ void ParserInt::InitOprt() { @@ -216,31 +224,31 @@ void ParserInt::InitOprt() { // Disable all built in operators, they wont work with integer numbers // since they are designed for floating point numbers - DefineInfixOprt(_T("-"), UnaryMinus); - DefineInfixOprt(_T("!"), Not); + assertNoError(DefineInfixOprt(_T("-"), UnaryMinus)); + assertNoError(DefineInfixOprt(_T("!"), Not)); - (void)DefineOprt(_T("&"), LogAnd, prLOGIC); - (void)DefineOprt(_T("|"), LogOr, prLOGIC); - (void)DefineOprt(_T("&&"), And, prLOGIC); - (void)DefineOprt(_T("||"), Or, prLOGIC); + assertNoError(DefineOprt(_T("&"), LogAnd, prLOGIC)); + assertNoError(DefineOprt(_T("|"), LogOr, prLOGIC)); + assertNoError(DefineOprt(_T("&&"), And, prLOGIC)); + assertNoError(DefineOprt(_T("||"), Or, prLOGIC)); - (void)DefineOprt(_T("<"), Less, prCMP); - (void)DefineOprt(_T(">"), Greater, prCMP); - (void)DefineOprt(_T("<="), LessEq, prCMP); - (void)DefineOprt(_T(">="), GreaterEq, prCMP); - (void)DefineOprt(_T("=="), Equal, prCMP); - (void)DefineOprt(_T("!="), NotEqual, prCMP); + assertNoError(DefineOprt(_T("<"), Less, prCMP)); + assertNoError(DefineOprt(_T(">"), Greater, prCMP)); + assertNoError(DefineOprt(_T("<="), LessEq, prCMP)); + assertNoError(DefineOprt(_T(">="), GreaterEq, prCMP)); + assertNoError(DefineOprt(_T("=="), Equal, prCMP)); + assertNoError(DefineOprt(_T("!="), NotEqual, prCMP)); - (void)DefineOprt(_T("+"), Add, prADD_SUB); - (void)DefineOprt(_T("-"), Sub, prADD_SUB); + assertNoError(DefineOprt(_T("+"), Add, prADD_SUB)); + assertNoError(DefineOprt(_T("-"), Sub, prADD_SUB)); - (void)DefineOprt(_T("*"), Mul, prMUL_DIV); - (void)DefineOprt(_T("/"), Div, prMUL_DIV); - (void)DefineOprt(_T("%"), Mod, prMUL_DIV); + assertNoError(DefineOprt(_T("*"), Mul, prMUL_DIV)); + assertNoError(DefineOprt(_T("/"), Div, prMUL_DIV)); + assertNoError(DefineOprt(_T("%"), Mod, prMUL_DIV)); - (void)DefineOprt(_T("^"), Pow, prPOW, oaRIGHT); - (void)DefineOprt(_T(">>"), Shr, prMUL_DIV + 1); - (void)DefineOprt(_T("<<"), Shl, prMUL_DIV + 1); + assertNoError(DefineOprt(_T("^"), Pow, prPOW, oaRIGHT)); + assertNoError(DefineOprt(_T(">>"), Shr, prMUL_DIV + 1)); + assertNoError(DefineOprt(_T("<<"), Shl, prMUL_DIV + 1)); } } // namespace mu diff --git a/muparser-2.2.5/src/muParserTest.cpp b/muparser-2.2.5/src/muParserTest.cpp index ac0b2ce83..188759657 100644 --- a/muparser-2.2.5/src/muParserTest.cpp +++ b/muparser-2.2.5/src/muParserTest.cpp @@ -47,6 +47,12 @@ static value_type getOrThrow(mu::ValueOrError voerr) { return *voerr; } +static void throwIfError(mu::OptionalError oerr) { + if (oerr.has_error()) { + throw oerr.error(); + } +} + int ParserTester::c_iCount = 0; //--------------------------------------------------------------------------------------------- @@ -95,10 +101,10 @@ int ParserTester::TestInterface() { Parser p; try { - p.DefineVar(_T("a"), &afVal[0]); - p.DefineVar(_T("b"), &afVal[1]); - p.DefineVar(_T("c"), &afVal[2]); - p.SetExpr(_T("a+b+c")); + throwIfError(p.DefineVar(_T("a"), &afVal[0])); + throwIfError(p.DefineVar(_T("b"), &afVal[1])); + throwIfError(p.DefineVar(_T("c"), &afVal[2])); + throwIfError(p.SetExpr(_T("a+b+c"))); getOrThrow(p.Eval()); } catch (...) { iStat += 1; // this is not supposed to happen @@ -283,21 +289,17 @@ int ParserTester::TestBinOprt() { //--------------------------------------------------------------------------------------------- /** \brief Check muParser name restriction enforcement. */ int ParserTester::TestNames() { - int iStat = 0, iErr = 0; + int failures = 0; mu::console() << "testing name restriction enforcement..."; Parser p; + OptionalError oerr; -#define PARSER_THROWCHECK(DOMAIN, FAIL, EXPR, ARG) \ - iErr = 0; \ - ParserTester::c_iCount++; \ - try { \ - p.Define##DOMAIN(EXPR, ARG); \ - } catch (Parser::exception_type &) { \ - iErr = (FAIL == false) ? 0 : 1; \ - } \ - iStat += iErr; +#define PARSER_THROWCHECK(DOMAIN, SHOULDPASS, EXPR, ARG) \ + ParserTester::c_iCount++; \ + oerr = p.Define##DOMAIN(EXPR, ARG); \ + failures += (oerr.has_error() == SHOULDPASS); // constant names PARSER_THROWCHECK(Const, false, _T("0a"), 1) @@ -374,12 +376,12 @@ int ParserTester::TestNames() { PARSER_THROWCHECK(Oprt, true, _T("||"), f1of2) #undef PARSER_THROWCHECK - if (iStat == 0) + if (failures == 0) mu::console() << _T("passed") << endl; else - mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl; + mu::console() << _T("\n failed with ") << failures << _T(" errors") << endl; - return iStat; + return failures; } //--------------------------------------------------------------------------- @@ -970,17 +972,17 @@ int ParserTester::ThrowTest(const string_type &a_str, int a_iErrc, bool a_bFail) value_type fVal[] = {1, 1, 1}; Parser p; - p.DefineVar(_T("a"), &fVal[0]); - p.DefineVar(_T("b"), &fVal[1]); - p.DefineVar(_T("c"), &fVal[2]); - p.DefinePostfixOprt(_T("{m}"), Milli); - p.DefinePostfixOprt(_T("m"), Milli); + throwIfError(p.DefineVar(_T("a"), &fVal[0])); + throwIfError(p.DefineVar(_T("b"), &fVal[1])); + throwIfError(p.DefineVar(_T("c"), &fVal[2])); + throwIfError(p.DefinePostfixOprt(_T("{m}"), Milli)); + throwIfError(p.DefinePostfixOprt(_T("m"), Milli)); p.DefineFun(_T("ping"), Ping); p.DefineFun(_T("valueof"), ValueOf); p.DefineFun(_T("strfun1"), StrFun1); p.DefineFun(_T("strfun2"), StrFun2); p.DefineFun(_T("strfun3"), StrFun3); - p.SetExpr(a_str); + throwIfError(p.SetExpr(a_str)); getOrThrow(p.Eval()); } catch (ParserError &e) { // output the formula in case of an failed test @@ -1021,8 +1023,8 @@ int ParserTester::EqnTestWithVarChange(const string_type &a_str, double a_fVar1, value_type var = 0; // variable - p.DefineVar(_T("a"), &var); - p.SetExpr(a_str); + throwIfError(p.DefineVar(_T("a"), &var)); + throwIfError(p.SetExpr(a_str)); var = a_fVar1; fVal[0] = getOrThrow(p.Eval()); @@ -1069,21 +1071,21 @@ int ParserTester::EqnTest(const string_type &a_str, double a_fRes, bool a_fPass) p1.reset(new mu::Parser()); // Add constants - p1->DefineConst(_T("pi"), (value_type)PARSER_CONST_PI); - p1->DefineConst(_T("e"), (value_type)PARSER_CONST_E); - p1->DefineConst(_T("const"), 1); - p1->DefineConst(_T("const1"), 2); - p1->DefineConst(_T("const2"), 3); + throwIfError(p1->DefineConst(_T("pi"), (value_type)PARSER_CONST_PI)); + throwIfError(p1->DefineConst(_T("e"), (value_type)PARSER_CONST_E)); + throwIfError(p1->DefineConst(_T("const"), 1)); + throwIfError(p1->DefineConst(_T("const1"), 2)); + throwIfError(p1->DefineConst(_T("const2"), 3)); // string constants - p1->DefineStrConst(_T("str1"), _T("1.11")); - p1->DefineStrConst(_T("str2"), _T("2.22")); + throwIfError(p1->DefineStrConst(_T("str1"), _T("1.11"))); + throwIfError(p1->DefineStrConst(_T("str2"), _T("2.22"))); // variables value_type vVarVal[] = {1, 2, 3, -2}; - p1->DefineVar(_T("a"), &vVarVal[0]); - p1->DefineVar(_T("aa"), &vVarVal[1]); - p1->DefineVar(_T("b"), &vVarVal[1]); - p1->DefineVar(_T("c"), &vVarVal[2]); - p1->DefineVar(_T("d"), &vVarVal[3]); + throwIfError(p1->DefineVar(_T("a"), &vVarVal[0])); + throwIfError(p1->DefineVar(_T("aa"), &vVarVal[1])); + throwIfError(p1->DefineVar(_T("b"), &vVarVal[1])); + throwIfError(p1->DefineVar(_T("c"), &vVarVal[2])); + throwIfError(p1->DefineVar(_T("d"), &vVarVal[3])); // custom value ident functions p1->AddValIdent(&ParserTester::IsHexVal); @@ -1107,9 +1109,9 @@ int ParserTester::EqnTest(const string_type &a_str, double a_fRes, bool a_fPass) p1->DefineFun(_T("f5of5"), f5of5); // binary operators - p1->DefineOprt(_T("add"), add, 0); - p1->DefineOprt(_T("++"), add, 0); - p1->DefineOprt(_T("&"), land, prLAND); + throwIfError(p1->DefineOprt(_T("add"), add, 0)); + throwIfError(p1->DefineOprt(_T("++"), add, 0)); + throwIfError(p1->DefineOprt(_T("&"), land, prLAND)); // sample functions p1->DefineFun(_T("min"), Min); @@ -1127,16 +1129,16 @@ int ParserTester::EqnTest(const string_type &a_str, double a_fRes, bool a_fPass) // infix / postfix operator // Note: Identifiers used here do not have any meaning // they are mere placeholders to test certain features. - p1->DefineInfixOprt(_T("$"), sign, prPOW + 1); // sign with high priority - p1->DefineInfixOprt(_T("~"), plus2); // high priority - p1->DefineInfixOprt(_T("~~"), plus2); - p1->DefinePostfixOprt(_T("{m}"), Milli); - p1->DefinePostfixOprt(_T("{M}"), Mega); - p1->DefinePostfixOprt(_T("m"), Milli); - p1->DefinePostfixOprt(_T("meg"), Mega); - p1->DefinePostfixOprt(_T("#"), times3); - p1->DefinePostfixOprt(_T("'"), sqr); - p1->SetExpr(a_str); + throwIfError(p1->DefineInfixOprt(_T("$"), sign, prPOW + 1)); // sign with high priority + throwIfError(p1->DefineInfixOprt(_T("~"), plus2)); // high priority + throwIfError(p1->DefineInfixOprt(_T("~~"), plus2)); + throwIfError(p1->DefinePostfixOprt(_T("{m}"), Milli)); + throwIfError(p1->DefinePostfixOprt(_T("{M}"), Mega)); + throwIfError(p1->DefinePostfixOprt(_T("m"), Milli)); + throwIfError(p1->DefinePostfixOprt(_T("meg"), Mega)); + throwIfError(p1->DefinePostfixOprt(_T("#"), times3)); + throwIfError(p1->DefinePostfixOprt(_T("'"), sqr)); + throwIfError(p1->SetExpr(a_str)); // Test bytecode integrity // String parsing and bytecode parsing must yield the same result @@ -1201,13 +1203,13 @@ int ParserTester::EqnTestInt(const string_type &a_str, double a_fRes, bool a_fPa try { value_type fVal[2] = {-99, -999}; // results: initially should be different ParserInt p; - p.DefineConst(_T("const1"), 1); - p.DefineConst(_T("const2"), 2); - p.DefineVar(_T("a"), &vVarVal[0]); - p.DefineVar(_T("b"), &vVarVal[1]); - p.DefineVar(_T("c"), &vVarVal[2]); + throwIfError(p.DefineConst(_T("const1"), 1)); + throwIfError(p.DefineConst(_T("const2"), 2)); + throwIfError(p.DefineVar(_T("a"), &vVarVal[0])); + throwIfError(p.DefineVar(_T("b"), &vVarVal[1])); + throwIfError(p.DefineVar(_T("c"), &vVarVal[2])); - p.SetExpr(a_str); + throwIfError((p.SetExpr(a_str))); fVal[0] = getOrThrow(p.Eval()); // result from stringparsing fVal[1] = getOrThrow(p.Eval()); // result from bytecode