From 0b49785255cb22656d96bf218e697d22f59d40b6 Mon Sep 17 00:00:00 2001 From: dismine Date: Mon, 28 Apr 2014 21:41:38 +0300 Subject: [PATCH] First success build after all changes. --HG-- branch : feature --- src/libs/qmuparser/qmuparser.cpp | 9 +- src/libs/qmuparser/qmuparser.h | 2 +- src/libs/qmuparser/qmuparserbase.cpp | 207 +++++++++-------- src/libs/qmuparser/qmuparserbase.h | 59 ++--- src/libs/qmuparser/qmuparserbytecode.cpp | 82 +++---- src/libs/qmuparser/qmuparsercallback.h | 2 +- src/libs/qmuparser/qmuparserdef.h | 67 ++---- src/libs/qmuparser/qmuparsererror.cpp | 78 +++---- src/libs/qmuparser/qmuparsererror.h | 39 ++-- src/libs/qmuparser/qmuparsertest.cpp | 142 ++++++------ src/libs/qmuparser/qmuparsertest.h | 49 ++-- src/libs/qmuparser/qmuparsertokenreader.cpp | 244 ++++++++++++-------- src/libs/qmuparser/qmuparsertokenreader.h | 24 +- 13 files changed, 496 insertions(+), 508 deletions(-) diff --git a/src/libs/qmuparser/qmuparser.cpp b/src/libs/qmuparser/qmuparser.cpp index 2517cd8fb..bfcf74bdf 100644 --- a/src/libs/qmuparser/qmuparser.cpp +++ b/src/libs/qmuparser/qmuparser.cpp @@ -166,11 +166,16 @@ qreal QmuParser::Max(const qreal *a_afArg, int a_iArgc) \param [out] a_fVal Pointer where the value should be stored in case one is found. \return 1 if a value was found 0 otherwise. */ - int QmuParser::IsVal(const char_type* a_szExpr, int *a_iPos, qreal *a_fVal) + int QmuParser::IsVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal) { qreal fVal(0); - stringstream_type stream(a_szExpr); +#if defined(_UNICODE) + std::wstring a_szExprStd = a_szExpr.toStdWString(); +#else + std::string a_szExprStd = a_szExpr.toStdString(); +#endif + stringstream_type stream(a_szExprStd); stream.seekg(0); // todo: check if this really is necessary stream.imbue(QmuParser::s_locale); stream >> fVal; diff --git a/src/libs/qmuparser/qmuparser.h b/src/libs/qmuparser/qmuparser.h index 2cadae6de..e0b44d06a 100644 --- a/src/libs/qmuparser/qmuparser.h +++ b/src/libs/qmuparser/qmuparser.h @@ -83,7 +83,7 @@ protected: static qreal Min(const qreal*, int); // minimum static qreal Max(const qreal*, int); // maximum - static int IsVal(const char_type* a_szExpr, int *a_iPos, qreal *a_fVal); + static int IsVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal); }; } // namespace qmu diff --git a/src/libs/qmuparser/qmuparserbase.cpp b/src/libs/qmuparser/qmuparserbase.cpp index 019994ceb..7b7d1e9c3 100644 --- a/src/libs/qmuparser/qmuparserbase.cpp +++ b/src/libs/qmuparser/qmuparserbase.cpp @@ -53,15 +53,9 @@ namespace qmu When defining custom binary operators with #AddOprt(...) make sure not to choose names conflicting with these definitions. */ - const char_type* QmuParserBase::c_DefaultOprt[] = - { - "<=", ">=", "!=", - "==", "<", ">", - "+", "-", "*", - "/", "^", "&&", - "||", "=", "(", - ")", "?", ":", 0 - }; + const QStringList QmuParserBase::c_DefaultOprt = QStringList() << "<=" << ">=" << "!=" << "==" << "<" << ">" << "+" + << "-" << "*" << "/" << "^" << "&&" << "||" << "=" + << "(" << ")" << "?" << ":"; //------------------------------------------------------------------------------ /** \brief Constructor. @@ -247,7 +241,7 @@ namespace qmu } //--------------------------------------------------------------------------- - void QmuParserBase::OnDetectVar(string_type * /*pExpr*/, int & /*nStart*/, int & /*nEnd*/) + void QmuParserBase::OnDetectVar(QString * /*pExpr*/, int & /*nStart*/, int & /*nEnd*/) {} //--------------------------------------------------------------------------- @@ -329,10 +323,10 @@ namespace qmu //--------------------------------------------------------------------------- /** \brief Add a function or operator callback to the parser. */ - void QmuParserBase::AddCallback(const string_type &a_strName, + void QmuParserBase::AddCallback(const QString &a_strName, const QmuParserCallback &a_Callback, funmap_type &a_Storage, - const char_type *a_szCharSet ) + const QString &a_szCharSet ) { if (a_Callback.GetAddr()==0) Error(ecINVALID_FUN_PTR); @@ -362,13 +356,19 @@ namespace qmu \throw ParserException if the name contains invalid charakters. */ - void QmuParserBase::CheckOprt(const string_type &a_sName, + void QmuParserBase::CheckOprt(const QString &a_sName, const QmuParserCallback &a_Callback, - const string_type &a_szCharSet) const + const QString &a_szCharSet) const { - if ( !a_sName.length() || - (a_sName.find_first_not_of(a_szCharSet)!=string_type::npos) || - (a_sName[0]>='0' && a_sName[0]<='9')) +#if defined(_UNICODE) + const std::wstring a_sNameStd = a_sName.toStdWString(); + const std::wstring a_szCharSetStd = a_szCharSet.toStdWString(); +#else + const std::string a_sNameStd = a_sName.toStdString(); + const std::string a_szCharSetStd = a_szCharSet.toStdString(); +#endif + if ( !a_sNameStd.length() || (a_sNameStd.find_first_not_of(a_szCharSetStd)!=string_type::npos) || + (a_sNameStd.at(0)>='0' && a_sNameStd.at(0)<='9')) { switch(a_Callback.GetCode()) { @@ -379,21 +379,26 @@ namespace qmu } } - //--------------------------------------------------------------------------- - /** \brief Check if a name contains invalid characters. +//--------------------------------------------------------------------------- +/** \brief Check if a name contains invalid characters. - \throw ParserException if the name contains invalid charakters. - */ - void QmuParserBase::CheckName(const string_type &a_sName, - const string_type &a_szCharSet) const - { - if ( !a_sName.length() || - (a_sName.find_first_not_of(a_szCharSet)!=string_type::npos) || - (a_sName[0]>='0' && a_sName[0]<='9')) + \throw ParserException if the name contains invalid charakters. +*/ +void QmuParserBase::CheckName(const QString &a_sName, const QString &a_szCharSet) const +{ + #if defined(_UNICODE) + std::wstring a_sNameStd = a_sName.toStdWString(); + std::wstring a_szCharSetStd = a_szCharSet.toStdWString(); + #else + std::string a_sNameStd = a_sName.toStdString(); + std::string a_szCharSetStd = a_szCharSet.toStdString(); + #endif + if ( !a_sNameStd.length() || (a_sNameStd.find_first_not_of(a_szCharSetStd)!=string_type::npos) || + (a_sNameStd[0]>='0' && a_sNameStd[0]<='9')) { - Error(ecINVALID_NAME); + Error(ecINVALID_NAME); } - } +} //--------------------------------------------------------------------------- /** \brief Set the formula. @@ -403,7 +408,7 @@ namespace qmu Triggers first time calculation thus the creation of the bytecode and scanning of used variables. */ -void QmuParserBase::SetExpr(const string_type &a_sExpr) +void QmuParserBase::SetExpr(const QString &a_sExpr) { // Check locale compatibility std::locale loc; @@ -415,9 +420,9 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) // 20060222: Bugfix for Borland-Kylix: // adding a space to the expression will keep Borlands KYLIX from going wild // when calling tellg on a stringstream created from the expression after - // reading a value at the end of an expression. (mu::Parser::IsVal function) + // reading a value at the end of an expression. (qmu::QmuParser::IsVal function) // (tellg returns -1 otherwise causing the parser to ignore the value) - string_type sBuf(a_sExpr + " " ); + QString sBuf(a_sExpr + " " ); m_pTokenReader->SetFormula(sBuf); ReInit(); } @@ -426,9 +431,9 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) /** \brief Get the default symbols used for the built in operators. \sa c_DefaultOprt */ - const char_type** QmuParserBase::GetOprtDef() const + const QStringList &QmuParserBase::GetOprtDef() const { - return (const char_type **)(&c_DefaultOprt[0]); + return c_DefaultOprt; } //--------------------------------------------------------------------------- @@ -458,53 +463,41 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) m_sInfixOprtChars = a_szCharset; } - //--------------------------------------------------------------------------- - /** \brief Virtual function that defines the characters allowed in name identifiers. - \sa #ValidOprtChars, #ValidPrefixOprtChars - */ - const char_type* QmuParserBase::ValidNameChars() const - { +//--------------------------------------------------------------------------- +/** \brief Virtual function that defines the characters allowed in name identifiers. + \sa #ValidOprtChars, #ValidPrefixOprtChars +*/ +const QString& QmuParserBase::ValidNameChars() const +{ assert(m_sNameChars.size()); - #if defined(_UNICODE) - return m_sNameChars.toStdWString().c_str(); - #else - return m_sNameChars.toStdString().c_str(); - #endif - } + return m_sNameChars; +} //--------------------------------------------------------------------------- /** \brief Virtual function that defines the characters allowed in operator definitions. \sa #ValidNameChars, #ValidPrefixOprtChars */ - const char_type* QmuParserBase::ValidOprtChars() const + const QString &QmuParserBase::ValidOprtChars() const { assert(m_sOprtChars.size()); - #if defined(_UNICODE) - return m_sOprtChars.toStdWString().c_str(); - #else - return m_sOprtChars.toStdString().c_str(); - #endif + return m_sOprtChars; } //--------------------------------------------------------------------------- /** \brief Virtual function that defines the characters allowed in infix operator definitions. \sa #ValidNameChars, #ValidOprtChars */ - const char_type* QmuParserBase::ValidInfixOprtChars() const + const QString &QmuParserBase::ValidInfixOprtChars() const { assert(m_sInfixOprtChars.size()); - #if defined(_UNICODE) - return m_sInfixOprtChars.toStdWString().c_str(); - #else - return m_sInfixOprtChars.toStdString().c_str(); - #endif + return m_sInfixOprtChars; } //--------------------------------------------------------------------------- /** \brief Add a user defined operator. \post Will reset the Parser to string parsing mode. */ - void QmuParserBase::DefinePostfixOprt(const string_type &a_sName, + void QmuParserBase::DefinePostfixOprt(const QString &a_sName, fun_type1 a_pFun, bool a_bAllowOpt) { @@ -536,7 +529,7 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) \param [in] a_bAllowOpt True if operator is volatile (default=false) \sa EPrec */ - void QmuParserBase::DefineInfixOprt(const string_type &a_sName, + void QmuParserBase::DefineInfixOprt(const QString &a_sName, fun_type1 a_pFun, int a_iPrec, bool a_bAllowOpt) @@ -558,7 +551,7 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) Adds a new Binary operator the the parser instance. */ - void QmuParserBase::DefineOprt( const string_type &a_sName, + void QmuParserBase::DefineOprt( const QString &a_sName, fun_type2 a_pFun, unsigned a_iPrec, EOprtAssociativity a_eAssociativity, @@ -566,8 +559,12 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) { // Check for conflicts with built in operator names for (int i=0; m_bBuiltInOp && iGetExpr(); } @@ -1129,9 +1132,9 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) switch(pTok->Fun.argc) // switch according to argument count { - case 0: Stack[sidx] = (*(strfun_type1)pTok->Fun.ptr)(m_vStringBuf[iIdxStack].c_str()); continue; - case 1: Stack[sidx] = (*(strfun_type2)pTok->Fun.ptr)(m_vStringBuf[iIdxStack].c_str(), Stack[sidx]); continue; - case 2: Stack[sidx] = (*(strfun_type3)pTok->Fun.ptr)(m_vStringBuf[iIdxStack].c_str(), Stack[sidx], Stack[sidx+1]); continue; + case 0: Stack[sidx] = (*(strfun_type1)pTok->Fun.ptr)(m_vStringBuf.at(iIdxStack)); continue; + case 1: Stack[sidx] = (*(strfun_type2)pTok->Fun.ptr)(m_vStringBuf.at(iIdxStack), Stack[sidx]); continue; + case 2: Stack[sidx] = (*(strfun_type3)pTok->Fun.ptr)(m_vStringBuf.at(iIdxStack), Stack[sidx], Stack[sidx+1]); continue; } continue; @@ -1448,7 +1451,7 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) \param a_strTok [in] The token string representation associated with the error. \throw ParserException always throws thats the only purpose of this function. */ - void QmuParserBase::Error(EErrorCodes a_iErrc, int a_iPos, const string_type &a_sTok) const + void 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); } @@ -1471,7 +1474,7 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) Removes a variable if it exists. If the Variable does not exist nothing will be done. */ - void QmuParserBase::RemoveVar(const string_type &a_strVarName) + void QmuParserBase::RemoveVar(const QString &a_strVarName) { varmap_type::iterator item = m_VarDef.find(a_strVarName); if (item!=m_VarDef.end()) @@ -1592,7 +1595,7 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) //------------------------------------------------------------------------------ /** \brief Get the argument separator character. */ - char_type QmuParserBase::GetArgSep() const + QChar QmuParserBase::GetArgSep() const { return m_pTokenReader->GetArgSep(); } @@ -1617,22 +1620,22 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) QStack stOprt(a_stOprt), stVal(a_stVal); - qmu::console() << "\nValue stack:\n"; + qDebug() << "\nValue stack:\n"; while ( !stVal.empty() ) { token_type val = stVal.pop(); if (val.GetType()==tpSTR) - qmu::console() << " \"" << val.GetAsString() << "\" "; + qDebug() << " \"" << val.GetAsString() << "\" "; else - qmu::console() << " " << val.GetVal() << " "; + qDebug() << " " << val.GetVal() << " "; } - qmu::console() << "\nOperator stack:\n"; + qDebug() << "\nOperator stack:\n"; while ( !stOprt.empty() ) { if (stOprt.top().GetCode()<=cmASSIGN) { - qmu::console() << "OPRT_INTRNL \"" + qDebug() << "OPRT_INTRNL \"" << QmuParserBase::c_DefaultOprt[stOprt.top().GetCode()] << "\" \n"; } @@ -1640,35 +1643,35 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) { switch(stOprt.top().GetCode()) { - case cmVAR: qmu::console() << "VAR\n"; break; - case cmVAL: qmu::console() << "VAL\n"; break; - case cmFUNC: qmu::console() << "FUNC \"" + case cmVAR: qDebug() << "VAR\n"; break; + case cmVAL: qDebug() << "VAL\n"; break; + case cmFUNC: qDebug() << "FUNC \"" << stOprt.top().GetAsString() << "\"\n"; break; - case cmFUNC_BULK: qmu::console() << "FUNC_BULK \"" + case cmFUNC_BULK: qDebug() << "FUNC_BULK \"" << stOprt.top().GetAsString() << "\"\n"; break; - case cmOPRT_INFIX: qmu::console() << "OPRT_INFIX \"" + case cmOPRT_INFIX: qDebug() << "OPRT_INFIX \"" << stOprt.top().GetAsString() << "\"\n"; break; - case cmOPRT_BIN: qmu::console() << "OPRT_BIN \"" + case cmOPRT_BIN: qDebug() << "OPRT_BIN \"" << stOprt.top().GetAsString() << "\"\n"; break; - case cmFUNC_STR: qmu::console() << "FUNC_STR\n"; break; - case cmEND: qmu::console() << "END\n"; break; - case cmUNKNOWN: qmu::console() << "UNKNOWN\n"; break; - case cmBO: qmu::console() << "BRACKET \"(\"\n"; break; - case cmBC: qmu::console() << "BRACKET \")\"\n"; break; - case cmIF: qmu::console() << "IF\n"; break; - case cmELSE: qmu::console() << "ELSE\n"; break; - case cmENDIF: qmu::console() << "ENDIF\n"; break; - default: qmu::console() << stOprt.top().GetCode() << " "; break; + case cmFUNC_STR: qDebug() << "FUNC_STR\n"; break; + case cmEND: qDebug() << "END\n"; break; + case cmUNKNOWN: qDebug() << "UNKNOWN\n"; break; + case cmBO: qDebug() << "BRACKET \"(\"\n"; break; + case cmBC: qDebug() << "BRACKET \")\"\n"; break; + case cmIF: qDebug() << "IF\n"; break; + case cmELSE: qDebug() << "ELSE\n"; break; + case cmENDIF: qDebug() << "ENDIF\n"; break; + default: qDebug() << stOprt.top().GetCode() << " "; break; } } stOprt.pop(); } - qmu::console() << dec << endl; + qDebug() << dec; } //------------------------------------------------------------------------------ diff --git a/src/libs/qmuparser/qmuparserbase.h b/src/libs/qmuparser/qmuparserbase.h index 73e7b1c16..ab1bbc2b8 100644 --- a/src/libs/qmuparser/qmuparserbase.h +++ b/src/libs/qmuparser/qmuparserbase.h @@ -32,6 +32,7 @@ #include #include #include +#include //--- Parser includes -------------------------------------------------------------------------- #include "qmuparserdef.h" @@ -75,13 +76,13 @@ private: typedef QVector valbuf_type; /** \brief Type for a vector of strings. */ - typedef QVector stringbuf_type; + typedef QVector stringbuf_type; /** \brief Typedef for the token reader. */ typedef QmuParserTokenReader token_reader_type; /** \brief Type used for parser tokens. */ - typedef QmuParserToken token_type; + typedef QmuParserToken token_type; /** \brief Maximum number of threads spawned by OpenMP when using the bulk mode. */ static const int s_MaxNumOpenMPThreads = 4; @@ -108,7 +109,7 @@ private: int GetNumResults() const; - void SetExpr(const string_type &a_sExpr); + void SetExpr(const QString &a_sExpr); void SetVarFactory(facfun_type a_pFactory, void *pUserData = NULL); void SetDecSep(char_type cDecSep); @@ -128,21 +129,21 @@ private: \param a_bAllowOpt A flag indicating this function may be optimized */ template - void DefineFun(const string_type &a_strName, T a_pFun, bool a_bAllowOpt = true) + void DefineFun(const QString &a_strName, T a_pFun, bool a_bAllowOpt = true) { AddCallback( a_strName, QmuParserCallback(a_pFun, a_bAllowOpt), m_FunDef, ValidNameChars() ); } - void DefineOprt(const string_type &a_strName, - fun_type2 a_pFun, - unsigned a_iPri=0, + void DefineOprt(const QString &a_strName, + fun_type2 a_pFun, + unsigned a_iPri=0, EOprtAssociativity a_eAssociativity = oaLEFT, bool a_bAllowOpt = false); - void DefineConst(const string_type &a_sName, qreal a_fVal); - void DefineStrConst(const string_type &a_sName, const string_type &a_strVal); - void DefineVar(const string_type &a_sName, qreal *a_fVar); - void DefinePostfixOprt(const string_type &a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt=true); - void DefineInfixOprt(const string_type &a_strName, fun_type1 a_pOprt, int a_iPrec=prINFIX, bool a_bAllowOpt=true); + void DefineConst(const QString &a_sName, qreal a_fVal); + void DefineStrConst(const QString &a_sName, const QString &a_strVal); + void DefineVar(const QString &a_sName, qreal *a_fVar); + void DefinePostfixOprt(const QString &a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt=true); + void DefineInfixOprt(const QString &a_strName, fun_type1 a_pOprt, int a_iPrec=prINFIX, bool a_bAllowOpt=true); // Clear user defined variables, constants or functions void ClearVar(); @@ -152,29 +153,29 @@ private: void ClearPostfixOprt(); void ClearOprt(); - void RemoveVar(const string_type &a_strVarName); + void RemoveVar(const QString &a_strVarName); const varmap_type& GetUsedVar() const; const varmap_type& GetVar() const; const valmap_type& GetConst() const; - const string_type& GetExpr() const; + const QString &GetExpr() const; const funmap_type& GetFunDef() const; string_type GetVersion(EParserVersionInfo eInfo = pviFULL) const; - const char_type ** GetOprtDef() const; + const QStringList &GetOprtDef() const; void DefineNameChars(const QString &a_szCharset); void DefineOprtChars(const QString &a_szCharset); void DefineInfixOprtChars(const QString &a_szCharset); - const char_type* ValidNameChars() const; - const char_type* ValidOprtChars() const; - const char_type* ValidInfixOprtChars() const; + const QString& ValidNameChars() const; + const QString &ValidOprtChars() const; + const QString &ValidInfixOprtChars() const; void SetArgSep(char_type cArgSep); - char_type GetArgSep() const; + QChar GetArgSep() const; - void Error(EErrorCodes a_iErrc, - int a_iPos = (int)qmu::string_type::npos, - const string_type &a_strTok = string_type() ) const; + void Error(EErrorCodes a_iErrc, + int a_iPos = -1, + const QString &a_strTok = QString() ) const; protected: @@ -185,9 +186,9 @@ private: virtual void InitConst() = 0; virtual void InitOprt() = 0; - virtual void OnDetectVar(string_type *pExpr, int &nStart, int &nEnd); + virtual void OnDetectVar(QString *pExpr, int &nStart, int &nEnd); - static const char_type *c_DefaultOprt[]; + static const QStringList c_DefaultOprt; static std::locale s_locale; ///< The locale used by the parser static bool g_DbgDumpCmdCode; static bool g_DbgDumpStack; @@ -235,10 +236,10 @@ private: void InitTokenReader(); void ReInit() const; - void AddCallback( const string_type &a_strName, + void AddCallback(const QString &a_strName, const QmuParserCallback &a_Callback, funmap_type &a_Storage, - const char_type *a_szCharSet ); + const QString &a_szCharSet ); void ApplyRemainingOprt(QStack &a_stOpt, QStack &a_stVal) const; void ApplyBinOprt(QStack &a_stOpt, QStack &a_stVal) const; @@ -257,10 +258,10 @@ private: qreal ParseCmdCode() const; qreal ParseCmdCodeBulk(int nOffset, int nThreadID) const; - void CheckName(const string_type &a_strName, const string_type &a_CharSet) const; - void CheckOprt(const string_type &a_sName, + void CheckName(const QString &a_strName, const QString &a_CharSet) const; + void CheckOprt(const QString &a_sName, const QmuParserCallback &a_Callback, - const string_type &a_szCharSet) const; + const QString &a_szCharSet) const; void StackDump(const QStack &a_stVal, const QStack &a_stOprt) const; diff --git a/src/libs/qmuparser/qmuparserbytecode.cpp b/src/libs/qmuparser/qmuparserbytecode.cpp index 910ae6375..5665417f3 100644 --- a/src/libs/qmuparser/qmuparserbytecode.cpp +++ b/src/libs/qmuparser/qmuparserbytecode.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include "qmuparserdef.h" #include "qmuparsererror.h" @@ -492,89 +493,76 @@ namespace qmu { if (!m_vRPN.size()) { - qmu::console() << "No bytecode available\n"; + qDebug() << "No bytecode available\n"; return; } - qmu::console() << "Number of RPN tokens:" << (int)m_vRPN.size() << "\n"; + qDebug() << "Number of RPN tokens:" << m_vRPN.size() << "\n"; for (std::size_t i=0; i funmap_type; +typedef std::map funmap_type; } // namespace qmu diff --git a/src/libs/qmuparser/qmuparserdef.h b/src/libs/qmuparser/qmuparserdef.h index 2ad34d556..0ecb3ac4a 100644 --- a/src/libs/qmuparser/qmuparserdef.h +++ b/src/libs/qmuparser/qmuparserdef.h @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include "qmuparserfixes.h" @@ -49,54 +51,15 @@ //#define MUP_USE_OPENMP #if defined(_UNICODE) - /** \brief Definition of the basic parser string type. */ - #define MUP_STRING_TYPE std::wstring - + /** \brief Definition of the basic parser string type. */ + #define QMUP_STRING_TYPE std::wstring #else - - /** \brief Definition of the basic parser string type. */ - #define MUP_STRING_TYPE std::string + /** \brief Definition of the basic parser string type. */ + #define QMUP_STRING_TYPE std::string #endif namespace qmu { -#if defined(_UNICODE) - - //------------------------------------------------------------------------------ - /** \brief Encapsulate wcout. */ - inline std::wostream& console() - { - return std::wcout; - } - - /** \brief Encapsulate cin. */ - inline std::wistream& console_in() - { - return std::wcin; - } - -#else - - /** \brief Encapsulate cout. - - Used for supporting UNICODE more easily. - */ - inline std::ostream& console() - { - return std::cout; - } - - /** \brief Encapsulate cin. - - Used for supporting UNICODE more easily. - */ - inline std::istream& console_in() - { - return std::cin; - } - -#endif - //------------------------------------------------------------------------------ /** \brief Bytecode values. @@ -200,7 +163,7 @@ namespace qmu Depends on wether UNICODE is used or not. */ - typedef MUP_STRING_TYPE string_type; + typedef QMUP_STRING_TYPE string_type; /** \brief The character type used by the parser. @@ -216,13 +179,13 @@ namespace qmu // Data container types /** \brief Type used for storing variables. */ - typedef std::map varmap_type; + typedef std::map varmap_type; /** \brief Type used for storing constants. */ - typedef std::map valmap_type; + typedef std::map valmap_type; /** \brief Type for assigning a string name to an index in the internal string table. */ - typedef std::map strmap_type; + typedef std::map strmap_type; // Parser callbacks @@ -299,19 +262,19 @@ namespace qmu typedef qreal (*multfun_type)(const qreal*, int); /** \brief Callback type used for functions taking a string as an argument. */ - typedef qreal (*strfun_type1)(const char_type*); + typedef qreal (*strfun_type1)(const QString &); /** \brief Callback type used for functions taking a string and a value as arguments. */ - typedef qreal (*strfun_type2)(const char_type*, qreal); + typedef qreal (*strfun_type2)(const QString &, qreal); /** \brief Callback type used for functions taking a string and two values as arguments. */ - typedef qreal (*strfun_type3)(const char_type*, qreal, qreal); + typedef qreal (*strfun_type3)(const QString &, qreal, qreal); /** \brief Callback used for functions that identify values in a string. */ - typedef int (*identfun_type)(const char_type *sExpr, int *nPos, qreal *fVal); + typedef int (*identfun_type)(const QString &sExpr, int *nPos, qreal *fVal); /** \brief Callback used for variable creation factory functions. */ - typedef qreal* (*facfun_type)(const char_type*, void*); + typedef qreal* (*facfun_type)(const QString &, void*); } // end of namespace #endif diff --git a/src/libs/qmuparser/qmuparsererror.cpp b/src/libs/qmuparser/qmuparsererror.cpp index c909f57c5..c073b68ea 100644 --- a/src/libs/qmuparser/qmuparsererror.cpp +++ b/src/libs/qmuparser/qmuparsererror.cpp @@ -22,6 +22,8 @@ #include "qmuparsererror.h" +#include + namespace qmu { @@ -34,9 +36,9 @@ namespace qmu } //------------------------------------------------------------------------------ - string_type QmuParserErrorMsg::operator[](unsigned a_iIdx) const + QString QmuParserErrorMsg::operator[](unsigned a_iIdx) const { - return (a_iIdx m_vErrMsg; ///< A vector with the predefined error messages + QVector m_vErrMsg; ///< A vector with the predefined error messages static const self_type m_Instance; ///< The instance pointer }; @@ -124,41 +124,34 @@ class QmuParserError private: /** \brief Replace all ocuurences of a substring with another string. */ - void ReplaceSubString( string_type &strSource, - const string_type &strFind, - const string_type &strReplaceWith); + void ReplaceSubString(QString &strSource, + const QString &strFind, + const QString &strReplaceWith); void Reset(); public: QmuParserError(); explicit QmuParserError(EErrorCodes a_iErrc); - explicit QmuParserError(const string_type &sMsg); - QmuParserError( EErrorCodes a_iErrc, - const string_type &sTok, - const string_type &sFormula = string_type(), - int a_iPos = -1); - QmuParserError( EErrorCodes a_iErrc, - int a_iPos, - const string_type &sTok); - QmuParserError( const char_type *a_szMsg, - int a_iPos = -1, - const string_type &sTok = string_type()); + explicit QmuParserError(const QString &sMsg); + QmuParserError( EErrorCodes a_iErrc, const QString &sTok, const QString &sFormula = QString(), int a_iPos = -1); + QmuParserError(EErrorCodes a_iErrc, int a_iPos, const QString &sTok); + QmuParserError(const QString &a_szMsg, int a_iPos, const QString &sTok = QString()); QmuParserError(const QmuParserError &a_Obj); QmuParserError& operator=(const QmuParserError &a_Obj); ~QmuParserError(); - void SetFormula(const string_type &a_strFormula); - const string_type& GetExpr() const; - const string_type& GetMsg() const; + void SetFormula(const QString &a_strFormula); + const QString &GetExpr() const; + const QString &GetMsg() const; std::size_t GetPos() const; - const string_type& GetToken() const; + const QString &GetToken() const; EErrorCodes GetCode() const; private: - string_type m_strMsg; ///< The message string - string_type m_strFormula; ///< Formula string - string_type m_strTok; ///< Token related with the error + QString m_strMsg; ///< The message string + QString m_strFormula; ///< Formula string + QString m_strTok; ///< Token related with the error int m_iPos; ///< Formula position related to the error EErrorCodes m_iErrc; ///< Error code const QmuParserErrorMsg &m_ErrMsg; diff --git a/src/libs/qmuparser/qmuparsertest.cpp b/src/libs/qmuparser/qmuparsertest.cpp index 070b9d144..d4d22919a 100644 --- a/src/libs/qmuparser/qmuparsertest.cpp +++ b/src/libs/qmuparser/qmuparsertest.cpp @@ -22,6 +22,7 @@ #include "qmuparsertest.h" #include +#include #include #include @@ -60,32 +61,37 @@ namespace qmu } //--------------------------------------------------------------------------------------------- - int QmuParserTester::IsHexVal(const char_type *a_szExpr, int *a_iPos, qreal *a_fVal) + 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') ) return 0; unsigned iVal(0); + bool ok = false; + iVal = a_szExpr.toUInt(&ok, 16); - // New code based on streams for UNICODE compliance: - stringstream_type::pos_type nPos(0); - stringstream_type ss(a_szExpr + 2); - ss >> std::hex >> iVal; - nPos = ss.tellg(); + if(ok) + { + int nPos = a_szExpr.indexOf(QString().setNum(iVal, 16)); + if(nPos == 0) + return 1; - if (nPos==(stringstream_type::pos_type)0) + *a_iPos += (int)(2 + nPos); + *a_fVal = (qreal)iVal; return 1; + } + else + { + return 0; + } - *a_iPos += (int)(2 + nPos); - *a_fVal = (qreal)iVal; - return 1; } //--------------------------------------------------------------------------------------------- int QmuParserTester::TestInterface() { int iStat = 0; - qmu::console() << "testing member functions..."; + qDebug() << "testing member functions..."; // Test RemoveVar qreal afVal[3] = {1,2,3}; @@ -116,9 +122,9 @@ namespace qmu } if (iStat==0) - qmu::console() << "passed" << endl; + qDebug() << "passed"; else - qmu::console() << "\n failed with " << iStat << " errors" << endl; + qDebug() << "\n failed with " << iStat << " errors"; return iStat; } @@ -127,7 +133,7 @@ namespace qmu int QmuParserTester::TestStrArg() { int iStat = 0; - qmu::console() << "testing string arguments..."; + qDebug() << "testing string arguments..."; iStat += EqnTest("valueof(\"\")", 123, true); // empty string arguments caused a crash iStat += EqnTest("valueof(\"aaa\")+valueof(\"bbb\") ", 246, true); @@ -141,9 +147,9 @@ namespace qmu iStat += EqnTest("strfun3(\"99\",1,2)", 102, true); if (iStat==0) - qmu::console() << "passed" << endl; + qDebug() << "passed"; else - qmu::console() << "\n failed with " << iStat << " errors" << endl; + qDebug() << "\n failed with " << iStat << " errors"; return iStat; } @@ -152,7 +158,7 @@ namespace qmu int QmuParserTester::TestBinOprt() { int iStat = 0; - qmu::console() << "testing binary operators..."; + qDebug() << "testing binary operators..."; // built in operators // xor operator @@ -212,9 +218,9 @@ namespace qmu iStat += EqnTest("3+4*2/(1-5)^2^3", 3.0001220703125, true); if (iStat==0) - qmu::console() << "passed" << endl; + qDebug() << "passed"; else - qmu::console() << "\n failed with " << iStat << " errors" << endl; + qDebug() << "\n failed with " << iStat << " errors"; return iStat; } @@ -226,7 +232,7 @@ namespace qmu int iStat= 0, iErr = 0; - qmu::console() << "testing name restriction enforcement..."; + qDebug() << "testing name restriction enforcement..."; QmuParser p; @@ -321,9 +327,9 @@ namespace qmu #undef PARSER_THROWCHECK if (iStat==0) - qmu::console() << "passed" << endl; + qDebug() << "passed"; else - qmu::console() << "\n failed with " << iStat << " errors" << endl; + qDebug() << "\n failed with " << iStat << " errors"; return iStat; } @@ -332,7 +338,7 @@ namespace qmu int QmuParserTester::TestSyntax() { int iStat = 0; - qmu::console() << "testing syntax engine..."; + qDebug() << "testing syntax engine..."; iStat += ThrowTest("1,", ecUNEXPECTED_EOF); // incomplete hex definition iStat += ThrowTest("a,", ecUNEXPECTED_EOF); // incomplete hex definition @@ -370,9 +376,9 @@ namespace qmu iStat += EqnTest("sin()", 0, false); // unexpected closing bracket if (iStat==0) - qmu::console() << "passed" << endl; + qDebug() << "passed"; else - qmu::console() << "\n failed with " << iStat << " errors" << endl; + qDebug() << "\n failed with " << iStat << " errors"; return iStat; } @@ -381,7 +387,7 @@ namespace qmu int QmuParserTester::TestVarConst() { int iStat = 0; - qmu::console() << "testing variable/constant detection..."; + qDebug() << "testing variable/constant detection..."; // Test if the result changes when a variable changes iStat += EqnTestWithVarChange( "a", 1, 1, 2, 2 ); @@ -479,9 +485,9 @@ namespace qmu } if (iStat==0) - qmu::console() << "passed" << endl; + qDebug() << "passed"; else - qmu::console() << "\n failed with " << iStat << " errors" << endl; + qDebug() << "\n failed with " << iStat << " errors"; return iStat; } @@ -490,7 +496,7 @@ namespace qmu int QmuParserTester::TestMultiArg() { int iStat = 0; - qmu::console() << "testing multiarg functions..."; + qDebug() << "testing multiarg functions..."; // Compound expressions iStat += EqnTest( "1,2,3", 3, true); @@ -573,9 +579,9 @@ namespace qmu iStat += EqnTest( "sum(,1,2)", 0, false); if (iStat==0) - qmu::console() << "passed" << endl; + qDebug() << "passed"; else - qmu::console() << "\n failed with " << iStat << " errors" << endl; + qDebug() << "\n failed with " << iStat << " errors"; return iStat; } @@ -585,7 +591,7 @@ namespace qmu int QmuParserTester::TestInfixOprt() { int iStat(0); - qmu::console() << "testing infix operators..."; + qDebug() << "testing infix operators..."; iStat += EqnTest( "-1", -1, true); iStat += EqnTest( "-(-1)", 1, true); @@ -638,9 +644,9 @@ namespace qmu iStat += EqnTest( "~~ 123", 123+2, true); if (iStat==0) - qmu::console() << "passed" << endl; + qDebug() << "passed"; else - qmu::console() << "\n failed with " << iStat << " errors" << endl; + qDebug() << "\n failed with " << iStat << " errors"; return iStat; } @@ -650,7 +656,7 @@ namespace qmu int QmuParserTester::TestPostFix() { int iStat = 0; - qmu::console() << "testing postfix operators..."; + qDebug() << "testing postfix operators..."; // application iStat += EqnTest( "3{m}+5", 5.003, true); @@ -690,9 +696,9 @@ namespace qmu iStat += ThrowTest( "multi*1.0", ecUNASSIGNABLE_TOKEN); if (iStat==0) - qmu::console() << "passed" << endl; + qDebug() << "passed"; else - qmu::console() << "\n failed with " << iStat << " errors" << endl; + qDebug() << "\n failed with " << iStat << " errors"; return iStat; } @@ -701,7 +707,7 @@ namespace qmu int QmuParserTester::TestExpression() { int iStat = 0; - qmu::console() << "testing expression samples..."; + qDebug() << "testing expression samples..."; qreal b = 2; @@ -770,9 +776,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); if (iStat==0) - qmu::console() << "passed" << endl; + qDebug() << "passed"; else - qmu::console() << "\n failed with " << iStat << " errors" << endl; + qDebug() << "\n failed with " << iStat << " errors"; return iStat; } @@ -783,7 +789,7 @@ namespace qmu int QmuParserTester::TestIfThenElse() { int iStat = 0; - qmu::console() << "testing if-then-else operator..."; + qDebug() << "testing if-then-else operator..."; // Test error detection iStat += ThrowTest(":3", ecUNEXPECTED_CONDITIONAL); @@ -878,9 +884,9 @@ namespace qmu iStat += EqnTest("a=0?5:b=1?3:4, b", 3, true); if (iStat==0) - qmu::console() << "passed" << endl; + qDebug() << "passed"; else - qmu::console() << "\n failed with " << iStat << " errors" << endl; + qDebug() << "\n failed with " << iStat << " errors"; return iStat; } @@ -889,7 +895,7 @@ namespace qmu int QmuParserTester::TestException() { int iStat = 0; - qmu::console() << "testing error codes..."; + qDebug() << "testing error codes..."; iStat += ThrowTest("3+", ecUNEXPECTED_EOF); iStat += ThrowTest("3+)", ecUNEXPECTED_PARENS); @@ -972,9 +978,9 @@ namespace qmu iStat += ThrowTest( "a=\"tttt\"", ecOPRT_TYPE_CONFLICT); if (iStat==0) - qmu::console() << "passed" << endl; + qDebug() << "passed" ; else - qmu::console() << "\n failed with " << iStat << " errors" << endl; + qDebug() << "\n failed with " << iStat << " errors" ; return iStat; } @@ -997,37 +1003,37 @@ namespace qmu } catch(QmuParser::exception_type &e) { - qmu::console() << "\n" << e.GetMsg() << endl; - qmu::console() << e.GetToken() << endl; + qDebug() << "\n" << e.GetMsg() ; + qDebug() << e.GetToken() ; Abort(); } catch(std::exception &e) { - qmu::console() << e.what() << endl; + qDebug() << e.what() ; Abort(); } catch(...) { - qmu::console() << "Internal error"; + qDebug() << "Internal error"; Abort(); } if (iStat==0) { - qmu::console() << "Test passed (" << QmuParserTester::c_iCount << " expressions)" << endl; + qDebug() << "Test passed (" << QmuParserTester::c_iCount << " expressions)" ; } else { - qmu::console() << "Test failed with " << iStat + qDebug() << "Test failed with " << iStat << " errors (" << QmuParserTester::c_iCount - << " expressions)" << endl; + << " expressions)" ; } QmuParserTester::c_iCount = 0; } //--------------------------------------------------------------------------- - int QmuParserTester::ThrowTest(const string_type &a_str, int a_iErrc, bool a_bFail) + int QmuParserTester::ThrowTest(const QString &a_str, int a_iErrc, bool a_bFail) { QmuParserTester::c_iCount++; @@ -1054,7 +1060,7 @@ namespace qmu // output the formula in case of an failed test if (a_bFail==false || (a_bFail==true && a_iErrc!=e.GetCode()) ) { - qmu::console() << "\n " + qDebug() << "\n " << "Expression: " << a_str << " Code:" << e.GetCode() << "(" << e.GetMsg() << ")" << " Expected:" << a_iErrc; @@ -1067,7 +1073,7 @@ namespace qmu bool bRet((a_bFail==false) ? 0 : 1); if (bRet==1) { - qmu::console() << "\n " + qDebug() << "\n " << "Expression: " << a_str << " did evaluate; Expected error:" << a_iErrc; } @@ -1080,7 +1086,7 @@ namespace qmu \return 1 in case of a failure, 0 otherwise. */ - int QmuParserTester::EqnTestWithVarChange(const string_type &a_str, + int QmuParserTester::EqnTestWithVarChange(const QString &a_str, double a_fVar1, double a_fRes1, double a_fVar2, @@ -1112,17 +1118,17 @@ namespace qmu } catch(QmuParser::exception_type &e) { - qmu::console() << "\n fail: " << a_str.c_str() << " (" << e.GetMsg() << ")"; + qDebug() << "\n fail: " << a_str << " (" << e.GetMsg() << ")"; return 1; } catch(std::exception &e) { - qmu::console() << "\n fail: " << a_str.c_str() << " (" << e.what() << ")"; + qDebug() << "\n fail: " << a_str << " (" << e.what() << ")"; return 1; // always return a failure since this exception is not expected } catch(...) { - qmu::console() << "\n fail: " << a_str.c_str() << " (unexpected exception)"; + qDebug() << "\n fail: " << a_str << " (unexpected exception)"; return 1; // exceptions other than ParserException are not allowed } @@ -1134,7 +1140,7 @@ namespace qmu \return 1 in case of a failure, 0 otherwise. */ - int QmuParserTester::EqnTest(const string_type &a_str, double a_fRes, bool a_fPass) + int QmuParserTester::EqnTest(const QString &a_str, double a_fRes, bool a_fPass) { QmuParserTester::c_iCount++; int iRet(0); @@ -1253,7 +1259,7 @@ namespace qmu } catch(std::exception &e) { - qmu::console() << "\n " << e.what() << "\n"; + qDebug() << "\n " << e.what() << "\n"; } // limited floating point accuracy requires the following test @@ -1274,7 +1280,7 @@ namespace qmu if (iRet==1) { - qmu::console() << "\n fail: " << a_str.c_str() + qDebug() << "\n fail: " << a_str << " (incorrect result; expected: " << a_fRes << " ;calculated: " << fVal[0] << "," << fVal[1] << "," @@ -1288,20 +1294,20 @@ namespace qmu if (a_fPass) { if (fVal[0]!=fVal[2] && fVal[0]!=-999 && fVal[1]!=-998) - qmu::console() << "\n fail: " << a_str.c_str() << " (copy construction)"; + qDebug() << "\n fail: " << a_str << " (copy construction)"; else - qmu::console() << "\n fail: " << a_str.c_str() << " (" << e.GetMsg() << ")"; + qDebug() << "\n fail: " << a_str << " (" << e.GetMsg() << ")"; return 1; } } catch(std::exception &e) { - qmu::console() << "\n fail: " << a_str.c_str() << " (" << e.what() << ")"; + qDebug() << "\n fail: " << a_str << " (" << e.what() << ")"; return 1; // always return a failure since this exception is not expected } catch(...) { - qmu::console() << "\n fail: " << a_str.c_str() << " (unexpected exception)"; + qDebug() << "\n fail: " << a_str << " (unexpected exception)"; return 1; // exceptions other than ParserException are not allowed } @@ -1312,7 +1318,7 @@ namespace qmu /** \brief Internal error in test class Test is going to be aborted. */ void QmuParserTester::Abort() const { - qmu::console() << "Test failed (internal error in test class)" << endl; + qDebug() << "Test failed (internal error in test class)" ; while (!getchar()); exit(-1); } diff --git a/src/libs/qmuparser/qmuparsertest.h b/src/libs/qmuparser/qmuparsertest.h index 4baa0eed0..b92338b3f 100644 --- a/src/libs/qmuparser/qmuparsertest.h +++ b/src/libs/qmuparser/qmuparsertest.h @@ -27,6 +27,7 @@ #include #include // for accumulate #include "qmuparser.h" +#include /** \file \brief This file contains the parser test class. @@ -48,14 +49,14 @@ namespace qmu static int c_iCount; // Multiarg callbacks - static qreal f1of1(qreal v) { return v;}; + static qreal f1of1(qreal v) { return v;} - static qreal f1of2(qreal v, qreal ) {return v;}; - static qreal f2of2(qreal , qreal v) {return v;}; + static qreal f1of2(qreal v, qreal ) {return v;} + static qreal f2of2(qreal , qreal v) {return v;} - static qreal f1of3(qreal v, qreal , qreal ) {return v;}; - static qreal f2of3(qreal , qreal v, qreal ) {return v;}; - static qreal f3of3(qreal , qreal , qreal v) {return v;}; + static qreal f1of3(qreal v, qreal , qreal ) {return v;} + static qreal f2of3(qreal , qreal v, qreal ) {return v;} + static qreal f3of3(qreal , qreal , qreal v) {return v;} static qreal f1of4(qreal v, qreal, qreal , qreal ) {return v;} static qreal f2of4(qreal , qreal v, qreal , qreal ) {return v;} @@ -120,36 +121,32 @@ namespace qmu return 10; } - static qreal ValueOf(const char_type*) + static qreal ValueOf(const QString &) { return 123; } - static qreal StrFun1(const char_type* v1) + static qreal StrFun1(const QString & v1) { - int val(0); - stringstream_type(v1) >> val; + int val = v1.toInt(); return (qreal)val; } - static qreal StrFun2(const char_type* v1, qreal v2) + static qreal StrFun2(const QString & v1, qreal v2) { - int val(0); - stringstream_type(v1) >> val; + int val = v1.toInt(); return (qreal)(val + v2); } - static qreal StrFun3(const char_type* v1, qreal v2, qreal v3) + static qreal StrFun3(const QString & v1, qreal v2, qreal v3) { - int val(0); - stringstream_type(v1) >> val; + int val = v1.toInt(); return val + v2 + v3; } - static qreal StrToFloat(const char_type* a_szMsg) + static qreal StrToFloat(const QString & a_szMsg) { - qreal val(0); - stringstream_type(a_szMsg) >> val; + qreal val = a_szMsg.toDouble(); return val; } @@ -159,7 +156,7 @@ namespace qmu static qreal Milli(qreal a_fVal) { return a_fVal / (qreal)1e3; } // Custom value recognition - static int IsHexVal(const char_type *a_szExpr, int *a_iPos, qreal *a_fVal); + static int IsHexVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal); int TestNames(); int TestSyntax(); @@ -187,13 +184,13 @@ namespace qmu void AddTest(testfun_type a_pFun); // Test Double Parser - int EqnTest(const string_type& a_str, double a_fRes, bool a_fPass); - int EqnTestWithVarChange(const string_type& a_str, - double a_fRes1, - double a_fVar1, - double a_fRes2, + int EqnTest(const QString &a_str, double a_fRes, bool a_fPass); + int EqnTestWithVarChange(const QString &a_str, + double a_fRes1, + double a_fVar1, + double a_fRes2, double a_fVar2); - int ThrowTest(const string_type& a_str, int a_iErrc, bool a_bFail = true); + int ThrowTest(const QString &a_str, int a_iErrc, bool a_bFail = true); }; } // namespace Test } // namespace qmu diff --git a/src/libs/qmuparser/qmuparsertokenreader.cpp b/src/libs/qmuparser/qmuparsertokenreader.cpp index 24a439120..f21e80bf8 100644 --- a/src/libs/qmuparser/qmuparsertokenreader.cpp +++ b/src/libs/qmuparser/qmuparsertokenreader.cpp @@ -27,6 +27,8 @@ #include #include +#include + #include "qmuparsertokenreader.h" #include "qmuparserbase.h" @@ -191,7 +193,7 @@ namespace qmu \return #m_strFormula \throw nothrow */ - const string_type& QmuParserTokenReader::GetExpr() const + const QString& QmuParserTokenReader::GetExpr() const { return m_strFormula; } @@ -209,7 +211,7 @@ namespace qmu Sets the formula position index to zero and set Syntax flags to default for initial formula parsing. \pre [assert] triggered if a_szFormula==0 */ - void QmuParserTokenReader::SetFormula(const string_type &a_strFormula) + void QmuParserTokenReader::SetFormula(const QString &a_strFormula) { m_strFormula = a_strFormula; ReInit(); @@ -253,13 +255,19 @@ namespace qmu { assert(m_pParser); - std::stack FunArgs; - const char_type *szFormula = m_strFormula.c_str(); + //std::stack FunArgs; +#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) + { ++m_iPos; + } if ( IsEOF(tok) ) return SaveBeforeReturn(tok); // Check for end of formula if ( IsOprt(tok) ) return SaveBeforeReturn(tok); // Check for user defined binary operator @@ -280,19 +288,23 @@ namespace qmu // (The GetUsedVar function must suppress the error for // undefined variables in order to collect all variable // names including the undefined ones.) - if ( (m_bIgnoreUndefVar || m_pFactory) && IsUndefVarTok(tok) ) + if ( (m_bIgnoreUndefVar || m_pFactory) && IsUndefVarTok(tok) ) + { return SaveBeforeReturn(tok); + } // Check for unknown token // // !!! From this point on there is no exit without an exception possible... // - string_type strTok; + QString strTok; int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos); if (iEnd!=m_iPos) + { Error(ecUNASSIGNABLE_TOKEN, m_iPos, strTok); + } - Error(ecUNASSIGNABLE_TOKEN, m_iPos, m_strFormula.substr(m_iPos)); + Error(ecUNASSIGNABLE_TOKEN, m_iPos, m_strFormula.mid(m_iPos)); return token_type(); // never reached } @@ -309,59 +321,86 @@ namespace qmu m_pConstDef = &a_pParent->m_ConstDef; } - //--------------------------------------------------------------------------- - /** \brief Extract all characters that belong to a certain charset. +//--------------------------------------------------------------------------- +/** \brief Extract all characters that belong to a certain charset. - \param a_szCharSet [in] Const char array of the characters allowed in the token. - \param a_strTok [out] The string that consists entirely of characters listed in a_szCharSet. - \param a_iPos [in] Position in the string from where to start reading. - \return The Position of the first character not listed in a_szCharSet. - \throw nothrow - */ - int QmuParserTokenReader::ExtractToken(const char_type *a_szCharSet, - string_type &a_sTok, - int a_iPos) const - { - int iEnd = (int)m_strFormula.find_first_not_of(a_szCharSet, a_iPos); +\param a_szCharSet [in] Const char array of the characters allowed in the token. +\param a_strTok [out] The string that consists entirely of characters listed in a_szCharSet. +\param a_iPos [in] Position in the string from where to start reading. +\return The Position of the first character not listed in a_szCharSet. +\throw nothrow +*/ +int QmuParserTokenReader::ExtractToken(const QString &a_szCharSet, QString &a_sTok, int a_iPos) const +{ +#if defined(_UNICODE) + const std::wstring m_strFormulaStd = m_strFormula.toStdWString(); + const std::wstring a_szCharSetstd = a_szCharSet.toStdWString(); +#else + const std::string m_strFormulaStd = m_strFormula.toStdString(); + const std::string a_szCharSetStd = a_szCharSet.toStdString(); +#endif + + int iEnd = (int)m_strFormulaStd.find_first_not_of(a_szCharSetStd, a_iPos); if (iEnd==(int)string_type::npos) - iEnd = (int)m_strFormula.length(); - - // Assign token string if there was something found - if (a_iPos!=iEnd) - a_sTok = string_type( m_strFormula.begin()+a_iPos, m_strFormula.begin()+iEnd); - - return iEnd; - } - - //--------------------------------------------------------------------------- - /** \brief Check Expression for the presence of a binary operator token. - - Userdefined binary operator "++" gives inconsistent parsing result for - the equations "a++b" and "a ++ b" if alphabetic characters are allowed - in operator tokens. To avoid this this function checks specifically - for operator tokens. - */ - int QmuParserTokenReader::ExtractOperatorToken(string_type &a_sTok, - int a_iPos) const - { - int iEnd = (int)m_strFormula.find_first_not_of(m_pParser->ValidInfixOprtChars(), a_iPos); - if (iEnd==(int)string_type::npos) - iEnd = (int)m_strFormula.length(); + { + iEnd = (int)m_strFormulaStd.length(); + } // Assign token string if there was something found if (a_iPos!=iEnd) { - a_sTok = string_type( m_strFormula.begin() + a_iPos, m_strFormula.begin() + iEnd); - return iEnd; + #if defined(_UNICODE) + a_sTok = QString().fromStdWString(std::wstring( m_strFormulaStd.begin()+a_iPos, m_strFormulaStd.begin()+iEnd)); + #else + a_sTok = QString().fromStdString(std::string( m_strFormulaStd.begin()+a_iPos, m_strFormulaStd.begin()+iEnd)); + #endif + } + + return iEnd; +} + +//--------------------------------------------------------------------------- +/** \brief Check Expression for the presence of a binary operator token. + +Userdefined binary operator "++" gives inconsistent parsing result for +the equations "a++b" and "a ++ b" if alphabetic characters are allowed +in operator tokens. To avoid this this function checks specifically +for operator tokens. +*/ +int QmuParserTokenReader::ExtractOperatorToken(QString &a_sTok, int a_iPos) const +{ +#if defined(_UNICODE) + const std::wstring m_strFormulaStd = m_strFormula.toStdWString(); + const std::wstring oprtCharsStd = m_pParser->ValidInfixOprtChars().toStdWString(); +#else + const std::string m_strFormulaStd = m_strFormula.toStdString(); + const std::string oprtCharsStd = m_pParser->ValidInfixOprtChars().toStdString(); +#endif + int iEnd = (int)m_strFormulaStd.find_first_not_of(oprtCharsStd, a_iPos); + if (iEnd==(int)string_type::npos) + { + iEnd = (int)m_strFormulaStd.length(); + } + + // Assign token string if there was something found + if (a_iPos!=iEnd) + { + #if defined(_UNICODE) + a_sTok = QString().fromStdWString(string_type(m_strFormulaStd.begin() + a_iPos, + m_strFormulaStd.begin() + iEnd)); + #else + a_sTok = QString().fromStdString(string_type(m_strFormulaStd.begin() + a_iPos, m_strFormulaStd.begin() + iEnd)); + #endif + return iEnd; } else { - // There is still the chance of having to deal with an operator consisting exclusively - // of alphabetic characters. - return ExtractToken(QMUP_CHARS, a_sTok, a_iPos); + // There is still the chance of having to deal with an operator consisting exclusively + // of alphabetic characters. + return ExtractToken(QMUP_CHARS, a_sTok, a_iPos); } - } +} //--------------------------------------------------------------------------- /** \brief Check if a built in operator or other token can be found @@ -370,15 +409,14 @@ namespace qmu */ bool QmuParserTokenReader::IsBuiltIn(token_type &a_Tok) { - const char_type **const pOprtDef = m_pParser->GetOprtDef(), - *const szFormula = m_strFormula.c_str(); + const QStringList pOprtDef = m_pParser->GetOprtDef(); // Compare token with function and operator strings // check string for operator/function - for (int i=0; pOprtDef[i]; i++) + for (int i=0; i < pOprtDef.size(); ++i) { - std::size_t len( std::char_traits::length(pOprtDef[i]) ); - if ( string_type(pOprtDef[i]) == string_type(szFormula + m_iPos, szFormula + m_iPos + len) ) + int len = pOprtDef.at(i).length(); + if ( pOprtDef.at(i) == m_strFormula.mid(m_iPos, m_iPos + len) ) { switch(i) { @@ -404,7 +442,7 @@ namespace qmu // The assignement operator need special treatment if (i==cmASSIGN && m_iSynFlags & noASSIGN) - Error(ecUNEXPECTED_OPERATOR, m_iPos, pOprtDef[i]); + Error(ecUNEXPECTED_OPERATOR, m_iPos, pOprtDef.at(i)); if (!m_pParser->HasBuiltInOprt()) continue; if (m_iSynFlags & noOPT) @@ -415,7 +453,7 @@ namespace qmu if ( IsInfixOpTok(a_Tok) ) return true; - Error(ecUNEXPECTED_OPERATOR, m_iPos, pOprtDef[i]); + Error(ecUNEXPECTED_OPERATOR, m_iPos, pOprtDef.at(i)); } m_iSynFlags = noBC | noOPT | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE; @@ -424,7 +462,7 @@ namespace qmu case cmBO: if (m_iSynFlags & noBO) - Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef[i]); + Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef.at(i)); if (m_lastTok.GetCode()==cmFUNC) m_iSynFlags = noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE; @@ -436,24 +474,24 @@ namespace qmu case cmBC: if (m_iSynFlags & noBC) - Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef[i]); + Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef.at(i)); m_iSynFlags = noBO | noVAR | noVAL | noFUN | noINFIXOP | noSTR | noASSIGN; if (--m_iBrackets<0) - Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef[i]); + Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef.at(i)); break; case cmELSE: if (m_iSynFlags & noELSE) - Error(ecUNEXPECTED_CONDITIONAL, m_iPos, pOprtDef[i]); + Error(ecUNEXPECTED_CONDITIONAL, m_iPos, pOprtDef.at(i)); m_iSynFlags = noBC | noPOSTOP | noEND | noOPT | noIF | noELSE; break; case cmIF: if (m_iSynFlags & noIF) - Error(ecUNEXPECTED_CONDITIONAL, m_iPos, pOprtDef[i]); + Error(ecUNEXPECTED_CONDITIONAL, m_iPos, pOprtDef.at(i)); m_iSynFlags = noBC | noPOSTOP | noEND | noOPT | noIF | noELSE; break; @@ -462,8 +500,8 @@ namespace qmu Error(ecINTERNAL_ERROR); } // switch operator id - m_iPos += (int)len; - a_Tok.Set( (ECmdCode)i, pOprtDef[i] ); + m_iPos += len; + a_Tok.Set( (ECmdCode)i, pOprtDef.at(i) ); return true; } // if operator string found } // end of for all operator strings @@ -474,17 +512,17 @@ namespace qmu //--------------------------------------------------------------------------- bool QmuParserTokenReader::IsArgSep(token_type &a_Tok) { - const char_type* szFormula = m_strFormula.c_str(); - - if (szFormula[m_iPos]==m_cArgSep) + if (m_strFormula.at(m_iPos)==m_cArgSep) { // copy the separator into null terminated string - char_type szSep[2]; + QString szSep; szSep[0] = m_cArgSep; szSep[1] = 0; if (m_iSynFlags & noARG_SEP) + { Error(ecUNEXPECTED_ARG_SEP, m_iPos, szSep); + } m_iSynFlags = noBC | noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN; m_iPos++; @@ -505,7 +543,11 @@ namespace qmu */ bool QmuParserTokenReader::IsEOF(token_type &a_Tok) { - const char_type* szFormula = m_strFormula.c_str(); +#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] /*|| szFormula[m_iPos] == '\n'*/) @@ -530,7 +572,7 @@ namespace qmu */ bool QmuParserTokenReader::IsInfixOpTok(token_type &a_Tok) { - string_type sTok; + QString sTok; int iEnd = ExtractToken(m_pParser->ValidInfixOprtChars(), sTok, m_iPos); if (iEnd==m_iPos) return false; @@ -539,7 +581,7 @@ namespace qmu funmap_type::const_reverse_iterator it = m_pInfixOprtDef->rbegin(); for ( ; it!=m_pInfixOprtDef->rend(); ++it) { - if (sTok.find(it->first)!=0) + if (sTok.indexOf(it->first)!=0) continue; a_Tok.Set(it->second, it->first); @@ -575,7 +617,7 @@ namespace qmu */ bool QmuParserTokenReader::IsFunTok(token_type &a_Tok) { - string_type strTok; + QString strTok; int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos); if (iEnd==m_iPos) return false; @@ -585,13 +627,12 @@ namespace qmu return false; // Check if the next sign is an opening bracket - const char_type *szFormula = m_strFormula.c_str(); - if (szFormula[iEnd]!='(') + if (m_strFormula.at(iEnd)!='(') return false; a_Tok.Set(item->second, strTok); - m_iPos = (int)iEnd; + m_iPos = iEnd; if (m_iSynFlags & noFUN) Error(ecUNEXPECTED_FUN, m_iPos-(int)a_Tok.GetAsString().length(), a_Tok.GetAsString()); @@ -606,18 +647,19 @@ namespace qmu */ bool QmuParserTokenReader::IsOprt(token_type &a_Tok) { - const char_type *const szExpr = m_strFormula.c_str(); - string_type strTok; + QString strTok; int iEnd = ExtractOperatorToken(strTok, m_iPos); if (iEnd==m_iPos) return false; // Check if the operator is a built in operator, if so ignore it here - const char_type **const pOprtDef = m_pParser->GetOprtDef(); - for (int i=0; m_pParser->HasBuiltInOprt() && pOprtDef[i]; ++i) + const QStringList pOprtDef = m_pParser->GetOprtDef(); + QStringList::const_iterator constIterator; + for (constIterator = pOprtDef.constBegin(); m_pParser->HasBuiltInOprt() && constIterator != pOprtDef.constEnd(); + ++constIterator) { - if (string_type(pOprtDef[i])==strTok) + if ((*constIterator)==strTok) return false; } @@ -630,8 +672,8 @@ namespace qmu funmap_type::const_reverse_iterator it = m_pOprtDef->rbegin(); for ( ; it!=m_pOprtDef->rend(); ++it) { - const string_type &sID = it->first; - if ( sID == string_type(szExpr + m_iPos, szExpr + m_iPos + sID.length()) ) + const QString &sID = it->first; + if ( sID == m_strFormula.mid(m_iPos, m_iPos + sID.length()) ) { a_Tok.Set(it->second, strTok); @@ -686,7 +728,7 @@ namespace qmu // token readers. // Test if there could be a postfix operator - string_type sTok; + QString sTok; int iEnd = ExtractToken(m_pParser->ValidOprtChars(), sTok, m_iPos); if (iEnd==m_iPos) return false; @@ -695,11 +737,11 @@ namespace qmu funmap_type::const_reverse_iterator it = m_pPostOprtDef->rbegin(); for ( ; it!=m_pPostOprtDef->rend(); ++it) { - if (sTok.find(it->first)!=0) + if (sTok.indexOf(it->first)!=0) continue; a_Tok.Set(it->second, sTok); - m_iPos += (int)it->first.length(); + m_iPos += it->first.length(); m_iSynFlags = noVAL | noVAR | noFUN | noBO | noPOSTOP | noSTR | noASSIGN; return true; @@ -721,7 +763,7 @@ namespace qmu assert(m_pConstDef); assert(m_pParser); - string_type strTok; + QString strTok; qreal fVal(0); int iEnd(0); @@ -737,7 +779,7 @@ namespace qmu a_Tok.SetVal(item->second, strTok); if (m_iSynFlags & noVAL) - Error(ecUNEXPECTED_VAL, m_iPos - (int)strTok.length(), strTok); + Error(ecUNEXPECTED_VAL, m_iPos - strTok.length(), strTok); m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN; return true; @@ -750,11 +792,11 @@ namespace qmu for (item = m_vIdentFun.begin(); item!=m_vIdentFun.end(); ++item) { int iStart = m_iPos; - if ( (*item)(m_strFormula.c_str() + m_iPos, &m_iPos, &fVal)==1 ) + if ( (*item)(m_strFormula.mid(m_iPos), &m_iPos, &fVal)==1 ) { - strTok.assign(m_strFormula.c_str(), iStart, m_iPos); + strTok = m_strFormula.mid(iStart, m_iPos); if (m_iSynFlags & noVAL) - Error(ecUNEXPECTED_VAL, m_iPos - (int)strTok.length(), strTok); + Error(ecUNEXPECTED_VAL, m_iPos - strTok.length(), strTok); a_Tok.SetVal(fVal, strTok); m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN; @@ -775,7 +817,7 @@ namespace qmu if (!m_pVarDef->size()) return false; - string_type strTok; + QString strTok; int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos); if (iEnd==m_iPos) return false; @@ -806,7 +848,7 @@ namespace qmu if (!m_pStrVarDef || !m_pStrVarDef->size()) return false; - string_type strTok; + QString strTok; int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos); if (iEnd==m_iPos) return false; @@ -838,7 +880,7 @@ namespace qmu */ bool QmuParserTokenReader::IsUndefVarTok(token_type &a_Tok) { - string_type strTok; + QString strTok; int iEnd( ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos) ); if ( iEnd==m_iPos ) return false; @@ -855,7 +897,7 @@ namespace qmu // If a factory is available implicitely create new variables if (m_pFactory) { - qreal *fVar = m_pFactory(strTok.c_str(), m_pFactoryData); + qreal *fVar = m_pFactory(strTok, m_pFactoryData); a_Tok.SetVar(fVar, strTok ); // Do not use m_pParser->DefineVar( strTok, fVar ); @@ -893,21 +935,21 @@ namespace qmu if (m_strFormula[m_iPos]!='"') return false; - string_type strBuf(&m_strFormula[m_iPos+1]); - std::size_t iEnd(0), iSkip(0); + QString strBuf(m_strFormula[m_iPos+1]); + int iEnd(0), iSkip(0); // parser over escaped '\"' end replace them with '"' - for(iEnd=(int)strBuf.find( "\"" ); iEnd!=0 && iEnd!=string_type::npos; iEnd=(int)strBuf.find( "\"", iEnd)) + for(iEnd=strBuf.indexOf( "\"" ); iEnd!=0 && iEnd!=-1; iEnd=strBuf.indexOf( "\"", iEnd)) { if (strBuf[iEnd-1]!='\\') break; strBuf.replace(iEnd-1, 2, "\"" ); iSkip++; } - if (iEnd==string_type::npos) + if (iEnd==-1) Error(ecUNTERMINATED_STRING, m_iPos, "\"" ); - string_type strTok(strBuf.begin(), strBuf.begin()+iEnd); + QString strTok = strBuf.mid(0, iEnd); if (m_iSynFlags & noSTR) Error(ecUNEXPECTED_STR, m_iPos, strTok); @@ -915,7 +957,7 @@ namespace qmu m_pParser->m_vStringBuf.push_back(strTok); // Store string in internal buffer a_Tok.SetString(strTok, m_pParser->m_vStringBuf.size()); - m_iPos += (int)strTok.length() + 2 + (int)iSkip; // +2 wg Anfhrungszeichen; +iSkip fr entfernte escape zeichen + m_iPos += (int)strTok.length() + 2 + iSkip; // +2 wg Anfhrungszeichen; +iSkip fr entfernte escape zeichen m_iSynFlags = noANY ^ ( noARG_SEP | noBC | noOPT | noEND ); return true; @@ -933,7 +975,7 @@ namespace qmu */ void QmuParserTokenReader::Error( EErrorCodes a_iErrc, int a_iPos, - const string_type &a_sTok) const + const QString &a_sTok) const { m_pParser->Error(a_iErrc, a_iPos, a_sTok); } @@ -945,7 +987,7 @@ namespace qmu } //--------------------------------------------------------------------------- - char_type QmuParserTokenReader::GetArgSep() const + QChar QmuParserTokenReader::GetArgSep() const { return m_cArgSep; } diff --git a/src/libs/qmuparser/qmuparsertokenreader.h b/src/libs/qmuparser/qmuparsertokenreader.h index 7c22fcb53..de73388eb 100644 --- a/src/libs/qmuparser/qmuparsertokenreader.h +++ b/src/libs/qmuparser/qmuparsertokenreader.h @@ -52,7 +52,7 @@ namespace qmu { private: - typedef QmuParserToken token_type; + typedef QmuParserToken token_type; public: @@ -61,13 +61,13 @@ namespace qmu void AddValIdent(identfun_type a_pCallback); void SetVarCreator(facfun_type a_pFactory, void *pUserData); - void SetFormula(const string_type &a_strFormula); + void SetFormula(const QString &a_strFormula); void SetArgSep(char_type cArgSep); int GetPos() const; - const string_type& GetExpr() const; + const QString &GetExpr() const; varmap_type& GetUsedVar(); - char_type GetArgSep() const; + QChar GetArgSep() const; void IgnoreUndefVar(bool bIgnore); void ReInit(); @@ -106,10 +106,8 @@ namespace qmu void Assign(const QmuParserTokenReader &a_Reader); void SetParent(QmuParserBase *a_pParent); - int ExtractToken(const char_type *a_szCharSet, - string_type &a_strTok, - int a_iPos) const; - int ExtractOperatorToken(string_type &a_sTok, int a_iPos) const; + int ExtractToken(const QString &a_szCharSet, QString &a_strTok, int a_iPos) const; + int ExtractOperatorToken(QString &a_sTok, int a_iPos) const; bool IsBuiltIn(token_type &a_Tok); bool IsArgSep(token_type &a_Tok); @@ -123,14 +121,14 @@ namespace qmu bool IsStrVarTok(token_type &a_Tok); bool IsUndefVarTok(token_type &a_Tok); bool IsString(token_type &a_Tok); - void Error(EErrorCodes a_iErrc, - int a_iPos = -1, - const string_type &a_sTok = string_type() ) const; + void Error(EErrorCodes a_iErrc, + int a_iPos = -1, + const QString &a_sTok = QString() ) const; token_type& SaveBeforeReturn(const token_type &tok); QmuParserBase *m_pParser; - string_type m_strFormula; + QString m_strFormula; int m_iPos; int m_iSynFlags; bool m_bIgnoreUndefVar; @@ -149,7 +147,7 @@ namespace qmu qreal m_fZero; ///< Dummy value of zero, referenced by undefined variables int m_iBrackets; token_type m_lastTok; - char_type m_cArgSep; ///< The character used for separating function arguments + QChar m_cArgSep; ///< The character used for separating function arguments }; } // namespace qmu