diff --git a/src/app/app.pro b/src/app/app.pro index 797def619..5ac95217c 100644 --- a/src/app/app.pro +++ b/src/app/app.pro @@ -102,7 +102,7 @@ CONFIG(debug, debug|release){ -Wmissing-include-dirs -Wpacked -Wredundant-decls -Winline \ -Wswitch-default -Wswitch-enum -Wuninitialized -Wvariadic-macros \ -Wlogical-op -Wnoexcept -Wmissing-noreturn -Wpointer-arith\ - -Wstrict-null-sentinel -Wstrict-overflow=5 -Wundef -Wno-unused -gdwarf-3 + -Wstrict-null-sentinel -Wstrict-overflow=5 -Wundef -Wno-unused -gdwarf-3 \ -ftrapv } } else { diff --git a/src/app/exception/vexception.h b/src/app/exception/vexception.h index 9771bb004..32a57f035 100644 --- a/src/app/exception/vexception.h +++ b/src/app/exception/vexception.h @@ -42,26 +42,26 @@ class VException : public QException { Q_DECLARE_TR_FUNCTIONS(VException) public: - /** - * @brief VException constructor exception - * @param what string with error - */ - VException(const QString &what); - /** - * @brief VException copy constructor - * @param e exception - */ - VException(const VException &e); - virtual ~VException() noexcept (true){} + /** + * @brief VException constructor exception + * @param what string with error + */ + VException(const QString &what); + /** + * @brief VException copy constructor + * @param e exception + */ + VException(const VException &e); + virtual ~VException() noexcept (true){} /** * @brief raise method raise for exception */ - void raise() const; + virtual void raise() const; /** * @brief clone clone exception * @return new exception */ - VException *clone() const; + virtual VException *clone() const; /** * @brief ErrorMessage return main error message * @return error message diff --git a/src/app/main.cpp b/src/app/main.cpp index b5facc0d5..299b22f91 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -74,8 +74,9 @@ void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &context, c switch (type) { case QtDebugMsg: - fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, - context.function); + fprintf(stderr, "Debug: %s\n", localMsg.constData()); +// fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, +// context.function); return; case QtWarningMsg: messageBox.setIcon(QMessageBox::Warning); diff --git a/src/libs/qmuparser/qmuparser.cpp b/src/libs/qmuparser/qmuparser.cpp index 96fc7b9c7..9c64c5e38 100644 --- a/src/libs/qmuparser/qmuparser.cpp +++ b/src/libs/qmuparser/qmuparser.cpp @@ -131,7 +131,7 @@ qreal QmuParser::Sum(const qreal *a_afArg, int a_iArgc) { if (a_iArgc == false) { - throw exception_type("too few arguments for function sum."); + throw QmuParserError("too few arguments for function sum."); } qreal fRes=0; for (int i=0; i #endif +#include "qmuparsererror.h" +#include "qmuparsertokenreader.h" + using namespace std; /** @@ -438,19 +441,19 @@ void QmuParserBase::CheckOprt(const QString &a_sName, const QmuParserCallback &a Q_UNREACHABLE(); break; case cmVARPOW2: - Q_UNREACHABLE(); + // For optimization purposes break; case cmVARPOW3: - Q_UNREACHABLE(); + // For optimization purposes break; case cmVARPOW4: - Q_UNREACHABLE(); + // For optimization purposes break; case cmVARMUL: - Q_UNREACHABLE(); + // For optimization purposes break; case cmPOW2: - Q_UNREACHABLE(); + // For optimization purposes break; case cmFUNC: Q_UNREACHABLE(); @@ -937,7 +940,7 @@ const varmap_type& QmuParserBase::GetUsedVar() const m_pParseFormula = &QmuParserBase::ParseString; m_pTokenReader->IgnoreUndefVar(false); } - catch (const exception_type &e) + catch (const QmuParserError &e) { // Make sure to stay in string parse mode, dont call ReInit() // because it deletes the array with the used variables @@ -995,7 +998,7 @@ const QString& QmuParserBase::GetExpr() const /** * @brief Execute a function that takes a single string argument. * @param a_FunTok Function token. - * @throw exception_type If the function token is not a string function + * @throw QmuParserError If the function token is not a string function */ QmuParserBase::token_type QmuParserBase::ApplyStrFunc(const token_type &a_FunTok, const QVector &a_vArg) const @@ -1052,7 +1055,7 @@ QmuParserBase::token_type QmuParserBase::ApplyStrFunc(const token_type &a_FunTok * @param iArgCount Number of Arguments actually gathered used only for multiarg functions. * @post The result is pushed to the value stack * @post The function token is removed from the stack - * @throw exception_type if Argument count does not mach function requirements. + * @throw QmuParserError if Argument count does not mach function requirements. */ void QmuParserBase::ApplyFunc( QStack &a_stOpt, QStack &a_stVal, int a_iArgCount) const { @@ -2051,7 +2054,7 @@ qreal QmuParserBase::ParseString() const m_pParseFormula = &QmuParserBase::ParseCmdCode; return (this->*m_pParseFormula)(); } - catch (QmuParserError &exc) + catch (qmu::QmuParserError &exc) { exc.SetFormula(m_pTokenReader->GetExpr()); throw; @@ -2071,7 +2074,7 @@ qreal QmuParserBase::ParseString() const */ void Q_NORETURN QmuParserBase::Error(EErrorCodes a_iErrc, int a_iPos, const QString &a_sTok) const { - throw exception_type(a_iErrc, a_sTok, m_pTokenReader->GetExpr(), a_iPos); + throw qmu::QmuParserError (a_iErrc, a_sTok, m_pTokenReader->GetExpr(), a_iPos); } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/qmuparser/qmuparserbase.h b/src/libs/qmuparser/qmuparserbase.h index a70adb5d8..62171abad 100644 --- a/src/libs/qmuparser/qmuparserbase.h +++ b/src/libs/qmuparser/qmuparserbase.h @@ -23,6 +23,7 @@ #ifndef QMUQPARSERBASE_H #define QMUQPARSERBASE_H +#include "qmuparser_global.h" #include #include #include @@ -51,17 +52,10 @@ namespace qmu * Complementary to a set of internally implemented functions the parser is able to handle * user defined functions and variables. */ -class QmuParserBase +class QMUPARSERSHARED_EXPORT QmuParserBase { friend class QmuParserTokenReader; public: - /** - * @brief Type of the error class. - * - * Included for backwards compatibility. - */ - typedef QmuParserError exception_type; - QmuParserBase(); QmuParserBase(const QmuParserBase &a_Parser); QmuParserBase& operator=(const QmuParserBase &a_Parser) Q_DECL_NOEXCEPT; @@ -112,7 +106,7 @@ public: const QString& ValidInfixOprtChars() const; void SetArgSep(char_type cArgSep); QChar GetArgSep() const; - void Error(EErrorCodes a_iErrc, int a_iPos = -1, const QString &a_strTok = QString() ) const; + void Q_NORETURN Error(EErrorCodes a_iErrc, int a_iPos = -1, const QString &a_strTok = QString() ) const; /** * @fn void qmu::QmuParserBase::DefineFun(const string_type &a_strName, fun_type0 a_pFun, * bool a_bAllowOpt = true) diff --git a/src/libs/qmuparser/qmuparserbytecode.cpp b/src/libs/qmuparser/qmuparserbytecode.cpp index 696163501..aa2a9e7be 100644 --- a/src/libs/qmuparser/qmuparserbytecode.cpp +++ b/src/libs/qmuparser/qmuparserbytecode.cpp @@ -430,10 +430,8 @@ void QmuParserByteCode::AddOp(ECmdCode a_Oprt) } break; case cmLE: - Q_UNREACHABLE(); break; case cmGE: - Q_UNREACHABLE(); break; case cmNEQ: Q_UNREACHABLE(); @@ -442,13 +440,10 @@ void QmuParserByteCode::AddOp(ECmdCode a_Oprt) Q_UNREACHABLE(); break; case cmLT: - Q_UNREACHABLE(); break; case cmGT: - Q_UNREACHABLE(); break; case cmLAND: - Q_UNREACHABLE(); break; case cmLOR: Q_UNREACHABLE(); @@ -670,10 +665,8 @@ void QmuParserByteCode::Finalize() Q_DECL_NOEXCEPT m_vRPN[idx].Oprt.offset = i - idx; break; case cmLE: - Q_UNREACHABLE(); break; case cmGE: - Q_UNREACHABLE(); break; case cmNEQ: Q_UNREACHABLE(); @@ -682,34 +675,25 @@ void QmuParserByteCode::Finalize() Q_DECL_NOEXCEPT Q_UNREACHABLE(); break; case cmLT: - Q_UNREACHABLE(); break; case cmGT: - Q_UNREACHABLE(); break; case cmADD: - Q_UNREACHABLE(); break; case cmSUB: - Q_UNREACHABLE(); break; case cmMUL: - Q_UNREACHABLE(); break; case cmDIV: - Q_UNREACHABLE(); break; case cmPOW: - Q_UNREACHABLE(); break; case cmLAND: - Q_UNREACHABLE(); break; case cmLOR: Q_UNREACHABLE(); break; case cmASSIGN: - Q_UNREACHABLE(); break; case cmBO: Q_UNREACHABLE(); @@ -721,31 +705,27 @@ void QmuParserByteCode::Finalize() Q_DECL_NOEXCEPT Q_UNREACHABLE(); break; case cmVAR: - Q_UNREACHABLE(); break; case cmVAL: - Q_UNREACHABLE(); break; case cmVARPOW2: - Q_UNREACHABLE(); + // For optimization purposes break; case cmVARPOW3: - Q_UNREACHABLE(); + // For optimization purposes break; case cmVARPOW4: - Q_UNREACHABLE(); + // For optimization purposes break; case cmVARMUL: - Q_UNREACHABLE(); + // For optimization purposes break; case cmPOW2: - Q_UNREACHABLE(); + // For optimization purposes break; case cmFUNC: - Q_UNREACHABLE(); break; case cmFUNC_STR: - Q_UNREACHABLE(); break; case cmFUNC_BULK: Q_UNREACHABLE(); @@ -763,7 +743,6 @@ void QmuParserByteCode::Finalize() Q_DECL_NOEXCEPT Q_UNREACHABLE(); break; case cmEND: - Q_UNREACHABLE(); break; case cmUNKNOWN: Q_UNREACHABLE(); diff --git a/src/libs/qmuparser/qmuparsererror.cpp b/src/libs/qmuparser/qmuparsererror.cpp index 6d01c8b39..0bdc28e81 100644 --- a/src/libs/qmuparser/qmuparsererror.cpp +++ b/src/libs/qmuparser/qmuparsererror.cpp @@ -109,7 +109,7 @@ QmuParserErrorMsg::QmuParserErrorMsg() * @brief Default constructor. */ QmuParserError::QmuParserError() - : m_sMsg(), m_sExpr(), m_sTok(), m_iPos ( -1 ), m_iErrc ( ecUNDEFINED ), + : QException(), m_sMsg(), m_sExpr(), m_sTok(), m_iPos ( -1 ), m_iErrc ( ecUNDEFINED ), m_ErrMsg ( QmuParserErrorMsg::Instance() ) {} @@ -120,7 +120,7 @@ QmuParserError::QmuParserError() * It does not contain any information but the error code. */ QmuParserError::QmuParserError ( EErrorCodes a_iErrc ) - : m_sMsg(), m_sExpr(), m_sTok(), m_iPos ( -1 ), m_iErrc ( a_iErrc ), + : QException(), m_sMsg(), m_sExpr(), m_sTok(), m_iPos ( -1 ), m_iErrc ( a_iErrc ), m_ErrMsg ( QmuParserErrorMsg::Instance() ) { m_sMsg = m_ErrMsg[m_iErrc]; @@ -133,7 +133,7 @@ QmuParserError::QmuParserError ( EErrorCodes a_iErrc ) * @brief Construct an error from a message text. */ QmuParserError::QmuParserError ( const QString &sMsg ) - : m_sMsg(sMsg), m_sExpr(), m_sTok(), m_iPos ( -1 ), m_iErrc ( ecUNDEFINED ), + : QException(), m_sMsg(sMsg), m_sExpr(), m_sTok(), m_iPos ( -1 ), m_iErrc ( ecUNDEFINED ), m_ErrMsg ( QmuParserErrorMsg::Instance() ) {} @@ -146,7 +146,7 @@ QmuParserError::QmuParserError ( const QString &sMsg ) * @param [in] a_iPos the position in the expression where the error occured. */ QmuParserError::QmuParserError ( EErrorCodes iErrc, const QString &sTok, const QString &sExpr, int iPos ) - : m_sMsg(), m_sExpr ( sExpr ), m_sTok ( sTok ), m_iPos ( iPos ), m_iErrc ( iErrc ), + : QException(), m_sMsg(), m_sExpr ( sExpr ), m_sTok ( sTok ), m_iPos ( iPos ), m_iErrc ( iErrc ), m_ErrMsg ( QmuParserErrorMsg::Instance() ) { m_sMsg = m_ErrMsg[m_iErrc]; @@ -162,7 +162,7 @@ QmuParserError::QmuParserError ( EErrorCodes iErrc, const QString &sTok, const Q * @param [in] sTok The token string related to this error. */ QmuParserError::QmuParserError ( EErrorCodes a_iErrc, int a_iPos, const QString &sTok ) - : m_sMsg(), m_sExpr(), m_sTok ( sTok ), m_iPos ( a_iPos ), m_iErrc ( a_iErrc ), + : QException(), m_sMsg(), m_sExpr(), m_sTok ( sTok ), m_iPos ( a_iPos ), m_iErrc ( a_iErrc ), m_ErrMsg ( QmuParserErrorMsg::Instance() ) { m_sMsg = m_ErrMsg[m_iErrc]; @@ -177,7 +177,7 @@ QmuParserError::QmuParserError ( EErrorCodes a_iErrc, int a_iPos, const QString * @param [in] sTok The token string related to this error. */ QmuParserError::QmuParserError ( const QString &szMsg, int iPos, const QString &sTok ) - : m_sMsg ( szMsg ), m_sExpr(), m_sTok ( sTok ), m_iPos ( iPos ), m_iErrc ( ecGENERIC ), + : QException(), m_sMsg ( szMsg ), m_sExpr(), m_sTok ( sTok ), m_iPos ( iPos ), m_iErrc ( ecGENERIC ), m_ErrMsg ( QmuParserErrorMsg::Instance() ) { ReplaceSubString ( m_sMsg, "$POS$", QString().setNum ( m_iPos ) ); @@ -187,7 +187,7 @@ QmuParserError::QmuParserError ( const QString &szMsg, int iPos, const QString & //--------------------------------------------------------------------------------------------------------------------- /** @brief Copy constructor. */ QmuParserError::QmuParserError ( const QmuParserError &a_Obj ) - : m_sMsg ( a_Obj.m_sMsg ), m_sExpr ( a_Obj.m_sExpr ), m_sTok ( a_Obj.m_sTok ), + : QException(), m_sMsg ( a_Obj.m_sMsg ), m_sExpr ( a_Obj.m_sExpr ), m_sTok ( a_Obj.m_sTok ), m_iPos ( a_Obj.m_iPos ), m_iErrc ( a_Obj.m_iErrc ), m_ErrMsg ( QmuParserErrorMsg::Instance() ) {} @@ -208,10 +208,6 @@ QmuParserError& QmuParserError::operator= ( const QmuParserError &a_Obj ) return *this; } -//--------------------------------------------------------------------------------------------------------------------- -QmuParserError::~QmuParserError() -{} - //--------------------------------------------------------------------------------------------------------------------- /** * @brief Replace all ocuurences of a substring with another string. @@ -309,4 +305,5 @@ EErrorCodes QmuParserError::GetCode() const { return m_iErrc; } + } // namespace qmu diff --git a/src/libs/qmuparser/qmuparsererror.h b/src/libs/qmuparser/qmuparsererror.h index dd450602f..249c654db 100644 --- a/src/libs/qmuparser/qmuparsererror.h +++ b/src/libs/qmuparser/qmuparsererror.h @@ -23,11 +23,9 @@ #ifndef QMUPARSERERROR_H #define QMUPARSERERROR_H -#include -#include -#include +#include "qmuparser_global.h" #include -#include +#include #include "qmuparserdef.h" @@ -117,10 +115,9 @@ private: Part of the math parser package. */ -class QmuParserError +class QMUPARSERSHARED_EXPORT QmuParserError : public QException { public: - QmuParserError(); explicit QmuParserError ( EErrorCodes a_iErrc ); explicit QmuParserError ( const QString &sMsg ); @@ -129,7 +126,7 @@ public: QmuParserError ( const QString &a_szMsg, int a_iPos, const QString &sTok = QString() ); QmuParserError ( const QmuParserError &a_Obj ); QmuParserError& operator= ( const QmuParserError &a_Obj ); - ~QmuParserError(); + virtual ~QmuParserError() noexcept (true){} void SetFormula ( const QString &a_strFormula ); const QString& GetExpr() const; @@ -138,6 +135,15 @@ public: const QString& GetToken() const; EErrorCodes GetCode() const; + /** + * @brief raise method raise for exception + */ + virtual void raise() const; + /** + * @brief clone clone exception + * @return new exception + */ + virtual QmuParserError *clone() const; private: QString m_sMsg; ///< The message string QString m_sExpr; ///< Formula string @@ -152,6 +158,16 @@ private: void Reset(); }; +inline void QmuParserError::raise() const +{ + throw *this; +} + +inline QmuParserError *QmuParserError::clone() const +{ + return new QmuParserError(*this); +} + } // namespace qmu #endif diff --git a/src/libs/qmuparser/qmuparsertest.cpp b/src/libs/qmuparser/qmuparsertest.cpp index 9bdd8bad4..cce7cdfc2 100644 --- a/src/libs/qmuparser/qmuparsertest.cpp +++ b/src/libs/qmuparser/qmuparsertest.cpp @@ -23,10 +23,8 @@ #include "qmuparsertest.h" #include #include - -#include -#include -#include +#include +#include "qmuparsererror.h" using namespace std; @@ -64,32 +62,33 @@ QmuParserTester::QmuParserTester() //--------------------------------------------------------------------------------------------------------------------- int QmuParserTester::IsHexVal ( const QString &a_szExpr, int *a_iPos, qreal *a_fVal ) { - if ( a_szExpr[1] == 0 || ( a_szExpr[0] != '0' || a_szExpr[1] != 'x' ) ) + if ( a_szExpr.data()[1] == 0 || ( a_szExpr.data()[0] != '0' || a_szExpr.data()[1] != 'x' ) ) { return 0; } unsigned iVal ( 0 ); - bool ok = false; - iVal = a_szExpr.toUInt ( &ok, 16 ); - if ( ok ) +#if defined(_UNICODE) + std::wstring a_szExprStd = a_szExpr.mid(2).toStdWString(); +#else + std::string a_szExprStd = a_szExpr.mid(2).toStdString(); +#endif + + // New code based on streams for UNICODE compliance: + stringstream_type::pos_type nPos(0); + stringstream_type ss(a_szExprStd); + ss >> std::hex >> iVal; + nPos = ss.tellg(); + + if (nPos==static_cast(0)) { - int nPos = a_szExpr.indexOf ( QString().setNum ( iVal, 16 ) ); - if ( nPos == 0 ) - { - return 1; - } - - *a_iPos += 2 + nPos; - *a_fVal = static_cast(iVal); return 1; } - else - { - return 0; - } + *a_iPos += static_cast(2 + nPos); + *a_fVal = static_cast(iVal); + return 1; } //--------------------------------------------------------------------------------------------------------------------- @@ -128,11 +127,11 @@ int QmuParserTester::TestInterface() if ( iStat == 0 ) { - qDebug() << "passed"; + qDebug() << "TestInterface passed"; } else { - qDebug() << "\n failed with " << iStat << " errors"; + qDebug() << "\n TestInterface failed with " << iStat << " errors"; } return iStat; @@ -157,11 +156,11 @@ int QmuParserTester::TestStrArg() if ( iStat == 0 ) { - qDebug() << "passed"; + qDebug() << "TestStrArg passed"; } else { - qDebug() << "\n failed with " << iStat << " errors"; + qDebug() << "\n TestStrArg failed with " << iStat << " errors"; } return iStat; @@ -232,11 +231,11 @@ int QmuParserTester::TestBinOprt() if ( iStat == 0 ) { - qDebug() << "passed"; + qDebug() << "TestBinOprt passed"; } else { - qDebug() << "\n failed with " << iStat << " errors"; + qDebug() << "\n TestBinOprt failed with " << iStat << " errors"; } return iStat; @@ -260,7 +259,7 @@ int QmuParserTester::TestNames() { \ p.Define##DOMAIN(EXPR, ARG); \ } \ - catch (QmuParser::exception_type&) \ + catch (QmuParserError &) \ { \ iErr = (FAIL==false) ? 0 : 1; \ } \ @@ -345,11 +344,11 @@ int QmuParserTester::TestNames() if ( iStat == 0 ) { - qDebug() << "passed"; + qDebug() << "TestNames passed"; } else { - qDebug() << "\n failed with " << iStat << " errors"; + qDebug() << "\n TestNames failed with " << iStat << " errors"; } return iStat; @@ -398,11 +397,11 @@ int QmuParserTester::TestSyntax() if ( iStat == 0 ) { - qDebug() << "passed"; + qDebug() << "TestSyntax passed"; } else { - qDebug() << "\n failed with " << iStat << " errors"; + qDebug() << "\n TestSyntax failed with " << iStat << " errors"; } return iStat; @@ -531,11 +530,11 @@ int QmuParserTester::TestVarConst() if ( iStat == 0 ) { - qDebug() << "passed"; + qDebug() << "TestVarConst passed"; } else { - qDebug() << "\n failed with " << iStat << " errors"; + qDebug() << "\n TestVarConst failed with " << iStat << " errors"; } return iStat; @@ -629,11 +628,11 @@ int QmuParserTester::TestMultiArg() if ( iStat == 0 ) { - qDebug() << "passed"; + qDebug() << "TestMultiArg passed"; } else { - qDebug() << "\n failed with " << iStat << " errors"; + qDebug() << "\n TestMultiArg failed with " << iStat << " errors"; } return iStat; @@ -698,11 +697,11 @@ int QmuParserTester::TestInfixOprt() if ( iStat == 0 ) { - qDebug() << "passed"; + qDebug() << "TestInfixOprt passed"; } else { - qDebug() << "\n failed with " << iStat << " errors"; + qDebug() << "\n TestInfixOprt failed with " << iStat << " errors"; } return iStat; @@ -754,11 +753,11 @@ int QmuParserTester::TestPostFix() if ( iStat == 0 ) { - qDebug() << "passed"; + qDebug() << "TestPostFix passed"; } else { - qDebug() << "\n failed with " << iStat << " errors"; + qDebug() << "\n TestPostFix failed with " << iStat << " errors"; } return iStat; @@ -792,6 +791,8 @@ int QmuParserTester::TestExpression() iStat += EqnTest ( "(2*b+1)*4", ( 2 * b + 1 ) * 4, true ); iStat += EqnTest ( "4*(2*b+1)", ( 2 * b + 1 ) * 4, true ); + // 2013-11-27 Issue 2: https://code.google.com/p/muparser/issues/detail?id=2 + iStat += EqnTest ( "1+2+3", 6, true ); // operator precedencs iStat += EqnTest ( "1+2-3*4/5^6", 2.99923, true ); @@ -839,11 +840,11 @@ int QmuParserTester::TestExpression() if ( iStat == 0 ) { - qDebug() << "passed"; + qDebug() << "TestExpression passed"; } else { - qDebug() << "\n failed with " << iStat << " errors"; + qDebug() << "\n TestExpression failed with " << iStat << " errors"; } return iStat; @@ -949,11 +950,11 @@ int QmuParserTester::TestIfThenElse() if ( iStat == 0 ) { - qDebug() << "passed"; + qDebug() << "TestIfThenElse passed"; } else { - qDebug() << "\n failed with " << iStat << " errors"; + qDebug() << "\n TestIfThenElse failed with " << iStat << " errors"; } return iStat; @@ -1047,11 +1048,11 @@ int QmuParserTester::TestException() if ( iStat == 0 ) { - qDebug() << "passed"; + qDebug() << "TestException passed"; } else { - qDebug() << "\n failed with " << iStat << " errors"; + qDebug() << "\n TestException failed with " << iStat << " errors"; } return iStat; @@ -1076,7 +1077,7 @@ void QmuParserTester::Run() iStat += ( this->*m_vTestFun[i] ) (); } } - catch ( QmuParser::exception_type &e ) + catch ( QmuParserError &e ) { qDebug() << "\n" << e.GetMsg(); qDebug() << e.GetToken(); @@ -1130,14 +1131,12 @@ int QmuParserTester::ThrowTest ( const QString &a_str, int a_iErrc, bool a_bFail p.SetExpr ( a_str ); p.Eval(); } - catch ( QmuParserError &e ) + catch ( const qmu::QmuParserError &e ) { // output the formula in case of an failed test if ( a_bFail == false || ( a_bFail == true && a_iErrc != e.GetCode() ) ) { - qDebug() << "\n " - << "Expression: " << a_str - << " Code:" << e.GetCode() << "(" << e.GetMsg() << ")" + qDebug() << "\n " << "Expression: " << a_str << " Code:" << e.GetCode() << "(" << e.GetMsg() << ")" << " Expected:" << a_iErrc; } @@ -1194,7 +1193,7 @@ int QmuParserTester::EqnTestWithVarChange ( const QString &a_str, double a_fVar1 throw std::runtime_error ( "incorrect result (second pass)" ); } } - catch ( QmuParser::exception_type &e ) + catch ( QmuParserError &e ) { qDebug() << "\n fail: " << a_str << " (" << e.GetMsg() << ")"; return 1; @@ -1308,7 +1307,7 @@ int QmuParserTester::EqnTest ( const QString &a_str, double a_fRes, bool a_fPass fVal[1] = p1->Eval(); // result from bytecode if ( qFuzzyCompare( fVal[0], fVal[1] ) == false ) { - throw QmuParser::exception_type ( "Bytecode / string parsing mismatch." ); + throw QmuParserError ( "Bytecode / string parsing mismatch." ); } // Test copy and assignement operators @@ -1379,7 +1378,7 @@ int QmuParserTester::EqnTest ( const QString &a_str, double a_fRes, bool a_fPass << fVal[4] << ")."; } } - catch ( QmuParser::exception_type &e ) + catch ( QmuParserError &e ) { if ( a_fPass ) { diff --git a/src/libs/qmuparser/qmuparsertest.h b/src/libs/qmuparser/qmuparsertest.h index ffa838ed8..0c02a88bb 100644 --- a/src/libs/qmuparser/qmuparsertest.h +++ b/src/libs/qmuparser/qmuparsertest.h @@ -23,9 +23,7 @@ #ifndef QMUPARSERTEST_H #define QMUPARSERTEST_H -#include -#include -#include // for accumulate +#include "qmuparser_global.h" #include "qmuparser.h" #include @@ -47,7 +45,7 @@ namespace Test * * (C) 2004-2011 Ingo Berg */ -class QmuParserTester // final +class QMUPARSERSHARED_EXPORT QmuParserTester // final { public: typedef int ( QmuParserTester::*testfun_type ) (); @@ -186,7 +184,7 @@ private: { if ( a_iArgc == false) { - throw qmu::QmuParser::exception_type ( "too few arguments for function FirstArg." ); + throw QmuParserError ( "too few arguments for function FirstArg." ); } return a_afArg[0]; @@ -196,7 +194,7 @@ private: { if ( a_iArgc == false) { - throw qmu::QmuParser::exception_type ( "too few arguments for function LastArg." ); + throw QmuParserError ( "too few arguments for function LastArg." ); } return a_afArg[a_iArgc - 1]; @@ -206,7 +204,7 @@ private: { if ( a_iArgc == false) { - throw qmu::QmuParser::exception_type ( "too few arguments for function sum." ); + throw QmuParserError ( "too few arguments for function sum." ); } qreal fRes = 0; diff --git a/src/libs/qmuparser/qmuparsertoken.h b/src/libs/qmuparser/qmuparsertoken.h index 92a2722c3..73db7485a 100644 --- a/src/libs/qmuparser/qmuparsertoken.h +++ b/src/libs/qmuparser/qmuparsertoken.h @@ -232,7 +232,7 @@ public: * * In cmSTRFUNC - This is the index to a string table in the main parser. * @param a_iIdx The index the string function result will take in the bytecode parser. - * @throw exception_type if #a_iIdx<0 or #m_iType!=cmSTRING + * @throw QmuParserError if #a_iIdx<0 or #m_iType!=cmSTRING */ void SetIdx ( int a_iIdx ) { @@ -250,7 +250,7 @@ public: * * In cmSTRFUNC - This is the index to a string table in the main parser. * - * @throw exception_type if #m_iIdx<0 or #m_iType!=cmSTRING + * @throw QmuParserError if #m_iIdx<0 or #m_iType!=cmSTRING * @return The index the result will take in the Bytecode calculatin array (#m_iIdx). */ int GetIdx() const @@ -327,7 +327,7 @@ public: * @brief Return the address of the callback function assoziated with function and operator tokens. * * @return The pointer stored in #m_pTok. - * @throw exception_type if token type is non of: + * @throw QmuParserError if token type is non of: *
    *
  • cmFUNC
  • *
  • cmSTRFUNC
  • @@ -348,7 +348,7 @@ public: * @brief Get value of the token. * * Only applicable to variable and value tokens. - * @throw exception_type if token is no value/variable token. + * @throw QmuParserError if token is no value/variable token. */ TBase GetVal() const { @@ -359,107 +359,39 @@ public: case cmVAR: return * ( reinterpret_cast(m_pTok) ); case cmLE: - Q_UNREACHABLE(); - break; case cmGE: - Q_UNREACHABLE(); - break; case cmNEQ: - Q_UNREACHABLE(); - break; case cmEQ: - Q_UNREACHABLE(); - break; case cmLT: - Q_UNREACHABLE(); - break; case cmGT: - Q_UNREACHABLE(); - break; case cmADD: - Q_UNREACHABLE(); - break; case cmSUB: - Q_UNREACHABLE(); - break; case cmMUL: - Q_UNREACHABLE(); - break; case cmDIV: - Q_UNREACHABLE(); - break; case cmPOW: - Q_UNREACHABLE(); - break; case cmLAND: - Q_UNREACHABLE(); - break; case cmLOR: - Q_UNREACHABLE(); - break; case cmASSIGN: - Q_UNREACHABLE(); - break; case cmBO: - Q_UNREACHABLE(); - break; case cmBC: - Q_UNREACHABLE(); - break; case cmIF: - Q_UNREACHABLE(); - break; case cmELSE: - Q_UNREACHABLE(); - break; case cmENDIF: - Q_UNREACHABLE(); - break; case cmARG_SEP: - Q_UNREACHABLE(); - break; case cmVARPOW2: - Q_UNREACHABLE(); - break; case cmVARPOW3: - Q_UNREACHABLE(); - break; case cmVARPOW4: - Q_UNREACHABLE(); - break; case cmVARMUL: - Q_UNREACHABLE(); - break; case cmPOW2: - Q_UNREACHABLE(); - break; case cmFUNC: - Q_UNREACHABLE(); - break; case cmFUNC_STR: - Q_UNREACHABLE(); - break; case cmFUNC_BULK: - Q_UNREACHABLE(); - break; - case cmSTRING: - Q_UNREACHABLE(); - break; case cmOPRT_BIN: - Q_UNREACHABLE(); - break; case cmOPRT_POSTFIX: - Q_UNREACHABLE(); - break; case cmOPRT_INFIX: - Q_UNREACHABLE(); - break; case cmEND: - Q_UNREACHABLE(); - break; case cmUNKNOWN: - Q_UNREACHABLE(); - break; + case cmSTRING: default: throw QmuParserError ( ecVAL_EXPECTED ); } @@ -470,7 +402,7 @@ public: * @brief Get address of a variable token. * * Valid only if m_iType==CmdVar. - * @throw exception_type if token is no variable token. + * @throw QmuParserError if token is no variable token. */ TBase* GetVar() const { diff --git a/src/libs/qmuparser/qmuparsertokenreader.cpp b/src/libs/qmuparser/qmuparsertokenreader.cpp index 6944656b9..e16e6404f 100644 --- a/src/libs/qmuparser/qmuparsertokenreader.cpp +++ b/src/libs/qmuparser/qmuparsertokenreader.cpp @@ -254,15 +254,10 @@ QmuParserTokenReader::token_type QmuParserTokenReader::ReadNextToken() { assert ( m_pParser ); -#if defined(_UNICODE) - const char_type *szFormula = m_strFormula.toStdWString().c_str(); -#else - const char_type *szFormula = m_strFormula.toStdString().c_str(); -#endif token_type tok; // Ignore all non printable characters when reading the expression - while ( szFormula[m_iPos] > 0 && szFormula[m_iPos] <= 0x20 ) + while ( m_strFormula.data()[m_iPos] > 0 && m_strFormula.data()[m_iPos] <= 0x20 ) { ++m_iPos; } @@ -452,7 +447,7 @@ bool QmuParserTokenReader::IsBuiltIn ( token_type &a_Tok ) for ( int i = 0; i < pOprtDef.size(); ++i ) { int len = pOprtDef.at ( i ).length(); - if ( pOprtDef.at ( i ) == m_strFormula.mid ( m_iPos, m_iPos + len ) ) + if ( pOprtDef.at ( i ) == m_strFormula.mid ( m_iPos, len ) ) { switch ( i ) { @@ -596,23 +591,31 @@ bool QmuParserTokenReader::IsArgSep ( token_type &a_Tok ) * * @return true if an end of formula is found false otherwise. * @param a_Tok [out] If an eof is found the corresponding token will be stored there. - * @throw nothrow * @sa IsOprt, IsFunTok, IsStrFunTok, IsValTok, IsVarTok, IsString, IsInfixOpTok, IsPostOpTok */ -bool QmuParserTokenReader::IsEOF ( token_type &a_Tok ) Q_DECL_NOEXCEPT +bool QmuParserTokenReader::IsEOF ( token_type &a_Tok ) { -#if defined(_UNICODE) - const char_type* szFormula = m_strFormula.toStdWString().c_str(); -#else - const char_type* szFormula = m_strFormula.toStdString().c_str(); -#endif +//#if defined(_UNICODE) +// const char_type* szFormula = m_strFormula.toStdWString().c_str(); +//#else +// const char_type* szFormula = m_strFormula.toStdString().c_str(); +//#endif // check for EOF - if ( szFormula[m_iPos] == false /*|| szFormula[m_iPos] == '\n'*/ ) + if ( m_strFormula.data()[m_iPos] == false /*|| szFormula[m_iPos] == '\n'*/ ) { if ( m_iSynFlags & noEND ) { - Error ( ecUNEXPECTED_EOF, m_iPos ); + try + { + Error ( ecUNEXPECTED_EOF, m_iPos ); + } + catch (qmu::QmuParserError &e) + { + qDebug() << "\n " + << " Code:" << e.GetCode() << "(" << e.GetMsg() << ")"; + throw e; + } } if ( m_iBrackets > 0 ) @@ -756,7 +759,7 @@ bool QmuParserTokenReader::IsOprt ( token_type &a_Tok ) for ( ; it != m_pOprtDef->rend(); ++it ) { const QString &sID = it->first; - if ( sID == m_strFormula.mid ( m_iPos, m_iPos + sID.length() ) ) + if ( sID == m_strFormula.mid ( m_iPos, sID.length() ) ) { a_Tok.Set ( it->second, strTok ); @@ -891,7 +894,8 @@ bool QmuParserTokenReader::IsValTok ( token_type &a_Tok ) if ( ( *item ) ( m_strFormula.mid ( m_iPos ), &m_iPos, &fVal ) == 1 ) { // 2013-11-27 Issue 2: https://code.google.com/p/muparser/issues/detail?id=2 - strTok = m_strFormula.mid ( iStart, m_iPos-iStart ); + //strTok = m_strFormula.mid ( iStart, m_iPos-iStart ); + strTok = m_strFormula.mid ( iStart, m_iPos ); if ( m_iSynFlags & noVAL ) { Error ( ecUNEXPECTED_VAL, m_iPos - strTok.length(), strTok ); @@ -1050,16 +1054,15 @@ bool QmuParserTokenReader::IsUndefVarTok ( token_type &a_Tok ) Q_DECL_NOEXCEPT * @param a_Tok [out] If a variable token has been found it will be placed here. * @return true if a string token has been found. * @sa IsOprt, IsFunTok, IsStrFunTok, IsValTok, IsVarTok, IsEOF, IsInfixOpTok, IsPostOpTok - * @throw nothrow */ -bool QmuParserTokenReader::IsString ( token_type &a_Tok ) Q_DECL_NOEXCEPT +bool QmuParserTokenReader::IsString ( token_type &a_Tok ) { if ( m_strFormula[m_iPos] != '"' ) { return false; } - QString strBuf ( m_strFormula[m_iPos + 1] ); + QString strBuf (m_strFormula.mid(m_iPos + 1)); int iEnd ( 0 ), iSkip ( 0 ); // parser over escaped '\"' end replace them with '"' @@ -1105,7 +1108,7 @@ bool QmuParserTokenReader::IsString ( token_type &a_Tok ) Q_DECL_NOEXCEPT * @param a_strTok [in] The token string representation associated with the error. * @throw ParserException always throws thats the only purpose of this function. */ -void QmuParserTokenReader::Error ( EErrorCodes a_iErrc, int a_iPos, const QString &a_sTok ) const +void Q_NORETURN QmuParserTokenReader::Error ( EErrorCodes a_iErrc, int a_iPos, const QString &a_sTok ) const { m_pParser->Error ( a_iErrc, a_iPos, a_sTok ); } diff --git a/src/libs/qmuparser/qmuparsertokenreader.h b/src/libs/qmuparser/qmuparsertokenreader.h index 93af5ad12..17ed8a50f 100644 --- a/src/libs/qmuparser/qmuparsertokenreader.h +++ b/src/libs/qmuparser/qmuparsertokenreader.h @@ -23,66 +23,53 @@ #ifndef QMUPARSERTOKENREADER_H #define QMUPARSERTOKENREADER_H -#include -#include -#include -#include -#include -#include -#include -#include - #include "qmuparserdef.h" #include "qmuparsertoken.h" -/** @file - @brief This file contains the parser token reader definition. -*/ - +/** + * @file + * @brief This file contains the parser token reader definition. + */ namespace qmu { - // Forward declaration - class QmuParserBase; +// Forward declaration +class QmuParserBase; - /** @brief Token reader for the ParserBase class. +/** + * @brief Token reader for the ParserBase class. + * + */ +class QmuParserTokenReader +{ +private: + typedef QmuParserToken token_type; +public: + QmuParserTokenReader(QmuParserBase *a_pParent); + QmuParserTokenReader* Clone(QmuParserBase *a_pParent) const Q_DECL_NOEXCEPT; - */ - class QmuParserTokenReader - { - private: + void AddValIdent(identfun_type a_pCallback); + void SetVarCreator(facfun_type a_pFactory, void *pUserData); + void SetFormula(const QString &a_strFormula); + void SetArgSep(char_type cArgSep); + int GetPos() const Q_DECL_NOEXCEPT; + const QString& GetExpr() const Q_DECL_NOEXCEPT; + varmap_type& GetUsedVar(); + QChar GetArgSep() const; + void IgnoreUndefVar(bool bIgnore); + void ReInit() Q_DECL_NOEXCEPT; + token_type ReadNextToken(); +private: - typedef QmuParserToken token_type; - - public: - - QmuParserTokenReader(QmuParserBase *a_pParent); - QmuParserTokenReader* Clone(QmuParserBase *a_pParent) const Q_DECL_NOEXCEPT; - - void AddValIdent(identfun_type a_pCallback); - void SetVarCreator(facfun_type a_pFactory, void *pUserData); - void SetFormula(const QString &a_strFormula); - void SetArgSep(char_type cArgSep); - - int GetPos() const Q_DECL_NOEXCEPT; - const QString &GetExpr() const Q_DECL_NOEXCEPT; - varmap_type& GetUsedVar(); - QChar GetArgSep() const; - - void IgnoreUndefVar(bool bIgnore); - void ReInit() Q_DECL_NOEXCEPT; - token_type ReadNextToken(); - - private: - /** - * @brief Syntax codes. - * - * The syntax codes control the syntax check done during the first time parsing of - * the expression string. They are flags that indicate which tokens are allowed next - * if certain tokens are identified. - */ - enum ESynCodes - { + /** + * @brief Syntax codes. + * + * The syntax codes control the syntax check done during the first time parsing of + * the expression string. They are flags that indicate which tokens are allowed next + * if certain tokens are identified. + */ + enum ESynCodes + { noBO = 1 << 0, ///< to avoid i.e. "cos(7)(" noBC = 1 << 1, ///< to avoid i.e. "sin)" or "()" noVAL = 1 << 2, ///< to avoid i.e. "tan 2" or "sin(8)3.14" @@ -99,56 +86,54 @@ namespace qmu noELSE = 1 << 13, sfSTART_OF_LINE = noOPT | noBC | noPOSTOP | noASSIGN | noIF | noELSE | noARG_SEP, noANY = ~0 ///< All of he above flags set - }; + }; - QmuParserTokenReader(const QmuParserTokenReader &a_Reader); - QmuParserTokenReader& operator=(const QmuParserTokenReader &a_Reader) Q_DECL_NOEXCEPT; - void Assign(const QmuParserTokenReader &a_Reader) Q_DECL_NOEXCEPT; + QmuParserTokenReader(const QmuParserTokenReader &a_Reader); + QmuParserTokenReader& operator=(const QmuParserTokenReader &a_Reader) Q_DECL_NOEXCEPT; + void Assign(const QmuParserTokenReader &a_Reader) Q_DECL_NOEXCEPT; - void SetParent(QmuParserBase *a_pParent); - int ExtractToken(const QString &a_szCharSet, QString &a_strTok, int a_iPos) const Q_DECL_NOEXCEPT; - int ExtractOperatorToken(QString &a_sTok, int a_iPos) const; + void SetParent(QmuParserBase *a_pParent); + int ExtractToken(const QString &a_szCharSet, QString &a_strTok, int a_iPos) const Q_DECL_NOEXCEPT; + int ExtractOperatorToken(QString &a_sTok, int a_iPos) const; - bool IsBuiltIn(token_type &a_Tok); - bool IsArgSep(token_type &a_Tok); - bool IsEOF(token_type &a_Tok) Q_DECL_NOEXCEPT; - bool IsInfixOpTok(token_type &a_Tok); - bool IsFunTok(token_type &a_Tok); - bool IsPostOpTok(token_type &a_Tok); - bool IsOprt(token_type &a_Tok); - bool IsValTok(token_type &a_Tok); - bool IsVarTok(token_type &a_Tok); - bool IsStrVarTok(token_type &a_Tok); - bool IsUndefVarTok(token_type &a_Tok) Q_DECL_NOEXCEPT; - bool IsString(token_type &a_Tok) Q_DECL_NOEXCEPT; - void Error(EErrorCodes a_iErrc, - int a_iPos = -1, - const QString &a_sTok = QString() ) const; + bool IsBuiltIn(token_type &a_Tok); + bool IsArgSep(token_type &a_Tok); + bool IsEOF(token_type &a_Tok); + bool IsInfixOpTok(token_type &a_Tok); + bool IsFunTok(token_type &a_Tok); + bool IsPostOpTok(token_type &a_Tok); + bool IsOprt(token_type &a_Tok); + bool IsValTok(token_type &a_Tok); + bool IsVarTok(token_type &a_Tok); + bool IsStrVarTok(token_type &a_Tok); + bool IsUndefVarTok(token_type &a_Tok) Q_DECL_NOEXCEPT; + bool IsString(token_type &a_Tok); + void Q_NORETURN Error(EErrorCodes a_iErrc, int a_iPos = -1, const QString &a_sTok = QString() ) const; - token_type& SaveBeforeReturn(const token_type &tok); + token_type& SaveBeforeReturn(const token_type &tok); - QmuParserBase *m_pParser; - QString m_strFormula; - int m_iPos; - int m_iSynFlags; - bool m_bIgnoreUndefVar; + QmuParserBase *m_pParser; + QString m_strFormula; + int m_iPos; + int m_iSynFlags; + bool m_bIgnoreUndefVar; - const funmap_type *m_pFunDef; - const funmap_type *m_pPostOprtDef; - const funmap_type *m_pInfixOprtDef; - const funmap_type *m_pOprtDef; - const valmap_type *m_pConstDef; - const strmap_type *m_pStrVarDef; - varmap_type *m_pVarDef; ///< The only non const pointer to parser internals - facfun_type m_pFactory; - void *m_pFactoryData; - std::list m_vIdentFun; ///< Value token identification function - varmap_type m_UsedVar; - qreal m_fZero; ///< Dummy value of zero, referenced by undefined variables - int m_iBrackets; - token_type m_lastTok; - QChar m_cArgSep; ///< The character used for separating function arguments - }; + const funmap_type *m_pFunDef; + const funmap_type *m_pPostOprtDef; + const funmap_type *m_pInfixOprtDef; + const funmap_type *m_pOprtDef; + const valmap_type *m_pConstDef; + const strmap_type *m_pStrVarDef; + varmap_type *m_pVarDef; ///< The only non const pointer to parser internals + facfun_type m_pFactory; + void *m_pFactoryData; + std::list m_vIdentFun; ///< Value token identification function + varmap_type m_UsedVar; + qreal m_fZero; ///< Dummy value of zero, referenced by undefined variables + int m_iBrackets; ///< Keep count open brackets + token_type m_lastTok; + QChar m_cArgSep; ///< The character used for separating function arguments +}; } // namespace qmu #endif