Use Qt math function.

--HG--
branch : feature
This commit is contained in:
dismine 2014-04-26 10:23:50 +03:00
parent 59c7405b88
commit 21c38b446d
9 changed files with 213 additions and 419 deletions

View file

@ -21,7 +21,8 @@
******************************************************************************************************/ ******************************************************************************************************/
#include "qmuparser.h" #include "qmuparser.h"
#include "qmuparsertemplatemagic.h" #include <QtMath>
#include <QtGlobal>
//--- Standard includes ------------------------------------------------------------------------ //--- Standard includes ------------------------------------------------------------------------
#include <cmath> #include <cmath>
@ -40,28 +41,17 @@ using namespace std;
\brief Implementation of the standard floating point QmuParser. \brief Implementation of the standard floating point QmuParser.
*/ */
/** \brief Namespace for mathematical applications. */ /** \brief Namespace for mathematical applications. */
namespace qmu namespace qmu
{ {
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Trigonometric function // Trigonometric function
qreal QmuParser::Sin(qreal v) { return MathImpl<qreal>::Sin(v); } qreal QmuParser::Sinh(qreal v) { return sinh(v); }
qreal QmuParser::Cos(qreal v) { return MathImpl<qreal>::Cos(v); } qreal QmuParser::Cosh(qreal v) { return cosh(v); }
qreal QmuParser::Tan(qreal v) { return MathImpl<qreal>::Tan(v); } qreal QmuParser::Tanh(qreal v) { return tanh(v); }
qreal QmuParser::ASin(qreal v) { return MathImpl<qreal>::ASin(v); } qreal QmuParser::ASinh(qreal v) { return log(v + qSqrt(v * v + 1)); }
qreal QmuParser::ACos(qreal v) { return MathImpl<qreal>::ACos(v); } qreal QmuParser::ACosh(qreal v) { return log(v + qSqrt(v * v - 1)); }
qreal QmuParser::ATan(qreal v) { return MathImpl<qreal>::ATan(v); } qreal QmuParser::ATanh(qreal v) { return ((qreal)0.5 * log((1 + v) / (1 - v))); }
qreal QmuParser::ATan2(qreal v1, qreal v2) { return MathImpl<qreal>::ATan2(v1, v2); }
qreal QmuParser::Sinh(qreal v) { return MathImpl<qreal>::Sinh(v); }
qreal QmuParser::Cosh(qreal v) { return MathImpl<qreal>::Cosh(v); }
qreal QmuParser::Tanh(qreal v) { return MathImpl<qreal>::Tanh(v); }
qreal QmuParser::ASinh(qreal v) { return MathImpl<qreal>::ASinh(v); }
qreal QmuParser::ACosh(qreal v) { return MathImpl<qreal>::ACosh(v); }
qreal QmuParser::ATanh(qreal v) { return MathImpl<qreal>::ATanh(v); }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Logarithm functions // Logarithm functions
@ -74,7 +64,7 @@ namespace qmu
throw QmuParserError(ecDOMAIN_ERROR, "Log2"); throw QmuParserError(ecDOMAIN_ERROR, "Log2");
#endif #endif
return MathImpl<qreal>::Log2(v); return log(v)/log((qreal)2);
} }
// Logarithm base 10 // Logarithm base 10
@ -85,35 +75,14 @@ namespace qmu
throw QmuParserError(ecDOMAIN_ERROR, "Log10"); throw QmuParserError(ecDOMAIN_ERROR, "Log10");
#endif #endif
return MathImpl<qreal>::Log10(v); return log10(v);
}
// Logarithm base e (natural logarithm)
qreal QmuParser::Ln(qreal v)
{
#ifdef MUP_MATH_EXCEPTIONS
if (v<=0)
throw QmuParserError(ecDOMAIN_ERROR, "Ln");
#endif
return MathImpl<qreal>::Log(v);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// misc // misc
qreal QmuParser::Exp(qreal v) { return MathImpl<qreal>::Exp(v); } qreal QmuParser::Abs(qreal v) { return (v>=0) ? v : -v; }
qreal QmuParser::Abs(qreal v) { return MathImpl<qreal>::Abs(v); } qreal QmuParser::Rint(qreal v) { return qFloor(v + (qreal)0.5); }
qreal QmuParser::Sqrt(qreal v) qreal QmuParser::Sign(qreal v) { return (qreal)((v<0) ? -1 : (v>0) ? 1 : 0); }
{
#ifdef MUP_MATH_EXCEPTIONS
if (v<0)
throw QmuParserError(ecDOMAIN_ERROR, "sqrt");
#endif
return MathImpl<qreal>::Sqrt(v);
}
qreal QmuParser::Rint(qreal v) { return MathImpl<qreal>::Rint(v); }
qreal QmuParser::Sign(qreal v) { return MathImpl<qreal>::Sign(v); }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
/** \brief Callback for the unary minus operator. /** \brief Callback for the unary minus operator.
@ -156,39 +125,45 @@ namespace qmu
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
/** \brief Callback for determining the minimum value out of a vector. /** \brief Callback for determining the minimum value out of a vector.
\param [in] a_afArg Vector with the function arguments \param [in] a_afArg Vector with the function arguments
\param [in] a_iArgc The size of a_afArg \param [in] a_iArgc The size of a_afArg
*/ */
qreal QmuParser::Min(const qreal *a_afArg, int a_iArgc) qreal QmuParser::Min(const qreal *a_afArg, int a_iArgc)
{ {
if (!a_iArgc) if (!a_iArgc)
throw exception_type("too few arguments for function min."); {
throw exception_type("too few arguments for function min.");
}
qreal fRes=a_afArg[0]; qreal fRes=a_afArg[0];
for (int i=0; i<a_iArgc; ++i) for (int i=0; i<a_iArgc; ++i)
fRes = std::min(fRes, a_afArg[i]); {
fRes = qMin(fRes, a_afArg[i]);
}
return fRes; return fRes;
} }
//---------------------------------------------------------------------------
//--------------------------------------------------------------------------- /** \brief Callback for determining the maximum value out of a vector.
/** \brief Callback for determining the maximum value out of a vector. \param [in] a_afArg Vector with the function arguments
\param [in] a_afArg Vector with the function arguments \param [in] a_iArgc The size of a_afArg
\param [in] a_iArgc The size of a_afArg */
*/ qreal QmuParser::Max(const qreal *a_afArg, int a_iArgc)
qreal QmuParser::Max(const qreal *a_afArg, int a_iArgc) {
{
if (!a_iArgc) if (!a_iArgc)
throw exception_type("too few arguments for function min."); {
throw exception_type("too few arguments for function min.");
}
qreal fRes=a_afArg[0]; qreal fRes=a_afArg[0];
for (int i=0; i<a_iArgc; ++i) fRes = std::max(fRes, a_afArg[i]); for (int i=0; i<a_iArgc; ++i)
{
fRes = qMax(fRes, a_afArg[i]);
}
return fRes; return fRes;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -247,55 +222,44 @@ namespace qmu
DefineInfixOprtChars( "/+-*^?<>=#!$%&|~'_" ); DefineInfixOprtChars( "/+-*^?<>=#!$%&|~'_" );
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
/** \brief Initialize the default functions. */ /** \brief Initialize the default functions. */
void QmuParser::InitFun() void QmuParser::InitFun()
{ {
if (qmu::TypeInfo<qreal>::IsInteger()) // trigonometric functions
{ DefineFun("sin", qSin);
// When setting MUP_BASETYPE to an integer type DefineFun("cos", qCos);
// Place functions for dealing with integer values here DefineFun("tan", qTan);
// ... // arcus functions
// ... DefineFun("asin", qAsin);
// ... DefineFun("acos", qAcos);
} DefineFun("atan", qAtan);
else DefineFun("atan2", qAtan2);
{ // hyperbolic functions
// trigonometric functions DefineFun("sinh", Sinh);
DefineFun("sin", Sin); DefineFun("cosh", Cosh);
DefineFun("cos", Cos); DefineFun("tanh", Tanh);
DefineFun("tan", Tan); // arcus hyperbolic functions
// arcus functions DefineFun("asinh", ASinh);
DefineFun("asin", ASin); DefineFun("acosh", ACosh);
DefineFun("acos", ACos); DefineFun("atanh", ATanh);
DefineFun("atan", ATan); // Logarithm functions
DefineFun("atan2", ATan2); DefineFun("log2", Log2);
// hyperbolic functions DefineFun("log10", Log10);
DefineFun("sinh", Sinh); DefineFun("log", Log10);
DefineFun("cosh", Cosh); DefineFun("ln", qLn);
DefineFun("tanh", Tanh); // misc
// arcus hyperbolic functions DefineFun("exp", qExp);
DefineFun("asinh", ASinh); DefineFun("sqrt", qSqrt);
DefineFun("acosh", ACosh); DefineFun("sign", Sign);
DefineFun("atanh", ATanh); DefineFun("rint", Rint);
// Logarithm functions DefineFun("abs", Abs);
DefineFun("log2", Log2); // Functions with variable number of arguments
DefineFun("log10", Log10); DefineFun("sum", Sum);
DefineFun("log", Log10); DefineFun("avg", Avg);
DefineFun("ln", Ln); DefineFun("min", Min);
// misc DefineFun("max", Max);
DefineFun("exp", Exp); }
DefineFun("sqrt", Sqrt);
DefineFun("sign", Sign);
DefineFun("rint", Rint);
DefineFun("abs", Abs);
// Functions with variable number of arguments
DefineFun("sum", Sum);
DefineFun("avg", Avg);
DefineFun("min", Min);
DefineFun("max", Max);
}
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
/** \brief Initialize constants. /** \brief Initialize constants.

View file

@ -30,7 +30,6 @@
//--- Parser includes -------------------------------------------------------------------------- //--- Parser includes --------------------------------------------------------------------------
#include "qmuparserbase.h" #include "qmuparserbase.h"
#include "qmuparsertemplatemagic.h"
/** \file /** \file
\brief Definition of the standard floating point parser. \brief Definition of the standard floating point parser.
@ -61,18 +60,8 @@ public:
qreal Diff(qreal *a_Var, qreal a_fPos, qreal a_fEpsilon = 0) const; qreal Diff(qreal *a_Var, qreal a_fPos, qreal a_fEpsilon = 0) const;
protected: protected:
// Trigonometric functions // Trigonometric functions
static qreal Sin(qreal);
static qreal Cos(qreal);
static qreal Tan(qreal);
static qreal Tan2(qreal, qreal); static qreal Tan2(qreal, qreal);
// arcus functions
static qreal ASin(qreal);
static qreal ACos(qreal);
static qreal ATan(qreal);
static qreal ATan2(qreal, qreal);
// hyperbolic functions // hyperbolic functions
static qreal Sinh(qreal); static qreal Sinh(qreal);
static qreal Cosh(qreal); static qreal Cosh(qreal);
@ -84,18 +73,13 @@ protected:
// Logarithm functions // Logarithm functions
static qreal Log2(qreal); // Logarithm Base 2 static qreal Log2(qreal); // Logarithm Base 2
static qreal Log10(qreal); // Logarithm Base 10 static qreal Log10(qreal); // Logarithm Base 10
static qreal Ln(qreal); // Logarithm Base e (natural logarithm)
// misc // misc
static qreal Exp(qreal);
static qreal Abs(qreal); static qreal Abs(qreal);
static qreal Sqrt(qreal);
static qreal Rint(qreal); static qreal Rint(qreal);
static qreal Sign(qreal); static qreal Sign(qreal);
// Prefix operators // Prefix operators
// !!! Unary Minus is a MUST if you want to use negative signs !!! // !!! Unary Minus is a MUST if you want to use negative signs !!!
static qreal UnaryMinus(qreal); static qreal UnaryMinus(qreal);
// Functions with variable number of arguments // Functions with variable number of arguments
static qreal Sum(const qreal*, int); // sum static qreal Sum(const qreal*, int); // sum
static qreal Avg(const qreal*, int); // mean value static qreal Avg(const qreal*, int); // mean value

View file

@ -52,7 +52,6 @@ HEADERS += \
qmuparserbytecode.h \ qmuparserbytecode.h \
qmuparserbase.h \ qmuparserbase.h \
qmuparsertest.h \ qmuparsertest.h \
qmuparsertemplatemagic.h \
qmuparserint.h \ qmuparserint.h \
stable.h stable.h

View file

@ -21,7 +21,6 @@
******************************************************************************************************/ ******************************************************************************************************/
#include "qmuparserbase.h" #include "qmuparserbase.h"
#include "qmuparsertemplatemagic.h"
//--- Standard includes ------------------------------------------------------------------------ //--- Standard includes ------------------------------------------------------------------------
#include <cassert> #include <cassert>
@ -266,11 +265,11 @@ namespace qmu
stringstream_type ss; stringstream_type ss;
ss << MUP_VERSION; ss << QMUP_VERSION;
if (eInfo==pviFULL) if (eInfo==pviFULL)
{ {
ss << " (" << MUP_VERSION_DATE; ss << " (" << QMUP_VERSION_DATE;
ss << std::dec << "; " << sizeof(void*)*8 << "BIT"; ss << std::dec << "; " << sizeof(void*)*8 << "BIT";
#ifdef _DEBUG #ifdef _DEBUG
@ -1030,7 +1029,7 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr)
continue; continue;
case cmPOW: case cmPOW:
--sidx; Stack[sidx] = MathImpl<qreal>::Pow(Stack[sidx], Stack[1+sidx]); --sidx; Stack[sidx] = std::pow(Stack[sidx], Stack[1+sidx]);
continue; continue;
case cmLAND: --sidx; Stack[sidx] = Stack[sidx] && Stack[sidx+1]; continue; case cmLAND: --sidx; Stack[sidx] = Stack[sidx] && Stack[sidx+1]; continue;
@ -1607,22 +1606,22 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr)
QStack<token_type> stOprt(a_stOprt), QStack<token_type> stOprt(a_stOprt),
stVal(a_stVal); stVal(a_stVal);
mu::console() << "\nValue stack:\n"; qmu::console() << "\nValue stack:\n";
while ( !stVal.empty() ) while ( !stVal.empty() )
{ {
token_type val = stVal.pop(); token_type val = stVal.pop();
if (val.GetType()==tpSTR) if (val.GetType()==tpSTR)
mu::console() << " \"" << val.GetAsString() << "\" "; qmu::console() << " \"" << val.GetAsString() << "\" ";
else else
mu::console() << " " << val.GetVal() << " "; qmu::console() << " " << val.GetVal() << " ";
} }
mu::console() << "\nOperator stack:\n"; qmu::console() << "\nOperator stack:\n";
while ( !stOprt.empty() ) while ( !stOprt.empty() )
{ {
if (stOprt.top().GetCode()<=cmASSIGN) if (stOprt.top().GetCode()<=cmASSIGN)
{ {
mu::console() << "OPRT_INTRNL \"" qmu::console() << "OPRT_INTRNL \""
<< QmuParserBase::c_DefaultOprt[stOprt.top().GetCode()] << QmuParserBase::c_DefaultOprt[stOprt.top().GetCode()]
<< "\" \n"; << "\" \n";
} }
@ -1630,35 +1629,35 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr)
{ {
switch(stOprt.top().GetCode()) switch(stOprt.top().GetCode())
{ {
case cmVAR: mu::console() << "VAR\n"; break; case cmVAR: qmu::console() << "VAR\n"; break;
case cmVAL: mu::console() << "VAL\n"; break; case cmVAL: qmu::console() << "VAL\n"; break;
case cmFUNC: mu::console() << "FUNC \"" case cmFUNC: qmu::console() << "FUNC \""
<< stOprt.top().GetAsString() << stOprt.top().GetAsString()
<< "\"\n"; break; << "\"\n"; break;
case cmFUNC_BULK: mu::console() << "FUNC_BULK \"" case cmFUNC_BULK: qmu::console() << "FUNC_BULK \""
<< stOprt.top().GetAsString() << stOprt.top().GetAsString()
<< "\"\n"; break; << "\"\n"; break;
case cmOPRT_INFIX: mu::console() << "OPRT_INFIX \"" case cmOPRT_INFIX: qmu::console() << "OPRT_INFIX \""
<< stOprt.top().GetAsString() << stOprt.top().GetAsString()
<< "\"\n"; break; << "\"\n"; break;
case cmOPRT_BIN: mu::console() << "OPRT_BIN \"" case cmOPRT_BIN: qmu::console() << "OPRT_BIN \""
<< stOprt.top().GetAsString() << stOprt.top().GetAsString()
<< "\"\n"; break; << "\"\n"; break;
case cmFUNC_STR: mu::console() << "FUNC_STR\n"; break; case cmFUNC_STR: qmu::console() << "FUNC_STR\n"; break;
case cmEND: mu::console() << "END\n"; break; case cmEND: qmu::console() << "END\n"; break;
case cmUNKNOWN: mu::console() << "UNKNOWN\n"; break; case cmUNKNOWN: qmu::console() << "UNKNOWN\n"; break;
case cmBO: mu::console() << "BRACKET \"(\"\n"; break; case cmBO: qmu::console() << "BRACKET \"(\"\n"; break;
case cmBC: mu::console() << "BRACKET \")\"\n"; break; case cmBC: qmu::console() << "BRACKET \")\"\n"; break;
case cmIF: mu::console() << "IF\n"; break; case cmIF: qmu::console() << "IF\n"; break;
case cmELSE: mu::console() << "ELSE\n"; break; case cmELSE: qmu::console() << "ELSE\n"; break;
case cmENDIF: mu::console() << "ENDIF\n"; break; case cmENDIF: qmu::console() << "ENDIF\n"; break;
default: mu::console() << stOprt.top().GetCode() << " "; break; default: qmu::console() << stOprt.top().GetCode() << " "; break;
} }
} }
stOprt.pop(); stOprt.pop();
} }
mu::console() << dec << endl; qmu::console() << dec << endl;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------

View file

@ -34,7 +34,6 @@
//--- Parser includes -------------------------------------------------------------------------- //--- Parser includes --------------------------------------------------------------------------
#include "qmuparserdef.h" #include "qmuparserdef.h"
#include "qmuparserstack.h"
#include "qmuparsertokenreader.h" #include "qmuparsertokenreader.h"
#include "qmuparserbytecode.h" #include "qmuparserbytecode.h"
#include "qmuparsererror.h" #include "qmuparsererror.h"
@ -121,7 +120,7 @@ private:
bool HasBuiltInOprt() const; bool HasBuiltInOprt() const;
void AddValIdent(identfun_type a_pCallback); void AddValIdent(identfun_type a_pCallback);
/** \fn void mu::QParserBase::DefineFun(const string_type &a_strName, fun_type0 a_pFun, bool a_bAllowOpt = true) /** \fn void qmu::QmuParserBase::DefineFun(const string_type &a_strName, fun_type0 a_pFun, bool a_bAllowOpt = true)
\brief Define a parser function without arguments. \brief Define a parser function without arguments.
\param a_strName Name of the function \param a_strName Name of the function
\param a_pFun Pointer to the callback function \param a_pFun Pointer to the callback function

View file

@ -31,8 +31,6 @@
#include "qmuparserdef.h" #include "qmuparserdef.h"
#include "qmuparsererror.h" #include "qmuparsererror.h"
#include "qmuparsertoken.h" #include "qmuparsertoken.h"
#include "qmuparserstack.h"
#include "qmuparsertemplatemagic.h"
namespace qmu namespace qmu
@ -166,7 +164,7 @@ namespace qmu
m_vRPN.pop_back(); m_vRPN.pop_back();
break; break;
case cmPOW: x = MathImpl<qreal>::Pow(x, y); case cmPOW: x = std::pow(x, y);
m_vRPN.pop_back(); m_vRPN.pop_back();
break; break;
@ -495,89 +493,89 @@ namespace qmu
{ {
if (!m_vRPN.size()) if (!m_vRPN.size())
{ {
mu::console() << "No bytecode available\n"; qmu::console() << "No bytecode available\n";
return; return;
} }
mu::console() << "Number of RPN tokens:" << (int)m_vRPN.size() << "\n"; qmu::console() << "Number of RPN tokens:" << (int)m_vRPN.size() << "\n";
for (std::size_t i=0; i<m_vRPN.size() && m_vRPN[i].Cmd!=cmEND; ++i) for (std::size_t i=0; i<m_vRPN.size() && m_vRPN[i].Cmd!=cmEND; ++i)
{ {
mu::console() << std::dec << i << " : \t"; qmu::console() << std::dec << i << " : \t";
switch (m_vRPN[i].Cmd) switch (m_vRPN[i].Cmd)
{ {
case cmVAL: mu::console() << "VAL \t"; case cmVAL: qmu::console() << "VAL \t";
mu::console() << "[" << m_vRPN[i].Val.data2 << "]\n"; qmu::console() << "[" << m_vRPN[i].Val.data2 << "]\n";
break; break;
case cmVAR: mu::console() << "VAR \t"; case cmVAR: qmu::console() << "VAR \t";
mu::console() << "[ADDR: 0x" << std::hex << m_vRPN[i].Val.ptr << "]\n"; qmu::console() << "[ADDR: 0x" << std::hex << m_vRPN[i].Val.ptr << "]\n";
break; break;
case cmVARPOW2: mu::console() << "VARPOW2 \t"; case cmVARPOW2: qmu::console() << "VARPOW2 \t";
mu::console() << "[ADDR: 0x" << std::hex << m_vRPN[i].Val.ptr << "]\n"; qmu::console() << "[ADDR: 0x" << std::hex << m_vRPN[i].Val.ptr << "]\n";
break; break;
case cmVARPOW3: mu::console() << "VARPOW3 \t"; case cmVARPOW3: qmu::console() << "VARPOW3 \t";
mu::console() << "[ADDR: 0x" << std::hex << m_vRPN[i].Val.ptr << "]\n"; qmu::console() << "[ADDR: 0x" << std::hex << m_vRPN[i].Val.ptr << "]\n";
break; break;
case cmVARPOW4: mu::console() << "VARPOW4 \t"; case cmVARPOW4: qmu::console() << "VARPOW4 \t";
mu::console() << "[ADDR: 0x" << std::hex << m_vRPN[i].Val.ptr << "]\n"; qmu::console() << "[ADDR: 0x" << std::hex << m_vRPN[i].Val.ptr << "]\n";
break; break;
case cmVARMUL: mu::console() << "VARMUL \t"; case cmVARMUL: qmu::console() << "VARMUL \t";
mu::console() << "[ADDR: 0x" << std::hex << m_vRPN[i].Val.ptr << "]"; qmu::console() << "[ADDR: 0x" << std::hex << m_vRPN[i].Val.ptr << "]";
mu::console() << " * [" << m_vRPN[i].Val.data << "]"; qmu::console() << " * [" << m_vRPN[i].Val.data << "]";
mu::console() << " + [" << m_vRPN[i].Val.data2 << "]\n"; qmu::console() << " + [" << m_vRPN[i].Val.data2 << "]\n";
break; break;
case cmFUNC: mu::console() << "CALL\t"; case cmFUNC: qmu::console() << "CALL\t";
mu::console() << "[ARG:" << std::dec << m_vRPN[i].Fun.argc << "]"; qmu::console() << "[ARG:" << std::dec << m_vRPN[i].Fun.argc << "]";
mu::console() << "[ADDR: 0x" << std::hex << m_vRPN[i].Fun.ptr << "]"; qmu::console() << "[ADDR: 0x" << std::hex << m_vRPN[i].Fun.ptr << "]";
mu::console() << "\n"; qmu::console() << "\n";
break; break;
case cmFUNC_STR: case cmFUNC_STR:
mu::console() << "CALL STRFUNC\t"; qmu::console() << "CALL STRFUNC\t";
mu::console() << "[ARG:" << std::dec << m_vRPN[i].Fun.argc << "]"; qmu::console() << "[ARG:" << std::dec << m_vRPN[i].Fun.argc << "]";
mu::console() << "[IDX:" << std::dec << m_vRPN[i].Fun.idx << "]"; qmu::console() << "[IDX:" << std::dec << m_vRPN[i].Fun.idx << "]";
mu::console() << "[ADDR: 0x" << m_vRPN[i].Fun.ptr << "]\n"; qmu::console() << "[ADDR: 0x" << m_vRPN[i].Fun.ptr << "]\n";
break; break;
case cmLT: mu::console() << "LT\n"; break; case cmLT: qmu::console() << "LT\n"; break;
case cmGT: mu::console() << "GT\n"; break; case cmGT: qmu::console() << "GT\n"; break;
case cmLE: mu::console() << "LE\n"; break; case cmLE: qmu::console() << "LE\n"; break;
case cmGE: mu::console() << "GE\n"; break; case cmGE: qmu::console() << "GE\n"; break;
case cmEQ: mu::console() << "EQ\n"; break; case cmEQ: qmu::console() << "EQ\n"; break;
case cmNEQ: mu::console() << "NEQ\n"; break; case cmNEQ: qmu::console() << "NEQ\n"; break;
case cmADD: mu::console() << "ADD\n"; break; case cmADD: qmu::console() << "ADD\n"; break;
case cmLAND: mu::console() << "&&\n"; break; case cmLAND: qmu::console() << "&&\n"; break;
case cmLOR: mu::console() << "||\n"; break; case cmLOR: qmu::console() << "||\n"; break;
case cmSUB: mu::console() << "SUB\n"; break; case cmSUB: qmu::console() << "SUB\n"; break;
case cmMUL: mu::console() << "MUL\n"; break; case cmMUL: qmu::console() << "MUL\n"; break;
case cmDIV: mu::console() << "DIV\n"; break; case cmDIV: qmu::console() << "DIV\n"; break;
case cmPOW: mu::console() << "POW\n"; break; case cmPOW: qmu::console() << "POW\n"; break;
case cmIF: mu::console() << "IF\t"; case cmIF: qmu::console() << "IF\t";
mu::console() << "[OFFSET:" << std::dec << m_vRPN[i].Oprt.offset << "]\n"; qmu::console() << "[OFFSET:" << std::dec << m_vRPN[i].Oprt.offset << "]\n";
break; break;
case cmELSE: mu::console() << "ELSE\t"; case cmELSE: qmu::console() << "ELSE\t";
mu::console() << "[OFFSET:" << std::dec << m_vRPN[i].Oprt.offset << "]\n"; qmu::console() << "[OFFSET:" << std::dec << m_vRPN[i].Oprt.offset << "]\n";
break; break;
case cmENDIF: mu::console() << "ENDIF\n"; break; case cmENDIF: qmu::console() << "ENDIF\n"; break;
case cmASSIGN: case cmASSIGN:
mu::console() << "ASSIGN\t"; qmu::console() << "ASSIGN\t";
mu::console() << "[ADDR: 0x" << m_vRPN[i].Oprt.ptr << "]\n"; qmu::console() << "[ADDR: 0x" << m_vRPN[i].Oprt.ptr << "]\n";
break; break;
default: mu::console() << "(unknown code: " << m_vRPN[i].Cmd << ")\n"; default: qmu::console() << "(unknown code: " << m_vRPN[i].Cmd << ")\n";
break; break;
} // switch cmdCode } // switch cmdCode
} // while bytecode } // while bytecode
mu::console() << "END" << std::endl; qmu::console() << "END" << std::endl;
} }
} // namespace qmu } // namespace qmu

View file

@ -1,150 +0,0 @@
#ifndef QMUPARSERTEMPLATEMAGIC_H
#define QMUPARSERTEMPLATEMAGIC_H
#include <cmath>
#include "muParserError.h"
namespace qmu
{
//-----------------------------------------------------------------------------------------------
//
// Compile time type detection
//
//-----------------------------------------------------------------------------------------------
/** \brief A class singling out integer types at compile time using
template meta programming.
*/
template<typename T>
struct TypeInfo
{
static bool IsInteger() { return false; }
};
template<>
struct TypeInfo<char>
{
static bool IsInteger() { return true; }
};
template<>
struct TypeInfo<short>
{
static bool IsInteger() { return true; }
};
template<>
struct TypeInfo<int>
{
static bool IsInteger() { return true; }
};
template<>
struct TypeInfo<long>
{
static bool IsInteger() { return true; }
};
template<>
struct TypeInfo<unsigned char>
{
static bool IsInteger() { return true; }
};
template<>
struct TypeInfo<unsigned short>
{
static bool IsInteger() { return true; }
};
template<>
struct TypeInfo<unsigned int>
{
static bool IsInteger() { return true; }
};
template<>
struct TypeInfo<unsigned long>
{
static bool IsInteger() { return true; }
};
//-----------------------------------------------------------------------------------------------
//
// Standard math functions with dummy overload for integer types
//
//-----------------------------------------------------------------------------------------------
/** \brief A template class for providing wrappers for essential math functions.
This template is spezialized for several types in order to provide a unified interface
for parser internal math function calls regardless of the data type.
*/
template<typename T>
struct MathImpl
{
static T Sin(T v) { return sin(v); }
static T Cos(T v) { return cos(v); }
static T Tan(T v) { return tan(v); }
static T ASin(T v) { return asin(v); }
static T ACos(T v) { return acos(v); }
static T ATan(T v) { return atan(v); }
static T ATan2(T v1, T v2) { return atan2(v1, v2); }
static T Sinh(T v) { return sinh(v); }
static T Cosh(T v) { return cosh(v); }
static T Tanh(T v) { return tanh(v); }
static T ASinh(T v) { return log(v + sqrt(v * v + 1)); }
static T ACosh(T v) { return log(v + sqrt(v * v - 1)); }
static T ATanh(T v) { return ((T)0.5 * log((1 + v) / (1 - v))); }
static T Log(T v) { return log(v); }
static T Log2(T v) { return log(v)/log((T)2); } // Logarithm base 2
static T Log10(T v) { return log10(v); } // Logarithm base 10
static T Exp(T v) { return exp(v); }
static T Abs(T v) { return (v>=0) ? v : -v; }
static T Sqrt(T v) { return sqrt(v); }
static T Rint(T v) { return floor(v + (T)0.5); }
static T Sign(T v) { return (T)((v<0) ? -1 : (v>0) ? 1 : 0); }
static T Pow(T v1, T v2) { return std::pow(v1, v2); }
};
// Create (mostly) dummy math function definitions for integer types. They are mostly
// empty since they are not applicable for integer values.
#define MAKE_MATH_DUMMY(TYPE) \
template<> \
struct MathImpl<TYPE> \
{ \
static TYPE Sin(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE Cos(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE Tan(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE ASin(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE ACos(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE ATan(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE ATan2(TYPE, TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE Sinh(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE Cosh(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE Tanh(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE ASinh(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE ACosh(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE ATanh(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE Log(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE Log2(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE Log10(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE Exp(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE Abs(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE Sqrt(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE Rint(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE Sign(TYPE v) { return (TYPE)((v<0) ? -1 : (v>0) ? 1 : 0); } \
static TYPE Pow(TYPE v1, TYPE v2) { return (TYPE)std::pow((double)v1, (double)v2); } \
};
MAKE_MATH_DUMMY(char)
MAKE_MATH_DUMMY(short)
MAKE_MATH_DUMMY(int)
MAKE_MATH_DUMMY(long)
#undef MAKE_MATH_DUMMY
}
#endif

View file

@ -88,7 +88,7 @@ namespace qmu
int QmuParserTester::TestInterface() int QmuParserTester::TestInterface()
{ {
int iStat = 0; int iStat = 0;
mu::console() << "testing member functions..."; qmu::console() << "testing member functions...";
// Test RemoveVar // Test RemoveVar
qreal afVal[3] = {1,2,3}; qreal afVal[3] = {1,2,3};
@ -119,9 +119,9 @@ namespace qmu
} }
if (iStat==0) if (iStat==0)
mu::console() << "passed" << endl; qmu::console() << "passed" << endl;
else else
mu::console() << "\n failed with " << iStat << " errors" << endl; qmu::console() << "\n failed with " << iStat << " errors" << endl;
return iStat; return iStat;
} }
@ -130,7 +130,7 @@ namespace qmu
int QmuParserTester::TestStrArg() int QmuParserTester::TestStrArg()
{ {
int iStat = 0; int iStat = 0;
mu::console() << "testing string arguments..."; qmu::console() << "testing string arguments...";
iStat += EqnTest("valueof(\"\")", 123, true); // empty string arguments caused a crash iStat += EqnTest("valueof(\"\")", 123, true); // empty string arguments caused a crash
iStat += EqnTest("valueof(\"aaa\")+valueof(\"bbb\") ", 246, true); iStat += EqnTest("valueof(\"aaa\")+valueof(\"bbb\") ", 246, true);
@ -144,9 +144,9 @@ namespace qmu
iStat += EqnTest("strfun3(\"99\",1,2)", 102, true); iStat += EqnTest("strfun3(\"99\",1,2)", 102, true);
if (iStat==0) if (iStat==0)
mu::console() << "passed" << endl; qmu::console() << "passed" << endl;
else else
mu::console() << "\n failed with " << iStat << " errors" << endl; qmu::console() << "\n failed with " << iStat << " errors" << endl;
return iStat; return iStat;
} }
@ -155,7 +155,7 @@ namespace qmu
int QmuParserTester::TestBinOprt() int QmuParserTester::TestBinOprt()
{ {
int iStat = 0; int iStat = 0;
mu::console() << "testing binary operators..."; qmu::console() << "testing binary operators...";
// built in operators // built in operators
// xor operator // xor operator
@ -288,9 +288,9 @@ namespace qmu
if (iStat==0) if (iStat==0)
mu::console() << "passed" << endl; qmu::console() << "passed" << endl;
else else
mu::console() << "\n failed with " << iStat << " errors" << endl; qmu::console() << "\n failed with " << iStat << " errors" << endl;
return iStat; return iStat;
} }
@ -302,7 +302,7 @@ namespace qmu
int iStat= 0, int iStat= 0,
iErr = 0; iErr = 0;
mu::console() << "testing name restriction enforcement..."; qmu::console() << "testing name restriction enforcement...";
QmuParser p; QmuParser p;
@ -397,9 +397,9 @@ namespace qmu
#undef PARSER_THROWCHECK #undef PARSER_THROWCHECK
if (iStat==0) if (iStat==0)
mu::console() << "passed" << endl; qmu::console() << "passed" << endl;
else else
mu::console() << "\n failed with " << iStat << " errors" << endl; qmu::console() << "\n failed with " << iStat << " errors" << endl;
return iStat; return iStat;
} }
@ -408,7 +408,7 @@ namespace qmu
int QmuParserTester::TestSyntax() int QmuParserTester::TestSyntax()
{ {
int iStat = 0; int iStat = 0;
mu::console() << "testing syntax engine..."; qmu::console() << "testing syntax engine...";
iStat += ThrowTest("1,", ecUNEXPECTED_EOF); // incomplete hex definition iStat += ThrowTest("1,", ecUNEXPECTED_EOF); // incomplete hex definition
iStat += ThrowTest("a,", ecUNEXPECTED_EOF); // incomplete hex definition iStat += ThrowTest("a,", ecUNEXPECTED_EOF); // incomplete hex definition
@ -446,9 +446,9 @@ namespace qmu
iStat += EqnTest("sin()", 0, false); // unexpected closing bracket iStat += EqnTest("sin()", 0, false); // unexpected closing bracket
if (iStat==0) if (iStat==0)
mu::console() << "passed" << endl; qmu::console() << "passed" << endl;
else else
mu::console() << "\n failed with " << iStat << " errors" << endl; qmu::console() << "\n failed with " << iStat << " errors" << endl;
return iStat; return iStat;
} }
@ -457,7 +457,7 @@ namespace qmu
int QmuParserTester::TestVarConst() int QmuParserTester::TestVarConst()
{ {
int iStat = 0; int iStat = 0;
mu::console() << "testing variable/constant detection..."; qmu::console() << "testing variable/constant detection...";
// Test if the result changes when a variable changes // Test if the result changes when a variable changes
iStat += EqnTestWithVarChange( "a", 1, 1, 2, 2 ); iStat += EqnTestWithVarChange( "a", 1, 1, 2, 2 );
@ -504,7 +504,7 @@ namespace qmu
// Test lookup of defined variables // Test lookup of defined variables
// 4 used variables // 4 used variables
p.SetExpr( "a+b+c+d" ); p.SetExpr( "a+b+c+d" );
mu::varmap_type UsedVar = p.GetUsedVar(); qmu::varmap_type UsedVar = p.GetUsedVar();
int iCount = (int)UsedVar.size(); int iCount = (int)UsedVar.size();
if (iCount!=4) if (iCount!=4)
throw false; throw false;
@ -514,7 +514,7 @@ namespace qmu
if (p.GetVar().size()!=5) if (p.GetVar().size()!=5)
throw false; throw false;
mu::varmap_type::const_iterator item = UsedVar.begin(); qmu::varmap_type::const_iterator item = UsedVar.begin();
for (idx=0; item!=UsedVar.end(); ++item) for (idx=0; item!=UsedVar.end(); ++item)
{ {
if (&vVarVal[idx++]!=item->second) if (&vVarVal[idx++]!=item->second)
@ -555,9 +555,9 @@ namespace qmu
} }
if (iStat==0) if (iStat==0)
mu::console() << "passed" << endl; qmu::console() << "passed" << endl;
else else
mu::console() << "\n failed with " << iStat << " errors" << endl; qmu::console() << "\n failed with " << iStat << " errors" << endl;
return iStat; return iStat;
} }
@ -566,7 +566,7 @@ namespace qmu
int QmuParserTester::TestMultiArg() int QmuParserTester::TestMultiArg()
{ {
int iStat = 0; int iStat = 0;
mu::console() << "testing multiarg functions..."; qmu::console() << "testing multiarg functions...";
// Compound expressions // Compound expressions
iStat += EqnTest( "1,2,3", 3, true); iStat += EqnTest( "1,2,3", 3, true);
@ -649,9 +649,9 @@ namespace qmu
iStat += EqnTest( "sum(,1,2)", 0, false); iStat += EqnTest( "sum(,1,2)", 0, false);
if (iStat==0) if (iStat==0)
mu::console() << "passed" << endl; qmu::console() << "passed" << endl;
else else
mu::console() << "\n failed with " << iStat << " errors" << endl; qmu::console() << "\n failed with " << iStat << " errors" << endl;
return iStat; return iStat;
} }
@ -661,7 +661,7 @@ namespace qmu
int QmuParserTester::TestInfixOprt() int QmuParserTester::TestInfixOprt()
{ {
int iStat(0); int iStat(0);
mu::console() << "testing infix operators..."; qmu::console() << "testing infix operators...";
iStat += EqnTest( "-1", -1, true); iStat += EqnTest( "-1", -1, true);
iStat += EqnTest( "-(-1)", 1, true); iStat += EqnTest( "-(-1)", 1, true);
@ -714,9 +714,9 @@ namespace qmu
iStat += EqnTest( "~~ 123", 123+2, true); iStat += EqnTest( "~~ 123", 123+2, true);
if (iStat==0) if (iStat==0)
mu::console() << "passed" << endl; qmu::console() << "passed" << endl;
else else
mu::console() << "\n failed with " << iStat << " errors" << endl; qmu::console() << "\n failed with " << iStat << " errors" << endl;
return iStat; return iStat;
} }
@ -726,7 +726,7 @@ namespace qmu
int QmuParserTester::TestPostFix() int QmuParserTester::TestPostFix()
{ {
int iStat = 0; int iStat = 0;
mu::console() << "testing postfix operators..."; qmu::console() << "testing postfix operators...";
// application // application
iStat += EqnTest( "3{m}+5", 5.003, true); iStat += EqnTest( "3{m}+5", 5.003, true);
@ -766,9 +766,9 @@ namespace qmu
iStat += ThrowTest( "multi*1.0", ecUNASSIGNABLE_TOKEN); iStat += ThrowTest( "multi*1.0", ecUNASSIGNABLE_TOKEN);
if (iStat==0) if (iStat==0)
mu::console() << "passed" << endl; qmu::console() << "passed" << endl;
else else
mu::console() << "\n failed with " << iStat << " errors" << endl; qmu::console() << "\n failed with " << iStat << " errors" << endl;
return iStat; return iStat;
} }
@ -777,7 +777,7 @@ namespace qmu
int QmuParserTester::TestExpression() int QmuParserTester::TestExpression()
{ {
int iStat = 0; int iStat = 0;
mu::console() << "testing expression samples..."; qmu::console() << "testing expression samples...";
qreal b = 2; qreal b = 2;
@ -846,9 +846,9 @@ namespace qmu
iStat += EqnTest( "1+2-3*4/5^6*(2*(1-5+(3*7^9)*(4+6*7-3)))+12", -7995810.09926, true); iStat += EqnTest( "1+2-3*4/5^6*(2*(1-5+(3*7^9)*(4+6*7-3)))+12", -7995810.09926, true);
if (iStat==0) if (iStat==0)
mu::console() << "passed" << endl; qmu::console() << "passed" << endl;
else else
mu::console() << "\n failed with " << iStat << " errors" << endl; qmu::console() << "\n failed with " << iStat << " errors" << endl;
return iStat; return iStat;
} }
@ -859,7 +859,7 @@ namespace qmu
int QmuParserTester::TestIfThenElse() int QmuParserTester::TestIfThenElse()
{ {
int iStat = 0; int iStat = 0;
mu::console() << "testing if-then-else operator..."; qmu::console() << "testing if-then-else operator...";
// Test error detection // Test error detection
iStat += ThrowTest(":3", ecUNEXPECTED_CONDITIONAL); iStat += ThrowTest(":3", ecUNEXPECTED_CONDITIONAL);
@ -954,9 +954,9 @@ namespace qmu
iStat += EqnTest("a=0?5:b=1?3:4, b", 3, true); iStat += EqnTest("a=0?5:b=1?3:4, b", 3, true);
if (iStat==0) if (iStat==0)
mu::console() << "passed" << endl; qmu::console() << "passed" << endl;
else else
mu::console() << "\n failed with " << iStat << " errors" << endl; qmu::console() << "\n failed with " << iStat << " errors" << endl;
return iStat; return iStat;
} }
@ -965,7 +965,7 @@ namespace qmu
int QmuParserTester::TestException() int QmuParserTester::TestException()
{ {
int iStat = 0; int iStat = 0;
mu::console() << "testing error codes..."; qmu::console() << "testing error codes...";
iStat += ThrowTest("3+", ecUNEXPECTED_EOF); iStat += ThrowTest("3+", ecUNEXPECTED_EOF);
iStat += ThrowTest("3+)", ecUNEXPECTED_PARENS); iStat += ThrowTest("3+)", ecUNEXPECTED_PARENS);
@ -1048,9 +1048,9 @@ namespace qmu
iStat += ThrowTest( "a=\"tttt\"", ecOPRT_TYPE_CONFLICT); iStat += ThrowTest( "a=\"tttt\"", ecOPRT_TYPE_CONFLICT);
if (iStat==0) if (iStat==0)
mu::console() << "passed" << endl; qmu::console() << "passed" << endl;
else else
mu::console() << "\n failed with " << iStat << " errors" << endl; qmu::console() << "\n failed with " << iStat << " errors" << endl;
return iStat; return iStat;
} }
@ -1073,28 +1073,28 @@ namespace qmu
} }
catch(QmuParser::exception_type &e) catch(QmuParser::exception_type &e)
{ {
mu::console() << "\n" << e.GetMsg() << endl; qmu::console() << "\n" << e.GetMsg() << endl;
mu::console() << e.GetToken() << endl; qmu::console() << e.GetToken() << endl;
Abort(); Abort();
} }
catch(std::exception &e) catch(std::exception &e)
{ {
mu::console() << e.what() << endl; qmu::console() << e.what() << endl;
Abort(); Abort();
} }
catch(...) catch(...)
{ {
mu::console() << "Internal error"; qmu::console() << "Internal error";
Abort(); Abort();
} }
if (iStat==0) if (iStat==0)
{ {
mu::console() << "Test passed (" << QmuParserTester::c_iCount << " expressions)" << endl; qmu::console() << "Test passed (" << QmuParserTester::c_iCount << " expressions)" << endl;
} }
else else
{ {
mu::console() << "Test failed with " << iStat qmu::console() << "Test failed with " << iStat
<< " errors (" << QmuParserTester::c_iCount << " errors (" << QmuParserTester::c_iCount
<< " expressions)" << endl; << " expressions)" << endl;
} }
@ -1130,7 +1130,7 @@ namespace qmu
// output the formula in case of an failed test // output the formula in case of an failed test
if (a_bFail==false || (a_bFail==true && a_iErrc!=e.GetCode()) ) if (a_bFail==false || (a_bFail==true && a_iErrc!=e.GetCode()) )
{ {
mu::console() << "\n " qmu::console() << "\n "
<< "Expression: " << a_str << "Expression: " << a_str
<< " Code:" << e.GetCode() << "(" << e.GetMsg() << ")" << " Code:" << e.GetCode() << "(" << e.GetMsg() << ")"
<< " Expected:" << a_iErrc; << " Expected:" << a_iErrc;
@ -1143,7 +1143,7 @@ namespace qmu
bool bRet((a_bFail==false) ? 0 : 1); bool bRet((a_bFail==false) ? 0 : 1);
if (bRet==1) if (bRet==1)
{ {
mu::console() << "\n " qmu::console() << "\n "
<< "Expression: " << a_str << "Expression: " << a_str
<< " did evaluate; Expected error:" << a_iErrc; << " did evaluate; Expected error:" << a_iErrc;
} }
@ -1188,17 +1188,17 @@ namespace qmu
} }
catch(QmuParser::exception_type &e) catch(QmuParser::exception_type &e)
{ {
mu::console() << "\n fail: " << a_str.c_str() << " (" << e.GetMsg() << ")"; qmu::console() << "\n fail: " << a_str.c_str() << " (" << e.GetMsg() << ")";
return 1; return 1;
} }
catch(std::exception &e) catch(std::exception &e)
{ {
mu::console() << "\n fail: " << a_str.c_str() << " (" << e.what() << ")"; qmu::console() << "\n fail: " << a_str.c_str() << " (" << e.what() << ")";
return 1; // always return a failure since this exception is not expected return 1; // always return a failure since this exception is not expected
} }
catch(...) catch(...)
{ {
mu::console() << "\n fail: " << a_str.c_str() << " (unexpected exception)"; qmu::console() << "\n fail: " << a_str.c_str() << " (unexpected exception)";
return 1; // exceptions other than ParserException are not allowed return 1; // exceptions other than ParserException are not allowed
} }
@ -1329,7 +1329,7 @@ namespace qmu
} }
catch(std::exception &e) catch(std::exception &e)
{ {
mu::console() << "\n " << e.what() << "\n"; qmu::console() << "\n " << e.what() << "\n";
} }
// limited floating point accuracy requires the following test // limited floating point accuracy requires the following test
@ -1350,7 +1350,7 @@ namespace qmu
if (iRet==1) if (iRet==1)
{ {
mu::console() << "\n fail: " << a_str.c_str() qmu::console() << "\n fail: " << a_str.c_str()
<< " (incorrect result; expected: " << a_fRes << " (incorrect result; expected: " << a_fRes
<< " ;calculated: " << fVal[0] << "," << " ;calculated: " << fVal[0] << ","
<< fVal[1] << "," << fVal[1] << ","
@ -1364,20 +1364,20 @@ namespace qmu
if (a_fPass) if (a_fPass)
{ {
if (fVal[0]!=fVal[2] && fVal[0]!=-999 && fVal[1]!=-998) if (fVal[0]!=fVal[2] && fVal[0]!=-999 && fVal[1]!=-998)
mu::console() << "\n fail: " << a_str.c_str() << " (copy construction)"; qmu::console() << "\n fail: " << a_str.c_str() << " (copy construction)";
else else
mu::console() << "\n fail: " << a_str.c_str() << " (" << e.GetMsg() << ")"; qmu::console() << "\n fail: " << a_str.c_str() << " (" << e.GetMsg() << ")";
return 1; return 1;
} }
} }
catch(std::exception &e) catch(std::exception &e)
{ {
mu::console() << "\n fail: " << a_str.c_str() << " (" << e.what() << ")"; qmu::console() << "\n fail: " << a_str.c_str() << " (" << e.what() << ")";
return 1; // always return a failure since this exception is not expected return 1; // always return a failure since this exception is not expected
} }
catch(...) catch(...)
{ {
mu::console() << "\n fail: " << a_str.c_str() << " (unexpected exception)"; qmu::console() << "\n fail: " << a_str.c_str() << " (unexpected exception)";
return 1; // exceptions other than ParserException are not allowed return 1; // exceptions other than ParserException are not allowed
} }
@ -1413,7 +1413,7 @@ namespace qmu
(a_fRes!=fVal[0] && !a_fPass) ) ? 0 : 1; (a_fRes!=fVal[0] && !a_fPass) ) ? 0 : 1;
if (iRet==1) if (iRet==1)
{ {
mu::console() << "\n fail: " << a_str.c_str() qmu::console() << "\n fail: " << a_str.c_str()
<< " (incorrect result; expected: " << a_fRes << " (incorrect result; expected: " << a_fRes
<< " ;calculated: " << fVal[0]<< ")."; << " ;calculated: " << fVal[0]<< ").";
} }
@ -1422,13 +1422,13 @@ namespace qmu
{ {
if (a_fPass) if (a_fPass)
{ {
mu::console() << "\n fail: " << e.GetExpr() << " : " << e.GetMsg(); qmu::console() << "\n fail: " << e.GetExpr() << " : " << e.GetMsg();
iRet = 1; iRet = 1;
} }
} }
catch(...) catch(...)
{ {
mu::console() << "\n fail: " << a_str.c_str() << " (unexpected exception)"; qmu::console() << "\n fail: " << a_str.c_str() << " (unexpected exception)";
iRet = 1; // exceptions other than ParserException are not allowed iRet = 1; // exceptions other than ParserException are not allowed
} }
@ -1439,7 +1439,7 @@ namespace qmu
/** \brief Internal error in test class Test is going to be aborted. */ /** \brief Internal error in test class Test is going to be aborted. */
void QmuParserTester::Abort() const void QmuParserTester::Abort() const
{ {
mu::console() << "Test failed (internal error in test class)" << endl; qmu::console() << "Test failed (internal error in test class)" << endl;
while (!getchar()); while (!getchar());
exit(-1); exit(-1);
} }

View file

@ -28,6 +28,7 @@
#include <stack> #include <stack>
#include <vector> #include <vector>
#include <memory> #include <memory>
#include <QtGlobal>
#include "qmuparsererror.h" #include "qmuparsererror.h"
#include "qmuparsercallback.h" #include "qmuparsercallback.h"