From 9649b132bd31deca799a2bfea68b887e3e25fd8f Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Wed, 22 Nov 2017 12:27:10 -0800 Subject: [PATCH] [muparser] Continue adopting ValueOrError --- muparser-2.2.5/include/muParserBase.h | 4 +-- muparser-2.2.5/include/muParserDLL.h | 1 - muparser-2.2.5/samples/example1/example1.cpp | 13 +++++---- muparser-2.2.5/src/muParser.cpp | 10 +++++-- muparser-2.2.5/src/muParserBase.cpp | 8 +++--- muparser-2.2.5/src/muParserDLL.cpp | 14 +--------- muparser-2.2.5/src/muParserTest.cpp | 29 ++++++++++---------- src/builtin_math.cpp | 10 +++---- 8 files changed, 40 insertions(+), 49 deletions(-) diff --git a/muparser-2.2.5/include/muParserBase.h b/muparser-2.2.5/include/muParserBase.h index 8be20cee6..57564eb09 100644 --- a/muparser-2.2.5/include/muParserBase.h +++ b/muparser-2.2.5/include/muParserBase.h @@ -97,8 +97,8 @@ class ParserBase { virtual ~ParserBase(); - value_type Eval() const; - value_type *Eval(int &nStackSize) const; + ValueOrError Eval() const; + void Eval(std::vector *results) const; int GetNumResults() const; diff --git a/muparser-2.2.5/include/muParserDLL.h b/muparser-2.2.5/include/muParserDLL.h index caaccd9d2..ccc79ff1f 100644 --- a/muparser-2.2.5/include/muParserDLL.h +++ b/muparser-2.2.5/include/muParserDLL.h @@ -112,7 +112,6 @@ API_EXPORT(void) mupSetVarFactory(muParserHandle_t a_hParser, muFacFun_t a_pFactory, void *pUserData); API_EXPORT(const muChar_t *) mupGetVersion(muParserHandle_t a_hParser); API_EXPORT(muFloat_t) mupEval(muParserHandle_t a_hParser); -API_EXPORT(muFloat_t *) mupEvalMulti(muParserHandle_t a_hParser, int *nNum); // Defining callbacks / variables / constants API_EXPORT(void) diff --git a/muparser-2.2.5/samples/example1/example1.cpp b/muparser-2.2.5/samples/example1/example1.cpp index c54ad3e1e..e4f48839a 100644 --- a/muparser-2.2.5/samples/example1/example1.cpp +++ b/muparser-2.2.5/samples/example1/example1.cpp @@ -416,7 +416,7 @@ void Calc() { // 1.) If you know there is only a single return value or in case you only need the last // result of an expression consisting of comma separated subexpressions you can // simply use: - mu::console() << _T("ans=") << parser.Eval() << _T("\n"); + mu::console() << _T("ans=") << *parser.Eval() << _T("\n"); // 2.) As an alternative you can also retrieve multiple return values using this API: int nNum = parser.GetNumResults(); @@ -425,10 +425,11 @@ void Calc() { // this is the hard way if you need to retrieve multiple subexpression // results - value_type *v = parser.Eval(nNum); + std::vector vs; + parser.Eval(&vs); mu::console() << std::setprecision(12); - for (int i = 0; i < nNum; ++i) { - mu::console() << v[i] << _T("\n"); + for (const ValueOrError &v : vs) { + mu::console() << *v << _T("\n"); } } } catch (mu::Parser::exception_type &e) { @@ -446,8 +447,8 @@ void Calc() { //--------------------------------------------------------------------------- int main(int, char **) { Splash(); - SelfTest(); - Help(); + (void)SelfTest(); + (void)Help(); // CheckLocale(); // CheckDiff(); diff --git a/muparser-2.2.5/src/muParser.cpp b/muparser-2.2.5/src/muParser.cpp index bbd0097f7..6d19b9f25 100644 --- a/muparser-2.2.5/src/muParser.cpp +++ b/muparser-2.2.5/src/muParser.cpp @@ -331,9 +331,10 @@ void Parser::OnDetectVar(string_type * /*pExpr*/, int & /*nStart*/, int & /*nEnd http://sourceforge.net/forum/forum.php?thread_id=1994611&forum_id=462843 */ ValueOrError Parser::Diff(value_type *a_Var, value_type a_fPos, value_type a_fEpsilon) const { - value_type fRes(0), fBuf(*a_Var), f[4] = {0, 0, 0, 0}, fEpsilon(a_fEpsilon); + value_type fRes(0), fBuf(*a_Var), fEpsilon(a_fEpsilon); + ValueOrError f[4] = {0, 0, 0, 0}; - // Backwards compatible calculation of epsilon inc case the user doesn't provide + // Backwards compatible calculation of epsilon in case the user doesn't provide // his own epsilon if (fEpsilon == 0) fEpsilon = (a_fPos == 0) ? (value_type)1e-10 : (value_type)1e-7 * a_fPos; @@ -347,7 +348,10 @@ ValueOrError Parser::Diff(value_type *a_Var, value_type a_fPos, value_type a_fEp f[3] = Eval(); *a_Var = fBuf; // restore variable - fRes = (-f[0] + 8 * f[1] - 8 * f[2] + f[3]) / (12 * fEpsilon); + for (ValueOrError &v : f) { + if (!v) return std::move(v); + } + fRes = (-*f[0] + 8 * *f[1] - 8 * *f[2] + *f[3]) / (12 * fEpsilon); return fRes; } } // namespace mu diff --git a/muparser-2.2.5/src/muParserBase.cpp b/muparser-2.2.5/src/muParserBase.cpp index 47a5e5e42..f335cdf00 100644 --- a/muparser-2.2.5/src/muParserBase.cpp +++ b/muparser-2.2.5/src/muParserBase.cpp @@ -1552,12 +1552,12 @@ void ParserBase::StackDump(const ParserStack &a_stVal, This member function can be used to retrieve all results of an expression made up of multiple comma separated subexpressions (i.e. "x+y,sin(x),cos(y)") */ -value_type *ParserBase::Eval(int &nStackSize) const { +void ParserBase::Eval(std::vector *outResult) const { (this->*m_pParseFormula)(); - nStackSize = m_nFinalResultIdx; + int stackSize = m_nFinalResultIdx; // (for historic reasons the stack starts at position 1) - return &m_vStackBuffer[1]; + outResult->assign(&m_vStackBuffer[1], &m_vStackBuffer[1 + stackSize]); } //--------------------------------------------------------------------------- @@ -1585,6 +1585,6 @@ int ParserBase::GetNumResults() const { return m_nFinalResultIdx; } \return The evaluation result \throw ParseException if no Formula is set or in case of any other error related to the formula. */ -value_type ParserBase::Eval() const { return (this->*m_pParseFormula)().getOrThrow(); } +ValueOrError ParserBase::Eval() const { return (this->*m_pParseFormula)(); } } // namespace mu diff --git a/muparser-2.2.5/src/muParserDLL.cpp b/muparser-2.2.5/src/muParserDLL.cpp index 7fd891c35..6b196b5a2 100644 --- a/muparser-2.2.5/src/muParserDLL.cpp +++ b/muparser-2.2.5/src/muParserDLL.cpp @@ -195,19 +195,7 @@ API_EXPORT(const muChar_t*) mupGetVersion(muParserHandle_t a_hParser) { API_EXPORT(muFloat_t) mupEval(muParserHandle_t a_hParser) { MU_TRY muParser_t* const p(AsParser(a_hParser)); - return p->Eval(); - MU_CATCH - - return 0; -} - -//--------------------------------------------------------------------------- -API_EXPORT(muFloat_t*) mupEvalMulti(muParserHandle_t a_hParser, int* nNum) { - MU_TRY - assert(nNum != NULL); - - muParser_t* const p(AsParser(a_hParser)); - return p->Eval(*nNum); + return *p->Eval(); MU_CATCH return 0; diff --git a/muparser-2.2.5/src/muParserTest.cpp b/muparser-2.2.5/src/muParserTest.cpp index 6c1c57188..8ef1f167d 100644 --- a/muparser-2.2.5/src/muParserTest.cpp +++ b/muparser-2.2.5/src/muParserTest.cpp @@ -94,14 +94,14 @@ int ParserTester::TestInterface() { p.DefineVar(_T("b"), &afVal[1]); p.DefineVar(_T("c"), &afVal[2]); p.SetExpr(_T("a+b+c")); - p.Eval(); + (void)p.Eval(); } catch (...) { iStat += 1; // this is not supposed to happen } try { p.RemoveVar(_T("c")); - p.Eval(); + (void)p.Eval(); iStat += 1; // not supposed to reach this, nonexisting variable "c" deleted... } catch (...) { // failure is expected... @@ -1075,7 +1075,7 @@ int ParserTester::ThrowTest(const string_type &a_str, int a_iErrc, bool a_bFail) p.DefineFun(_T("strfun2"), StrFun2); p.DefineFun(_T("strfun3"), StrFun3); p.SetExpr(a_str); - p.Eval(); + (void)p.Eval(); } catch (ParserError &e) { // output the formula in case of an failed test if (a_bFail == false || (a_bFail == true && a_iErrc != e.GetCode())) { @@ -1119,10 +1119,10 @@ int ParserTester::EqnTestWithVarChange(const string_type &a_str, double a_fVar1, p.SetExpr(a_str); var = a_fVar1; - fVal[0] = p.Eval(); + fVal[0] = *p.Eval(); var = a_fVar2; - fVal[1] = p.Eval(); + fVal[1] = *p.Eval(); if (fabs(a_fRes1 - fVal[0]) > 0.0000000001) throw std::runtime_error("incorrect result (first pass)"); @@ -1234,8 +1234,8 @@ int ParserTester::EqnTest(const string_type &a_str, double a_fRes, bool a_fPass) // Test bytecode integrity // String parsing and bytecode parsing must yield the same result - fVal[0] = p1->Eval(); // result from stringparsing - fVal[1] = p1->Eval(); // result from bytecode + fVal[0] = *p1->Eval(); // result from stringparsing + fVal[1] = *p1->Eval(); // result from bytecode if (fVal[0] != fVal[1]) throw Parser::exception_type(_T("Bytecode / string parsing mismatch.")); @@ -1250,18 +1250,17 @@ int ParserTester::EqnTest(const string_type &a_str, double a_fRes, bool a_fPass) vParser.clear(); // delete the vector p1.reset(0); - fVal[2] = p2.Eval(); + fVal[2] = *p2.Eval(); // Test assignment operator mu::Parser p3; p3 = p2; - fVal[3] = p3.Eval(); + fVal[3] = *p3.Eval(); // Test Eval function for multiple return values - // use p2 since it has the optimizer enabled! - int nNum; - value_type *v = p2.Eval(nNum); - fVal[4] = v[nNum - 1]; + std::vector v; + p2.Eval(&v); + fVal[4] = *v.back(); } catch (std::exception &e) { mu::console() << _T("\n ") << e.what() << _T("\n"); } @@ -1328,8 +1327,8 @@ int ParserTester::EqnTestInt(const string_type &a_str, double a_fRes, bool a_fPa p.DefineVar(_T("c"), &vVarVal[2]); p.SetExpr(a_str); - fVal[0] = p.Eval(); // result from stringparsing - fVal[1] = p.Eval(); // result from bytecode + fVal[0] = *p.Eval(); // result from stringparsing + fVal[1] = *p.Eval(); // result from bytecode if (fVal[0] != fVal[1]) throw Parser::exception_type(_T("Bytecode corrupt.")); diff --git a/src/builtin_math.cpp b/src/builtin_math.cpp index 2a2325b5c..196ce32ad 100644 --- a/src/builtin_math.cpp +++ b/src/builtin_math.cpp @@ -131,13 +131,13 @@ static int evaluate_expression(wchar_t *cmd, parser_t &parser, io_streams_t &str p.DefineOprt(L"%", moduloOperator, mu::prINFIX); p.SetExpr(expression); - int nNum; - mu::value_type *v = p.Eval(nNum); - for (int i = 0; i < nNum; ++i) { + std::vector vs; + p.Eval(&vs); + for (const mu::ValueOrError &v : vs) { if (opts.scale == 0) { - streams.out.append_format(L"%ld\n", static_cast(v[i])); + streams.out.append_format(L"%ld\n", static_cast(*v)); } else { - streams.out.append_format(L"%.*lf\n", opts.scale, v[i]); + streams.out.append_format(L"%.*lf\n", opts.scale, *v); } } return STATUS_CMD_OK;