diff --git a/src/libs/qmuparser/qmuparser.cpp b/src/libs/qmuparser/qmuparser.cpp index 2224dabc2..0c7d38ea0 100644 --- a/src/libs/qmuparser/qmuparser.cpp +++ b/src/libs/qmuparser/qmuparser.cpp @@ -64,7 +64,7 @@ qreal QmuParser::ACosh(qreal v) qreal QmuParser::ATanh(qreal v) { - return ((qreal)0.5 * log((1 + v) / (1 - v))); + return (0.5 * log((1 + v) / (1 - v))); } //---------------------------------------------------------------------------------------------------------------------- // Logarithm functions @@ -78,7 +78,7 @@ qreal QmuParser::Log2(qreal v) throw QmuParserError(ecDOMAIN_ERROR, "Log2"); } #endif - return log(v)/log((qreal)2); + return log(v)/log(2.0); } // Logarithm base 10 @@ -102,12 +102,12 @@ qreal QmuParser::Abs(qreal v) qreal QmuParser::Rint(qreal v) { - return qFloor(v + (qreal)0.5); + return qFloor(v + 0.5); } qreal QmuParser::Sign(qreal v) { - return (qreal)((v<0) ? -1 : (v>0) ? 1 : 0); + return ((v<0) ? -1 : (v>0) ? 1 : 0); } //---------------------------------------------------------------------------------------------------------------------- @@ -152,7 +152,7 @@ qreal QmuParser::Avg(const qreal *a_afArg, int a_iArgc) } qreal fRes=0; for (int i=0; i(a_iArgc); } //---------------------------------------------------------------------------------------------------------------------- @@ -218,12 +218,12 @@ int QmuParser::IsVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal) stream >> fVal; stringstream_type::pos_type iEnd = stream.tellg(); // Position after reading - if (iEnd==(stringstream_type::pos_type)-1) + if (iEnd==static_cast(-1)) { return 0; } - *a_iPos += (int)iEnd; + *a_iPos += static_cast(iEnd); *a_fVal = fVal; return 1; } @@ -325,8 +325,11 @@ void QmuParser::InitOprt() } //---------------------------------------------------------------------------------------------------------------------- -void QmuParser::OnDetectVar(string_type * /*pExpr*/, int & /*nStart*/, int & /*nEnd*/) +void QmuParser::OnDetectVar(const QString &pExpr, int &nStart, int &nEnd) { + Q_UNUSED(pExpr); + Q_UNUSED(nStart); + Q_UNUSED(nEnd); // this is just sample code to illustrate modifying variable names on the fly. // I'm not sure anyone really needs such a feature... /* @@ -372,9 +375,9 @@ qreal QmuParser::Diff(qreal *a_Var, qreal a_fPos, qreal a_fEpsilon) const // Backwards compatible calculation of epsilon inc case the user doesnt provide // his own epsilon - if (fEpsilon==0) + if (qFuzzyCompare(fEpsilon + 1, 1 + 0)) { - fEpsilon = (a_fPos==0) ? (qreal)1e-10 : (qreal)1e-7 * a_fPos; + fEpsilon = (qFuzzyCompare(a_fPos + 1, 1 + 0)) ? static_cast(1e-10) : static_cast(1e-7) * a_fPos; } *a_Var = a_fPos+2 * fEpsilon; f[0] = Eval(); diff --git a/src/libs/qmuparser/qmuparser.h b/src/libs/qmuparser/qmuparser.h index 861325a5e..bb713ed76 100644 --- a/src/libs/qmuparser/qmuparser.h +++ b/src/libs/qmuparser/qmuparser.h @@ -51,7 +51,7 @@ namespace qmu virtual void InitFun(); virtual void InitConst(); virtual void InitOprt(); - virtual void OnDetectVar(string_type *pExpr, int &nStart, int &nEnd); + virtual void OnDetectVar(const QString &pExpr, int &nStart, int &nEnd); qreal Diff(qreal *a_Var, qreal a_fPos, qreal a_fEpsilon = 0) const; protected: static int IsVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal); diff --git a/src/libs/qmuparser/qmuparserbase.cpp b/src/libs/qmuparser/qmuparserbase.cpp index 62a76871c..07ecfea7a 100644 --- a/src/libs/qmuparser/qmuparserbase.cpp +++ b/src/libs/qmuparser/qmuparserbase.cpp @@ -58,9 +58,9 @@ const QStringList QmuParserBase::c_DefaultOprt = QStringList() << "<=" << ">=" < * @throw ParserException if a_szFormula is null. */ QmuParserBase::QmuParserBase() - :m_pParseFormula(&QmuParserBase::ParseString), m_vRPN(), m_vStringBuf(), m_pTokenReader(), m_FunDef(), - m_PostOprtDef(), m_InfixOprtDef(), m_OprtDef(), m_ConstDef(), m_StrVarDef(), m_VarDef(), m_bBuiltInOp(true), - m_sNameChars(), m_sOprtChars(), m_sInfixOprtChars(), m_nIfElseCounter(0), m_vStackBuffer(), + :m_pParseFormula(&QmuParserBase::ParseString), m_vRPN(), m_vStringBuf(), m_vStringVarBuf(), m_pTokenReader(), + m_FunDef(), m_PostOprtDef(), m_InfixOprtDef(), m_OprtDef(), m_ConstDef(), m_StrVarDef(), m_VarDef(), + m_bBuiltInOp(true), m_sNameChars(), m_sOprtChars(), m_sInfixOprtChars(), m_nIfElseCounter(0), m_vStackBuffer(), m_nFinalResultIdx(0) { InitTokenReader(); @@ -73,9 +73,10 @@ QmuParserBase::QmuParserBase() * Tha parser can be safely copy constructed but the bytecode is reset during copy construction. */ QmuParserBase::QmuParserBase(const QmuParserBase &a_Parser) -:m_pParseFormula(&QmuParserBase::ParseString), m_vRPN(), m_vStringBuf(), m_pTokenReader(), m_FunDef(), - m_PostOprtDef(), m_InfixOprtDef(), m_OprtDef(), m_ConstDef(), m_StrVarDef(), m_VarDef(), m_bBuiltInOp(true), - m_sNameChars(), m_sOprtChars(), m_sInfixOprtChars(), m_nIfElseCounter(0) + :m_pParseFormula(&QmuParserBase::ParseString), m_vRPN(), m_vStringBuf(), m_vStringVarBuf(), m_pTokenReader(), + m_FunDef(), m_PostOprtDef(), m_InfixOprtDef(), m_OprtDef(), m_ConstDef(), m_StrVarDef(), m_VarDef(), + m_bBuiltInOp(true), m_sNameChars(), m_sOprtChars(), m_sInfixOprtChars(), m_nIfElseCounter(0), m_vStackBuffer(), + m_nFinalResultIdx(0) { m_pTokenReader.reset(new token_reader_type(this)); Assign(a_Parser); @@ -216,8 +217,12 @@ void QmuParserBase::ReInit() const } //---------------------------------------------------------------------------------------------------------------------- -void QmuParserBase::OnDetectVar(QString * /*pExpr*/, int & /*nStart*/, int & /*nEnd*/) -{} +void QmuParserBase::OnDetectVar(const QString &pExpr, int &nStart, int &nEnd) +{ + Q_UNUSED(pExpr); + Q_UNUSED(nStart); + Q_UNUSED(nEnd); +} //---------------------------------------------------------------------------------------------------------------------- /** @@ -361,6 +366,108 @@ void QmuParserBase::CheckOprt(const QString &a_sName, const QmuParserCallback &a case cmOPRT_INFIX: Error(ecINVALID_INFIX_IDENT, -1, a_sName); break; + 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 cmVAR: + Q_UNREACHABLE(); + break; + case cmVAL: + 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 cmEND: + Q_UNREACHABLE(); + break; + case cmUNKNOWN: + Q_UNREACHABLE(); + break; default: Error(ecINVALID_NAME, -1, a_sName); break; @@ -660,6 +767,54 @@ int QmuParserBase::GetOprtPrecedence(const token_type &a_Tok) const case cmOPRT_INFIX: case cmOPRT_BIN: return a_Tok.GetPri(); + case cmBO: + Q_UNREACHABLE(); + break; + case cmBC: + Q_UNREACHABLE(); + break; + case cmENDIF: + Q_UNREACHABLE(); + break; + case cmVAR: + Q_UNREACHABLE(); + break; + case cmVAL: + 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_POSTFIX: + Q_UNREACHABLE(); + break; + case cmUNKNOWN: + Q_UNREACHABLE(); + break; default: Error(ecINTERNAL_ERROR, 5); return 999; @@ -693,6 +848,69 @@ EOprtAssociativity QmuParserBase::GetOprtAssociativity(const token_type &a_Tok) return oaRIGHT; case cmOPRT_BIN: return a_Tok.GetAssociativity(); + 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 cmVAR: + Q_UNREACHABLE(); + break; + case cmVAL: + 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_POSTFIX: + Q_UNREACHABLE(); + break; + case cmOPRT_INFIX: + Q_UNREACHABLE(); + break; + case cmEND: + Q_UNREACHABLE(); + break; + case cmUNKNOWN: + Q_UNREACHABLE(); + break; default: return oaNONE; } @@ -888,30 +1106,122 @@ void QmuParserBase::ApplyFunc( QStack &a_stOpt, QStack & switch(funTok.GetCode()) { - case cmFUNC_STR: - stArg.push_back(a_stVal.pop()); + case cmFUNC_STR: + stArg.push_back(a_stVal.pop()); - if ( stArg.back().GetType()==tpSTR && funTok.GetType()!=tpSTR ) - { - Error(ecVAL_EXPECTED, m_pTokenReader->GetPos(), funTok.GetAsString()); - } + if ( stArg.back().GetType()==tpSTR && funTok.GetType()!=tpSTR ) + { + Error(ecVAL_EXPECTED, m_pTokenReader->GetPos(), funTok.GetAsString()); + } - ApplyStrFunc(funTok, stArg); - break; - case cmFUNC_BULK: - m_vRPN.AddBulkFun(funTok.GetFuncAddr(), (int)stArg.size()); - break; - case cmOPRT_BIN: - case cmOPRT_POSTFIX: - case cmOPRT_INFIX: - case cmFUNC: - if (funTok.GetArgCount()==-1 && iArgCount==0) - { - Error(ecTOO_FEW_PARAMS, m_pTokenReader->GetPos(), funTok.GetAsString()); - } + ApplyStrFunc(funTok, stArg); + break; + case cmFUNC_BULK: + m_vRPN.AddBulkFun(funTok.GetFuncAddr(), stArg.size()); + break; + case cmOPRT_BIN: + case cmOPRT_POSTFIX: + case cmOPRT_INFIX: + case cmFUNC: + if (funTok.GetArgCount()==-1 && iArgCount==0) + { + Error(ecTOO_FEW_PARAMS, m_pTokenReader->GetPos(), funTok.GetAsString()); + } - m_vRPN.AddFun(funTok.GetFuncAddr(), (funTok.GetArgCount()==-1) ? -iArgNumerical : iArgNumerical); - break; + m_vRPN.AddFun(funTok.GetFuncAddr(), (funTok.GetArgCount()==-1) ? -iArgNumerical : iArgNumerical); + break; + 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 cmVAR: + Q_UNREACHABLE(); + break; + case cmVAL: + 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 cmSTRING: + Q_UNREACHABLE(); + break; + case cmEND: + Q_UNREACHABLE(); + break; + case cmUNKNOWN: + Q_UNREACHABLE(); + break; + default: + break; } // Push dummy value representing the function result to the stack token_type token; @@ -939,7 +1249,7 @@ void QmuParserBase::ApplyIfElse(QStack &a_stOpt, QStack token_type vVal1 = a_stVal.pop(); token_type vExpr = a_stVal.pop(); - a_stVal.push( (vExpr.GetVal()!=0) ? vVal1 : vVal2); + a_stVal.push( (qFuzzyCompare(vExpr.GetVal()+1, 1+0)==false) ? vVal1 : vVal2); token_type opIf = a_stOpt.pop(); Q_ASSERT(opElse.GetCode()==cmELSE); @@ -1031,6 +1341,63 @@ void QmuParserBase::ApplyRemainingOprt(QStack &stOpt, QStackOprt.ptr = Stack[sidx+1]; continue; - //case cmBO: // unused, listed for compiler optimization purposes - //case cmBC: + case cmBO: // unused, listed for compiler optimization purposes + Q_UNREACHABLE(); + break; + case cmBC: + Q_UNREACHABLE(); + break; // Q_ASSERT(INVALID_CODE_IN_BYTECODE); // continue; case cmIF: - if (Stack[sidx--]==0) + if (qFuzzyCompare(Stack[sidx--]+1, 1+0)) { pTok += pTok->Oprt.offset; } @@ -1149,7 +1534,9 @@ qreal QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const continue; case cmENDIF: continue; - //case cmARG_SEP: + case cmARG_SEP: + Q_UNREACHABLE(); + break; // Q_ASSERT(INVALID_CODE_IN_BYTECODE); // continue; @@ -1185,55 +1572,57 @@ qreal QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const { case 0: sidx += 1; - Stack[sidx] = (*(fun_type0)pTok->Fun.ptr)(); + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(); continue; case 1: - Stack[sidx] = (*(fun_type1)pTok->Fun.ptr)(Stack[sidx]); + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx]); continue; case 2: sidx -= 1; - Stack[sidx] = (*(fun_type2)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1]); + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1]); continue; case 3: sidx -= 2; - Stack[sidx] = (*(fun_type3)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2]); + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], + Stack[sidx+2]); continue; case 4: sidx -= 3; - Stack[sidx] = (*(fun_type4)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], - Stack[sidx+3]); + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], + Stack[sidx+2], Stack[sidx+3]); continue; case 5: sidx -= 4; - Stack[sidx] = (*(fun_type5)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], - Stack[sidx+3], Stack[sidx+4]); + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], + Stack[sidx+2], Stack[sidx+3], Stack[sidx+4]); continue; case 6: sidx -= 5; - Stack[sidx] = (*(fun_type6)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], - Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]); + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], + Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]); continue; case 7: sidx -= 6; - Stack[sidx] = (*(fun_type7)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], - Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]); + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], + Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]); continue; case 8: sidx -= 7; - Stack[sidx] = (*(fun_type8)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], - Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7]); + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], + Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], + Stack[sidx+7]); continue; case 9: sidx -= 8; - Stack[sidx] = (*(fun_type9)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], - Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], - Stack[sidx+8]); + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], + Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], + Stack[sidx+7], Stack[sidx+8]); continue; case 10: sidx -= 9; - Stack[sidx] = (*(fun_type10)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], - Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], - Stack[sidx+8], Stack[sidx+9]); + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], + Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], + Stack[sidx+7], Stack[sidx+8], Stack[sidx+9]); continue; default: if (iArgCount>0) // function with variable arguments store the number as a negative value @@ -1242,7 +1631,7 @@ qreal QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const } sidx -= -iArgCount - 1; - Stack[sidx] =(*(multfun_type)pTok->Fun.ptr)(&Stack[sidx], -iArgCount); + Stack[sidx] =(*reinterpret_cast(pTok->Fun.ptr))(&Stack[sidx], -iArgCount); continue; } } @@ -1253,25 +1642,27 @@ qreal QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const // The index of the string argument in the string table int iIdxStack = pTok->Fun.idx; - Q_ASSERT( iIdxStack>=0 && iIdxStack<(int)m_vStringBuf.size() ); + Q_ASSERT( iIdxStack>=0 && iIdxStackFun.argc) // switch according to argument count { case 0: - Stack[sidx] = (*(strfun_type1)pTok->Fun.ptr)(m_vStringBuf.at(iIdxStack)); + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(m_vStringBuf.at(iIdxStack)); continue; case 1: - Stack[sidx] = (*(strfun_type2)pTok->Fun.ptr)(m_vStringBuf.at(iIdxStack), Stack[sidx]); + Stack[sidx] = (*reinterpret_cast(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]); + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(m_vStringBuf.at(iIdxStack), + Stack[sidx], Stack[sidx+1]); continue; + default: + break; } continue; } - case cmFUNC_BULK: { int iArgCount = pTok->Fun.argc; @@ -1281,59 +1672,61 @@ qreal QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const { case 0: sidx += 1; - Stack[sidx] = (*(bulkfun_type0 )pTok->Fun.ptr)(nOffset, nThreadID); + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID); continue; case 1: - Stack[sidx] = (*(bulkfun_type1 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx]); + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, + Stack[sidx]); continue; case 2: sidx -= 1; - Stack[sidx] = (*(bulkfun_type2 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], Stack[sidx+1]); continue; case 3: sidx -= 2; - Stack[sidx] = (*(bulkfun_type3 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2]); continue; case 4: sidx -= 3; - Stack[sidx] = (*(bulkfun_type4 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3]); continue; case 5: sidx -= 4; - Stack[sidx] = (*(bulkfun_type5 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4]); continue; case 6: sidx -= 5; - Stack[sidx] = (*(bulkfun_type6 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]); continue; case 7: sidx -= 6; - Stack[sidx] = (*(bulkfun_type7 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]); continue; case 8: sidx -= 7; - Stack[sidx] = (*(bulkfun_type8 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7]); continue; case 9: sidx -= 8; - Stack[sidx] = (*(bulkfun_type9 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8]); continue; case 10: sidx -= 9; - Stack[sidx] = (*(bulkfun_type10)pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, + Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8], Stack[sidx+9]); @@ -1343,16 +1736,30 @@ qreal QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const continue; } } - //case cmSTRING: - //case cmOPRT_BIN: - //case cmOPRT_POSTFIX: - //case cmOPRT_INFIX: + case cmSTRING: + Q_UNREACHABLE(); + break; + case cmOPRT_BIN: + Q_UNREACHABLE(); + break; + case cmOPRT_POSTFIX: + Q_UNREACHABLE(); + break; + case cmOPRT_INFIX: + Q_UNREACHABLE(); + break; // Q_ASSERT(INVALID_CODE_IN_BYTECODE); // continue; - - //case cmEND: + case cmEND: + Q_UNREACHABLE(); + break; // return Stack[m_nFinalResultIdx]; - + case cmPOW2: + Q_UNREACHABLE(); + break; + case cmUNKNOWN: + Q_UNREACHABLE(); + break; default: Error(ecINTERNAL_ERROR, 3); return 0; @@ -1392,7 +1799,7 @@ void QmuParserBase::CreateRPN() const // Next three are different kind of value entries // case cmSTRING: - opt.SetIdx((int)m_vStringBuf.size()); // Assign buffer index to token + opt.SetIdx(m_vStringBuf.size()); // Assign buffer index to token stVal.push(opt); m_vStringBuf.push_back(opt.GetAsString()); // Store string in internal buffer break; @@ -1549,6 +1956,27 @@ void QmuParserBase::CreateRPN() const stOpt.push(opt); ApplyFunc(stOpt, stVal, 1); // this is the postfix operator break; + case cmENDIF: + 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 cmUNKNOWN: + Q_UNREACHABLE(); + break; default: Error(ecINTERNAL_ERROR, 3); } // end of switch operator-token @@ -1634,7 +2062,7 @@ qreal QmuParserBase::ParseString() const * @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 QString &a_sTok) 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); } @@ -1882,6 +2310,72 @@ void QmuParserBase::StackDump(const QStack &a_stVal, const QStack - void DefineFun(const QString &a_strName, T a_pFun, bool a_bAllowOpt = true) - { - AddCallback( a_strName, QmuParserCallback(a_pFun, a_bAllowOpt), m_FunDef, ValidNameChars() ); - } - protected: - static const QStringList c_DefaultOprt; - static std::locale s_locale; ///< The locale used by the parser - static bool g_DbgDumpCmdCode; - static bool g_DbgDumpStack; - void Init(); - virtual void InitCharSets() = 0; - virtual void InitFun() = 0; - virtual void InitConst() = 0; - virtual void InitOprt() = 0; - virtual void OnDetectVar(QString *pExpr, int &nStart, int &nEnd); - /** - * @brief A facet class used to change decimal and thousands separator. - */ - template - class change_dec_sep : public std::numpunct - { - public: - explicit change_dec_sep(char_type cDecSep, char_type cThousandsSep = 0, int nGroup = 3) - :std::numpunct(), m_nGroup(nGroup), m_cDecPoint(cDecSep), m_cThousandsSep(cThousandsSep) - {} - protected: - virtual char_type do_decimal_point() const - { - return m_cDecPoint; - } + static void EnableDebugDump(bool bDumpCmd, bool bDumpStack); + qreal Eval() const; + qreal* Eval(int &nStackSize) const; + void Eval(qreal *results, int nBulkSize); + int GetNumResults() const; + void SetExpr(const QString &a_sExpr); + void SetVarFactory(facfun_type a_pFactory, void *pUserData = NULL); + void SetDecSep(char_type cDecSep); + void SetThousandsSep(char_type cThousandsSep = 0); + void ResetLocale(); + void EnableOptimizer(bool a_bIsOn=true); + void EnableBuiltInOprt(bool a_bIsOn=true); + bool HasBuiltInOprt() const; + void AddValIdent(identfun_type a_pCallback); + 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 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(); + void ClearFun(); + void ClearConst(); + void ClearInfixOprt(); + void ClearPostfixOprt(); + void ClearOprt(); + void RemoveVar(const QString &a_strVarName); + const varmap_type& GetUsedVar() const; + const varmap_type& GetVar() const; + const valmap_type& GetConst() const; + const QString& GetExpr() const; + const funmap_type& GetFunDef() const; + QString GetVersion(EParserVersionInfo eInfo = pviFULL) const; + const QStringList& GetOprtDef() const; + void DefineNameChars(const QString &a_szCharset); + void DefineOprtChars(const QString &a_szCharset); + void DefineInfixOprtChars(const QString &a_szCharset); + const QString& ValidNameChars() const; + const QString& ValidOprtChars() const; + 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; + /** + * @fn void qmu::QmuParserBase::DefineFun(const string_type &a_strName, fun_type0 a_pFun, + * bool a_bAllowOpt = true) + * @brief Define a parser function without arguments. + * @param a_strName Name of the function + * @param a_pFun Pointer to the callback function + * @param a_bAllowOpt A flag indicating this function may be optimized + */ + template + void DefineFun(const QString &a_strName, T a_pFun, bool a_bAllowOpt = true) + { + AddCallback( a_strName, QmuParserCallback(a_pFun, a_bAllowOpt), m_FunDef, ValidNameChars() ); + } +protected: + static const QStringList c_DefaultOprt; + static std::locale s_locale; ///< The locale used by the parser + static bool g_DbgDumpCmdCode; + static bool g_DbgDumpStack; + void Init(); + virtual void InitCharSets() = 0; + virtual void InitFun() = 0; + virtual void InitConst() = 0; + virtual void InitOprt() = 0; + virtual void OnDetectVar(const QString &pExpr, int &nStart, int &nEnd); + /** + * @brief A facet class used to change decimal and thousands separator. + */ + template + class change_dec_sep : public std::numpunct + { + public: + explicit change_dec_sep(char_type cDecSep, char_type cThousandsSep = 0, int nGroup = 3) + :std::numpunct(), m_nGroup(nGroup), m_cDecPoint(cDecSep), m_cThousandsSep(cThousandsSep) + {} + protected: + virtual char_type do_decimal_point() const + { + return m_cDecPoint; + } - virtual char_type do_thousands_sep() const - { - return m_cThousandsSep; - } + virtual char_type do_thousands_sep() const + { + return m_cThousandsSep; + } - virtual std::string do_grouping() const - { - return std::string(1, m_nGroup); - } - private: - int m_nGroup; - char_type m_cDecPoint; - char_type m_cThousandsSep; - }; - private: - /** - * @brief Typedef for the parse functions. - * - * The parse function do the actual work. The parser exchanges - * the function pointer to the parser function depending on - * which state it is in. (i.e. bytecode parser vs. string parser) - */ - typedef qreal (QmuParserBase::*ParseFunction)() const; + virtual std::string do_grouping() const + { + return std::string(1, m_nGroup); + } + private: + int m_nGroup; + char_type m_cDecPoint; + char_type m_cThousandsSep; + }; +private: + /** + * @brief Typedef for the parse functions. + * + * The parse function do the actual work. The parser exchanges + * the function pointer to the parser function depending on + * which state it is in. (i.e. bytecode parser vs. string parser) + */ + typedef qreal (QmuParserBase::*ParseFunction)() const; - /** - * @brief Type used for storing an array of values. - */ - typedef QVector valbuf_type; + /** + * @brief Type used for storing an array of values. + */ + typedef QVector valbuf_type; - /** - * @brief Type for a vector of strings. - */ - typedef QVector stringbuf_type; + /** + * @brief Type for a vector of strings. + */ + typedef QVector stringbuf_type; - /** - * @brief Typedef for the token reader. - */ - typedef QmuParserTokenReader token_reader_type; + /** + * @brief Typedef for the token reader. + */ + typedef QmuParserTokenReader token_reader_type; - /** - * @brief Type used for parser tokens. - */ - typedef QmuParserToken token_type; + /** + * @brief Type used for parser tokens. + */ + typedef QmuParserToken token_type; - /** - * @brief Maximum number of threads spawned by OpenMP when using the bulk mode. - */ - static const int s_MaxNumOpenMPThreads = 4; + /** + * @brief Maximum number of threads spawned by OpenMP when using the bulk mode. + */ + static const int s_MaxNumOpenMPThreads = 4; - /** - * @brief Pointer to the parser function. - * - * Eval() calls the function whose address is stored there. - */ - mutable ParseFunction m_pParseFormula; - mutable QmuParserByteCode m_vRPN; ///< The Bytecode class. - mutable stringbuf_type m_vStringBuf; ///< String buffer, used for storing string function arguments - stringbuf_type m_vStringVarBuf; + /** + * @brief Pointer to the parser function. + * + * Eval() calls the function whose address is stored there. + */ + mutable ParseFunction m_pParseFormula; + mutable QmuParserByteCode m_vRPN; ///< The Bytecode class. + mutable stringbuf_type m_vStringBuf; ///< String buffer, used for storing string function arguments + stringbuf_type m_vStringVarBuf; - std::auto_ptr m_pTokenReader; ///< Managed pointer to the token reader object. + std::unique_ptr m_pTokenReader; ///< Managed pointer to the token reader object. - funmap_type m_FunDef; ///< Map of function names and pointers. - funmap_type m_PostOprtDef; ///< Postfix operator callbacks - funmap_type m_InfixOprtDef; ///< unary infix operator. - funmap_type m_OprtDef; ///< Binary operator callbacks - valmap_type m_ConstDef; ///< user constants. - strmap_type m_StrVarDef; ///< user defined string constants - varmap_type m_VarDef; ///< user defind variables. + funmap_type m_FunDef; ///< Map of function names and pointers. + funmap_type m_PostOprtDef; ///< Postfix operator callbacks + funmap_type m_InfixOprtDef; ///< unary infix operator. + funmap_type m_OprtDef; ///< Binary operator callbacks + valmap_type m_ConstDef; ///< user constants. + strmap_type m_StrVarDef; ///< user defined string constants + varmap_type m_VarDef; ///< user defind variables. - bool m_bBuiltInOp; ///< Flag that can be used for switching built in operators on and off + bool m_bBuiltInOp; ///< Flag that can be used for switching built in operators on and off - QString m_sNameChars; ///< Charset for names - QString m_sOprtChars; ///< Charset for postfix/ binary operator tokens - QString m_sInfixOprtChars; ///< Charset for infix operator tokens + QString m_sNameChars; ///< Charset for names + QString m_sOprtChars; ///< Charset for postfix/ binary operator tokens + QString m_sInfixOprtChars; ///< Charset for infix operator tokens - mutable int m_nIfElseCounter; ///< Internal counter for keeping track of nested if-then-else clauses + mutable int m_nIfElseCounter; ///< Internal counter for keeping track of nested if-then-else clauses - // items merely used for caching state information - mutable valbuf_type m_vStackBuffer; ///< This is merely a buffer used for the stack in the cmd parsing routine - mutable int m_nFinalResultIdx; + // items merely used for caching state information + mutable valbuf_type m_vStackBuffer; ///< This is merely a buffer used for the stack in the cmd parsing routine + mutable int m_nFinalResultIdx; - void Assign(const QmuParserBase &a_Parser); - void InitTokenReader(); - void ReInit() const; - void AddCallback(const QString &a_strName, const QmuParserCallback &a_Callback, - funmap_type &a_Storage, const QString &a_szCharSet ); - void ApplyRemainingOprt(QStack &a_stOpt, QStack &a_stVal) const; - void ApplyBinOprt(QStack &a_stOpt, QStack &a_stVal) const; - void ApplyIfElse(QStack &a_stOpt, QStack &a_stVal) const; - void ApplyFunc(QStack &a_stOpt, QStack &a_stVal, int iArgCount) const; - token_type ApplyStrFunc(const token_type &a_FunTok, const QVector &a_vArg) const; - int GetOprtPrecedence(const token_type &a_Tok) const; - EOprtAssociativity GetOprtAssociativity(const token_type &a_Tok) const; - void CreateRPN() const; - qreal ParseString() const; - qreal ParseCmdCode() const; - qreal ParseCmdCodeBulk(int nOffset, int nThreadID) const; - void CheckName(const QString &a_strName, const QString &a_CharSet) const; - void CheckOprt(const QString &a_sName, const QmuParserCallback &a_Callback, - const QString &a_szCharSet) const; - void StackDump(const QStack &a_stVal, const QStack &a_stOprt) const; - }; + void Assign(const QmuParserBase &a_Parser); + void InitTokenReader(); + void ReInit() const; + void AddCallback(const QString &a_strName, const QmuParserCallback &a_Callback, + funmap_type &a_Storage, const QString &a_szCharSet ); + void ApplyRemainingOprt(QStack &a_stOpt, QStack &a_stVal) const; + void ApplyBinOprt(QStack &a_stOpt, QStack &a_stVal) const; + void ApplyIfElse(QStack &a_stOpt, QStack &a_stVal) const; + void ApplyFunc(QStack &a_stOpt, QStack &a_stVal, int iArgCount) const; + token_type ApplyStrFunc(const token_type &a_FunTok, const QVector &a_vArg) const; + int GetOprtPrecedence(const token_type &a_Tok) const; + EOprtAssociativity GetOprtAssociativity(const token_type &a_Tok) const; + void CreateRPN() const; + qreal ParseString() const; + qreal ParseCmdCode() const; + qreal ParseCmdCodeBulk(int nOffset, int nThreadID) const; + void CheckName(const QString &a_strName, const QString &a_CharSet) const; + void CheckOprt(const QString &a_sName, const QmuParserCallback &a_Callback, + const QString &a_szCharSet) const; + void StackDump(const QStack &a_stVal, const QStack &a_stOprt) const; +}; } // namespace qmu diff --git a/src/libs/qmuparser/qmuparserbytecode.cpp b/src/libs/qmuparser/qmuparserbytecode.cpp index ea3c46a17..80e6822ea 100644 --- a/src/libs/qmuparser/qmuparserbytecode.cpp +++ b/src/libs/qmuparser/qmuparserbytecode.cpp @@ -52,6 +52,8 @@ QmuParserByteCode::QmuParserByteCode() * Implemented in Terms of Assign(const QParserByteCode &a_ByteCode) */ QmuParserByteCode::QmuParserByteCode(const QmuParserByteCode &a_ByteCode) + :m_iStackPos(a_ByteCode.m_iStackPos), m_iMaxStackSize(a_ByteCode.m_iMaxStackSize), m_vRPN(a_ByteCode.m_vRPN), + m_bEnableOptimizer(true) { Assign(a_ByteCode); } @@ -101,7 +103,7 @@ void QmuParserByteCode::Assign(const QmuParserByteCode &a_ByteCode) void QmuParserByteCode::AddVar(qreal *a_pVar) { ++m_iStackPos; - m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos); + m_iMaxStackSize = qMax(m_iMaxStackSize, static_cast(m_iStackPos)); // optimization does not apply SToken tok; @@ -129,7 +131,7 @@ void QmuParserByteCode::AddVar(qreal *a_pVar) void QmuParserByteCode::AddVal(qreal a_fVal) { ++m_iStackPos; - m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos); + m_iMaxStackSize = qMax(m_iMaxStackSize, static_cast(m_iStackPos)); // If optimization does not apply SToken tok; @@ -145,15 +147,15 @@ void QmuParserByteCode::ConstantFolding(ECmdCode a_Oprt) { std::size_t sz = m_vRPN.size(); qreal &x = m_vRPN[sz-2].Val.data2, - &y = m_vRPN[sz-1].Val.data2; + &y = m_vRPN[sz-1].Val.data2; switch (a_Oprt) { case cmLAND: - x = (int)x && (int)y; + x = static_cast(x) && static_cast(y); m_vRPN.pop_back(); break; case cmLOR: - x = (int)x || (int)y; + x = static_cast(x) || static_cast(y); m_vRPN.pop_back(); break; case cmLT: @@ -173,11 +175,11 @@ void QmuParserByteCode::ConstantFolding(ECmdCode a_Oprt) m_vRPN.pop_back(); break; case cmNEQ: - x = x != y; + x = (qFuzzyCompare(x, y) == false); m_vRPN.pop_back(); break; case cmEQ: - x = x == y; + x = qFuzzyCompare(x, y); m_vRPN.pop_back(); break; case cmADD: @@ -202,10 +204,79 @@ void QmuParserByteCode::ConstantFolding(ECmdCode a_Oprt) x = x / y; m_vRPN.pop_back(); break; - case cmPOW: - x = qPow(x, y); - m_vRPN.pop_back(); - break; + case cmPOW: + x = qPow(x, y); + m_vRPN.pop_back(); + 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 cmVAR: + Q_UNREACHABLE(); + break; + case cmVAL: + 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; default: break; } // switch opcode @@ -248,15 +319,15 @@ void QmuParserByteCode::AddOp(ECmdCode a_Oprt) // Optimization for ploynomials of low order if (m_vRPN[sz-2].Cmd == cmVAR && m_vRPN[sz-1].Cmd == cmVAL) { - if (m_vRPN[sz-1].Val.data2==2) + if (qFuzzyCompare(m_vRPN[sz-1].Val.data2, 2)) { m_vRPN[sz-2].Cmd = cmVARPOW2; } - else if (m_vRPN[sz-1].Val.data2==3) + else if (qFuzzyCompare(m_vRPN[sz-1].Val.data2, 3)) { m_vRPN[sz-2].Cmd = cmVARPOW3; } - else if (m_vRPN[sz-1].Val.data2==4) + else if (qFuzzyCompare(m_vRPN[sz-1].Val.data2, 4)) { m_vRPN[sz-2].Cmd = cmVARPOW4; } @@ -291,8 +362,9 @@ void QmuParserByteCode::AddOp(ECmdCode a_Oprt) (m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ); m_vRPN[sz-2].Cmd = cmVARMUL; - m_vRPN[sz-2].Val.ptr = (qreal*)((long long)(m_vRPN[sz-2].Val.ptr) | - (long long)(m_vRPN[sz-1].Val.ptr)); // variable + m_vRPN[sz-2].Val.ptr = reinterpret_cast( + reinterpret_cast(m_vRPN[sz-2].Val.ptr) | + reinterpret_cast(m_vRPN[sz-1].Val.ptr)); // variable m_vRPN[sz-2].Val.data2 += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].Val.data2; // offset m_vRPN[sz-2].Val.data += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].Val.data; // multiplikatior m_vRPN.pop_back(); @@ -304,8 +376,9 @@ void QmuParserByteCode::AddOp(ECmdCode a_Oprt) (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVAR) ) { m_vRPN[sz-2].Cmd = cmVARMUL; - m_vRPN[sz-2].Val.ptr = (qreal*)((long long)(m_vRPN[sz-2].Val.ptr) | - (long long)(m_vRPN[sz-1].Val.ptr)); + m_vRPN[sz-2].Val.ptr = reinterpret_cast( + reinterpret_cast(m_vRPN[sz-2].Val.ptr) | + reinterpret_cast(m_vRPN[sz-1].Val.ptr)); m_vRPN[sz-2].Val.data = m_vRPN[sz-2].Val.data2 + m_vRPN[sz-1].Val.data2; m_vRPN[sz-2].Val.data2 = 0; m_vRPN.pop_back(); @@ -316,8 +389,9 @@ void QmuParserByteCode::AddOp(ECmdCode a_Oprt) { // Optimization: 2*(3*b+1) or (3*b+1)*2 -> 6*b+2 m_vRPN[sz-2].Cmd = cmVARMUL; - m_vRPN[sz-2].Val.ptr = (qreal*)((long long)(m_vRPN[sz-2].Val.ptr) | - (long long)(m_vRPN[sz-1].Val.ptr)); + m_vRPN[sz-2].Val.ptr = reinterpret_cast( + reinterpret_cast(m_vRPN[sz-2].Val.ptr) | + reinterpret_cast(m_vRPN[sz-1].Val.ptr)); if (m_vRPN[sz-1].Cmd == cmVAL) { m_vRPN[sz-2].Val.data *= m_vRPN[sz-1].Val.data2; @@ -341,7 +415,8 @@ void QmuParserByteCode::AddOp(ECmdCode a_Oprt) } break; case cmDIV: - if (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVARMUL && m_vRPN[sz-1].Val.data2!=0) + if (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVARMUL && + (qFuzzyCompare(m_vRPN[sz-1].Val.data2+1, 1+0)==false)) { // Optimization: 4*a/2 -> 2*a m_vRPN[sz-2].Val.data /= m_vRPN[sz-1].Val.data2; @@ -350,8 +425,103 @@ void QmuParserByteCode::AddOp(ECmdCode a_Oprt) bOptimized = true; } break; + 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 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 cmVAR: + Q_UNREACHABLE(); + break; + case cmVAL: + 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; + default: + break; - } // switch a_Oprt + } // switch a_Oprt } } @@ -413,7 +583,7 @@ void QmuParserByteCode::AddFun(generic_fun_type a_pFun, int a_iArgc) // function with unlimited number of arguments m_iStackPos = m_iStackPos + a_iArgc + 1; } - m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos); + m_iMaxStackSize = qMax(m_iMaxStackSize, static_cast(m_iStackPos)); SToken tok; tok.Cmd = cmFUNC; @@ -432,7 +602,7 @@ void QmuParserByteCode::AddFun(generic_fun_type a_pFun, int a_iArgc) void QmuParserByteCode::AddBulkFun(generic_fun_type a_pFun, int a_iArgc) { m_iStackPos = m_iStackPos - a_iArgc + 1; - m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos); + m_iMaxStackSize = qMax(m_iMaxStackSize, static_cast(m_iStackPos)); SToken tok; tok.Cmd = cmFUNC_BULK; @@ -460,7 +630,7 @@ void QmuParserByteCode::AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iI tok.Fun.ptr = a_pFun; m_vRPN.push_back(tok); - m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos); + m_iMaxStackSize = qMax(m_iMaxStackSize, static_cast(m_iStackPos)); } //---------------------------------------------------------------------------------------------------------------------- @@ -479,7 +649,7 @@ void QmuParserByteCode::Finalize() // Determine the if-then-else jump offsets QStack stIf, stElse; int idx; - for (int i=0; i<(int)m_vRPN.size(); ++i) + for (int i=0; i ( a_pFun ) ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( fun_type1 a_pFun, bool a_bAllowOpti, int a_iPrec, ECmdCode a_iCode ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 1 ), m_iPri ( a_iPrec ), m_eOprtAsct ( oaNONE ), m_iCode ( a_iCode ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 1 ), m_iPri ( a_iPrec ), m_eOprtAsct ( oaNONE ), + m_iCode ( a_iCode ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} @@ -47,9 +54,12 @@ QmuParserCallback::QmuParserCallback ( fun_type1 a_pFun, bool a_bAllowOpti, int * @brief Constructor for constructing funcstion callbacks taking two arguments. * @throw nothrow */ +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( fun_type2 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- @@ -61,72 +71,105 @@ QmuParserCallback::QmuParserCallback ( fun_type2 a_pFun, bool a_bAllowOpti ) * @param a_eOprtAsct The operators associativity * @throw nothrow */ +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( fun_type2 a_pFun, bool a_bAllowOpti, int a_iPrec, EOprtAssociativity a_eOprtAsct ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 2 ), m_iPri ( a_iPrec ), m_eOprtAsct ( a_eOprtAsct ), + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 2 ), m_iPri ( a_iPrec ), m_eOprtAsct ( a_eOprtAsct ), m_iCode ( cmOPRT_BIN ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( fun_type3 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 3 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 3 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( fun_type4 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 4 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 4 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( fun_type5 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 5 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 5 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( fun_type6 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 6 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 6 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( fun_type7 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 7 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 7 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( fun_type8 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 8 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 8 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( fun_type9 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 9 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 9 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( fun_type10 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 10 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 10 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( bulkfun_type0 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( bulkfun_type1 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- @@ -134,81 +177,120 @@ QmuParserCallback::QmuParserCallback ( bulkfun_type1 a_pFun, bool a_bAllowOpti ) * @brief Constructor for constructing funcstion callbacks taking two arguments. * @throw nothrow */ +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( bulkfun_type2 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( bulkfun_type3 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 3 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 3 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( bulkfun_type4 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 4 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 4 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( bulkfun_type5 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 5 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 5 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( bulkfun_type6 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 6 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 6 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( bulkfun_type7 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 7 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 7 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( bulkfun_type8 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 8 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 8 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( bulkfun_type9 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 9 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 9 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( bulkfun_type10 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 10 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 10 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( multfun_type a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( -1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( -1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( strfun_type1 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_STR ), m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( strfun_type2 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_STR ), - m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_STR ), m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( strfun_type3 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_STR ), - m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_STR ), m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- @@ -227,6 +309,8 @@ QmuParserCallback::QmuParserCallback() * @throw nothrow */ QmuParserCallback::QmuParserCallback ( const QmuParserCallback &ref ) + : m_pFun ( ref.m_pFun ), m_iArgc ( ref.m_iArgc ), m_iPri ( ref.m_iPri ), m_eOprtAsct ( ref.m_eOprtAsct ), + m_iCode ( ref.m_iCode ), m_iType ( ref.m_iType ), m_bAllowOpti ( ref.m_bAllowOpti ) { m_pFun = ref.m_pFun; m_iArgc = ref.m_iArgc; diff --git a/src/libs/qmuparser/qmuparserdef.h b/src/libs/qmuparser/qmuparserdef.h index e7f5a4028..4edd3f390 100644 --- a/src/libs/qmuparser/qmuparserdef.h +++ b/src/libs/qmuparser/qmuparserdef.h @@ -44,7 +44,7 @@ OpenMP is used only in the bulk mode it may increase the performance a bit. */ -//#define MUP_USE_OPENMP +//#define QMUP_USE_OPENMP #if defined(_UNICODE) /** @brief Definition of the basic parser string type. */ diff --git a/src/libs/qmuparser/qmuparsererror.cpp b/src/libs/qmuparser/qmuparsererror.cpp index 571ae7241..543d60d9f 100644 --- a/src/libs/qmuparser/qmuparsererror.cpp +++ b/src/libs/qmuparser/qmuparsererror.cpp @@ -37,27 +37,13 @@ const QmuParserErrorMsg& QmuParserErrorMsg::Instance() //---------------------------------------------------------------------------------------------------------------------- QString QmuParserErrorMsg::operator[] ( unsigned a_iIdx ) const { - return ( a_iIdx < m_vErrMsg.size() ) ? m_vErrMsg[a_iIdx] : QString(); + return ( a_iIdx < static_cast( m_vErrMsg.size() ) ) ? m_vErrMsg[a_iIdx] : QString(); } //---------------------------------------------------------------------------------------------------------------------- QmuParserErrorMsg::~QmuParserErrorMsg() {} -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Assignement operator is deactivated. - */ -QmuParserErrorMsg& QmuParserErrorMsg::operator= ( const QmuParserErrorMsg& ) -{ - assert ( false ); - return *this; -} - -//---------------------------------------------------------------------------------------------------------------------- -QmuParserErrorMsg::QmuParserErrorMsg ( const QmuParserErrorMsg& ) -{} - //---------------------------------------------------------------------------------------------------------------------- QmuParserErrorMsg::QmuParserErrorMsg() : m_vErrMsg ( 0 ) @@ -147,11 +133,9 @@ QmuParserError::QmuParserError ( EErrorCodes a_iErrc ) * @brief Construct an error from a message text. */ QmuParserError::QmuParserError ( const QString &sMsg ) - : m_ErrMsg ( QmuParserErrorMsg::Instance() ) -{ - Reset(); - m_strMsg = sMsg; -} + : m_strMsg(sMsg), m_strFormula(), m_strTok(), m_iPos ( -1 ), m_iErrc ( ecUNDEFINED ), + m_ErrMsg ( QmuParserErrorMsg::Instance() ) +{} //---------------------------------------------------------------------------------------------------------------------- /** @@ -264,9 +248,9 @@ void QmuParserError::ReplaceSubString ( QString &strSource, const QString &strFi */ void QmuParserError::Reset() { - m_strMsg = ""; - m_strFormula = ""; - m_strTok = ""; + m_strMsg.clear(); + m_strFormula.clear(); + m_strTok.clear(); m_iPos = -1; m_iErrc = ecUNDEFINED; } diff --git a/src/libs/qmuparser/qmuparsererror.h b/src/libs/qmuparser/qmuparsererror.h index dd7592fc0..0ed154df6 100644 --- a/src/libs/qmuparser/qmuparsererror.h +++ b/src/libs/qmuparser/qmuparsererror.h @@ -99,8 +99,6 @@ class QmuParserErrorMsg public: typedef QmuParserErrorMsg self_type; - QmuParserErrorMsg& operator= ( const QmuParserErrorMsg & ); - QmuParserErrorMsg ( const QmuParserErrorMsg& ); QmuParserErrorMsg(); ~QmuParserErrorMsg(); @@ -108,6 +106,7 @@ public: QString operator[] ( unsigned a_iIdx ) const; private: + Q_DISABLE_COPY(QmuParserErrorMsg) QVector m_vErrMsg; ///< A vector with the predefined error messages static const self_type m_Instance; ///< The instance pointer }; diff --git a/src/libs/qmuparser/qmuparsertest.cpp b/src/libs/qmuparser/qmuparsertest.cpp index a5ed854a3..fa6fcb4b1 100644 --- a/src/libs/qmuparser/qmuparsertest.cpp +++ b/src/libs/qmuparser/qmuparsertest.cpp @@ -81,8 +81,8 @@ int QmuParserTester::IsHexVal ( const QString &a_szExpr, int *a_iPos, qreal *a_f return 1; } - *a_iPos += ( int ) ( 2 + nPos ); - *a_fVal = ( qreal ) iVal; + *a_iPos += 2 + nPos; + *a_fVal = static_cast(iVal); return 1; } else @@ -460,7 +460,7 @@ int QmuParserTester::TestVarConst() // 4 used variables p.SetExpr ( "a+b+c+d" ); qmu::varmap_type UsedVar = p.GetUsedVar(); - int iCount = ( int ) UsedVar.size(); + int iCount = static_cast(UsedVar.size()); if ( iCount != 4 ) { throw false; @@ -485,7 +485,7 @@ int QmuParserTester::TestVarConst() // Test lookup of undefined variables p.SetExpr ( "undef1+undef2+undef3" ); UsedVar = p.GetUsedVar(); - iCount = ( int ) UsedVar.size(); + iCount = static_cast(UsedVar.size()); if ( iCount != 3 ) { throw false; @@ -509,7 +509,7 @@ int QmuParserTester::TestVarConst() // 1 used variables p.SetExpr ( "a+b" ); UsedVar = p.GetUsedVar(); - iCount = ( int ) UsedVar.size(); + iCount = static_cast(UsedVar.size()); if ( iCount != 2 ) { throw false; @@ -1072,7 +1072,7 @@ void QmuParserTester::Run() int iStat = 0; try { - for ( int i = 0; i < ( int ) m_vTestFun.size(); ++i ) + for ( int i = 0; i < m_vTestFun.size(); ++i ) { iStat += ( this->*m_vTestFun[i] ) (); } @@ -1227,7 +1227,7 @@ int QmuParserTester::EqnTest ( const QString &a_str, double a_fRes, bool a_fPass try { - std::auto_ptr p1; + std::unique_ptr p1; QmuParser p2, p3; // three parser objects // they will be used for testing copy and assihnment operators // p1 is a pointer since i'm going to delete it in order to test if @@ -1306,7 +1306,7 @@ int QmuParserTester::EqnTest ( const QString &a_str, double a_fRes, bool a_fPass // String parsing and bytecode parsing must yield the same result fVal[0] = p1->Eval(); // result from stringparsing fVal[1] = p1->Eval(); // result from bytecode - if ( fVal[0] != fVal[1] ) + if ( qFuzzyCompare( fVal[0], fVal[1] ) == false ) { throw QmuParser::exception_type ( "Bytecode / string parsing mismatch." ); } @@ -1354,7 +1354,7 @@ int QmuParserTester::EqnTest ( const QString &a_str, double a_fRes, bool a_fPass // http://sourceforge.net/projects/muparser/forums/forum/462843/topic/5037825 if ( numeric_limits::has_infinity ) { - bCloseEnough &= ( fabs ( fVal[i] ) != numeric_limits::infinity() ); + bCloseEnough &= (qFuzzyCompare( fabs ( fVal[i] ), numeric_limits::infinity())==false ); } } @@ -1376,7 +1376,8 @@ int QmuParserTester::EqnTest ( const QString &a_str, double a_fRes, bool a_fPass { if ( a_fPass ) { - if ( fVal[0] != fVal[2] && fVal[0] != -999 && fVal[1] != -998 ) + if ( (qFuzzyCompare(fVal[0], fVal[2])==false) && (qFuzzyCompare(fVal[0], -999)==false) && + (qFuzzyCompare(fVal[1], -998 )==false)) { qDebug() << "\n fail: " << a_str << " (copy construction)"; } @@ -1405,7 +1406,7 @@ int QmuParserTester::EqnTest ( const QString &a_str, double a_fRes, bool a_fPass /** * @brief Internal error in test class Test is going to be aborted. */ -void QmuParserTester::Abort() const +void Q_NORETURN QmuParserTester::Abort() const { qDebug() << "Test failed (internal error in test class)" ; while ( !getchar() ); diff --git a/src/libs/qmuparser/qmuparsertest.h b/src/libs/qmuparser/qmuparsertest.h index 560b94420..aaf5ab48d 100644 --- a/src/libs/qmuparser/qmuparsertest.h +++ b/src/libs/qmuparser/qmuparsertest.h @@ -178,7 +178,7 @@ private: static qreal land ( qreal v1, qreal v2 ) { - return ( int ) v1 & ( int ) v2; + return static_cast( v1 ) & static_cast( v2 ); } static qreal FirstArg ( const qreal* a_afArg, int a_iArgc ) @@ -218,12 +218,12 @@ private: static qreal Rnd ( qreal v ) { - return ( qreal ) ( 1 + ( v * std::rand() / ( RAND_MAX + 1.0 ) ) ); + return static_cast( ( 1 + ( v * qrand() / ( RAND_MAX + 1.0 ) ) ) ); } static qreal RndWithString ( const char_type* ) { - return ( qreal ) ( 1 + ( 1000.0f * std::rand() / ( RAND_MAX + 1.0 ) ) ); + return static_cast( ( 1 + ( 1000.0f * static_cast(qrand()) / ( RAND_MAX + 1.0 ) ) ) ); } static qreal Ping() @@ -239,13 +239,13 @@ private: static qreal StrFun1 ( const QString & v1 ) { int val = v1.toInt(); - return ( qreal ) val; + return static_cast(val); } static qreal StrFun2 ( const QString & v1, qreal v2 ) { int val = v1.toInt(); - return ( qreal ) ( val + v2 ); + return static_cast( val + v2 ); } static qreal StrFun3 ( const QString & v1, qreal v2, qreal v3 ) @@ -263,17 +263,17 @@ private: // postfix operator callback static qreal Mega ( qreal a_fVal ) { - return a_fVal * ( qreal ) 1e6; + return a_fVal * static_cast( 1e6 ); } static qreal Micro ( qreal a_fVal ) { - return a_fVal * ( qreal ) 1e-6; + return a_fVal * static_cast( 1e-6 ); } static qreal Milli ( qreal a_fVal ) { - return a_fVal / ( qreal ) 1e3; + return a_fVal / static_cast( 1e3 ); } // Custom value recognition diff --git a/src/libs/qmuparser/qmuparsertoken.h b/src/libs/qmuparser/qmuparsertoken.h index f2f481c6a..a1ef34a13 100644 --- a/src/libs/qmuparser/qmuparsertoken.h +++ b/src/libs/qmuparser/qmuparsertoken.h @@ -1,396 +1,517 @@ -/*************************************************************************************************** - ** - ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhynskyi - ** - ** Permission is hereby granted, free of charge, to any person obtaining a copy of this - ** software and associated documentation files (the "Software"), to deal in the Software - ** without restriction, including without limitation the rights to use, copy, modify, - ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to - ** permit persons to whom the Software is furnished to do so, subject to the following conditions: - ** - ** The above copyright notice and this permission notice shall be included in all copies or - ** substantial portions of the Software. - ** - ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT - ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ** - ******************************************************************************************************/ - -#ifndef QMUPARSERTOKEN_H -#define QMUPARSERTOKEN_H - -#include -#include -#include -#include -#include - -#include "qmuparsererror.h" -#include "qmuparsercallback.h" - -/** @file - @brief This file contains the parser token definition. -*/ - -namespace qmu -{ - /** @brief Encapsulation of the data for a single formula token. - - Formula token implementation. Part of the Math Parser Package. - Formula tokens can be either one of the following: -
    -
  • value
  • -
  • variable
  • -
  • function with numerical arguments
  • -
  • functions with a string as argument
  • -
  • prefix operators
  • -
  • infix operators
  • -
  • binary operator
  • -
- - @author (C) 2004-2013 Ingo Berg - */ - template - class QmuParserToken - { - private: - - ECmdCode m_iCode; ///< Type of the token; The token type is a constant of type #ECmdCode. - ETypeCode m_iType; - void *m_pTok; ///< Stores Token pointer; not applicable for all tokens - int m_iIdx; ///< An otional index to an external buffer storing the token data - TString m_strTok; ///< Token string - TString m_strVal; ///< Value for string variables - qreal m_fVal; ///< the value - std::auto_ptr m_pCallback; - - public: - - //--------------------------------------------------------------------------- - /** @brief Constructor (default). - - Sets token to an neutral state of type cmUNKNOWN. - @throw nothrow - @sa ECmdCode - */ - QmuParserToken() - :m_iCode(cmUNKNOWN) - ,m_iType(tpVOID) - ,m_pTok(0) - ,m_iIdx(-1) - ,m_strTok() - ,m_pCallback() - {} - - //------------------------------------------------------------------------------ - /** @brief Create token from another one. - - Implemented by calling Assign(...) - @throw nothrow - @post m_iType==cmUNKNOWN - @sa #Assign - */ - QmuParserToken(const QmuParserToken &a_Tok) - { - Assign(a_Tok); - } - - //------------------------------------------------------------------------------ - /** @brief Assignement operator. - - Copy token state from another token and return this. - Implemented by calling Assign(...). - @throw nothrow - */ - QmuParserToken& operator=(const QmuParserToken &a_Tok) - { - Assign(a_Tok); - return *this; - } - - //------------------------------------------------------------------------------ - /** @brief Copy token information from argument. - - @throw nothrow - */ - void Assign(const QmuParserToken &a_Tok) - { - m_iCode = a_Tok.m_iCode; - m_pTok = a_Tok.m_pTok; - m_strTok = a_Tok.m_strTok; - m_iIdx = a_Tok.m_iIdx; - m_strVal = a_Tok.m_strVal; - m_iType = a_Tok.m_iType; - m_fVal = a_Tok.m_fVal; - // create new callback object if a_Tok has one - m_pCallback.reset(a_Tok.m_pCallback.get() ? a_Tok.m_pCallback->Clone() : 0); - } - - //------------------------------------------------------------------------------ - /** @brief Assign a token type. - - Token may not be of type value, variable or function. Those have seperate set functions. - - \pre [assert] a_iType!=cmVAR - \pre [assert] a_iType!=cmVAL - \pre [assert] a_iType!=cmFUNC - @post m_fVal = 0 - @post m_pTok = 0 - */ - QmuParserToken& Set(ECmdCode a_iType, const TString &a_strTok=TString()) - { - // The following types cant be set this way, they have special Set functions - assert(a_iType!=cmVAR); - assert(a_iType!=cmVAL); - assert(a_iType!=cmFUNC); - - m_iCode = a_iType; - m_iType = tpVOID; - m_pTok = 0; - m_strTok = a_strTok; - m_iIdx = -1; - - return *this; - } - - //------------------------------------------------------------------------------ - /** @brief Set Callback type. */ - QmuParserToken& Set(const QmuParserCallback &a_pCallback, const TString &a_sTok) - { - assert(a_pCallback.GetAddr()); - - m_iCode = a_pCallback.GetCode(); - m_iType = tpVOID; - m_strTok = a_sTok; - m_pCallback.reset(new QmuParserCallback(a_pCallback)); - - m_pTok = 0; - m_iIdx = -1; - - return *this; - } - - //------------------------------------------------------------------------------ - /** @brief Make this token a value token. - - Member variables not necessary for value tokens will be invalidated. - @throw nothrow - */ - QmuParserToken& SetVal(TBase a_fVal, const TString &a_strTok=TString()) - { - m_iCode = cmVAL; - m_iType = tpDBL; - m_fVal = a_fVal; - m_strTok = a_strTok; - m_iIdx = -1; - - m_pTok = 0; - m_pCallback.reset(0); - - return *this; - } - - //------------------------------------------------------------------------------ - /** @brief make this token a variable token. - - Member variables not necessary for variable tokens will be invalidated. - @throw nothrow - */ - QmuParserToken& SetVar(TBase *a_pVar, const TString &a_strTok) - { - m_iCode = cmVAR; - m_iType = tpDBL; - m_strTok = a_strTok; - m_iIdx = -1; - m_pTok = (void*)a_pVar; - m_pCallback.reset(0); - return *this; - } - - //------------------------------------------------------------------------------ - /** @brief Make this token a variable token. - - Member variables not necessary for variable tokens will be invalidated. - @throw nothrow - */ - QmuParserToken& SetString(const TString &a_strTok, std::size_t a_iSize) - { - m_iCode = cmSTRING; - m_iType = tpSTR; - m_strTok = a_strTok; - m_iIdx = static_cast(a_iSize); - - m_pTok = 0; - m_pCallback.reset(0); - return *this; - } - - //------------------------------------------------------------------------------ - /** @brief Set an index associated with the token related data. - - 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 - */ - void SetIdx(int a_iIdx) - { - if (m_iCode!=cmSTRING || a_iIdx<0) - throw QmuParserError(ecINTERNAL_ERROR); - - m_iIdx = a_iIdx; - } - - //------------------------------------------------------------------------------ - /** @brief Return Index associated with the token related data. - - 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 - * @return The index the result will take in the Bytecode calculatin array (#m_iIdx). - */ - int GetIdx() const - { - if (m_iIdx<0 || m_iCode!=cmSTRING ) - throw QmuParserError(ecINTERNAL_ERROR); - - return m_iIdx; - } - - //------------------------------------------------------------------------------ - /** @brief Return the token type. - - * @return #m_iType - @throw nothrow - */ - ECmdCode GetCode() const - { - if (m_pCallback.get()) - { - return m_pCallback->GetCode(); - } - else - { - return m_iCode; - } - } - - //------------------------------------------------------------------------------ - ETypeCode GetType() const - { - if (m_pCallback.get()) - { - return m_pCallback->GetType(); - } - else - { - return m_iType; - } - } - - //------------------------------------------------------------------------------ - int GetPri() const - { - if ( !m_pCallback.get()) - throw QmuParserError(ecINTERNAL_ERROR); - - if ( m_pCallback->GetCode()!=cmOPRT_BIN && m_pCallback->GetCode()!=cmOPRT_INFIX) - throw QmuParserError(ecINTERNAL_ERROR); - - return m_pCallback->GetPri(); - } - - //------------------------------------------------------------------------------ - EOprtAssociativity GetAssociativity() const - { - if (m_pCallback.get()==NULL || m_pCallback->GetCode()!=cmOPRT_BIN) - throw QmuParserError(ecINTERNAL_ERROR); - - return m_pCallback->GetAssociativity(); - } - - //------------------------------------------------------------------------------ - /** @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: -
    -
  • cmFUNC
  • -
  • cmSTRFUNC
  • -
  • cmPOSTOP
  • -
  • cmINFIXOP
  • -
  • cmOPRT_BIN
  • -
- @sa ECmdCode - */ - generic_fun_type GetFuncAddr() const - { - return (m_pCallback.get()) ? (generic_fun_type)m_pCallback->GetAddr() : 0; - } - - //------------------------------------------------------------------------------ - /** \biref Get value of the token. - - Only applicable to variable and value tokens. - @throw exception_type if token is no value/variable token. - */ - TBase GetVal() const - { - switch (m_iCode) - { - case cmVAL: return m_fVal; - case cmVAR: return *((TBase*)m_pTok); - default: throw QmuParserError(ecVAL_EXPECTED); - } - } - - //------------------------------------------------------------------------------ - /** @brief Get address of a variable token. - - Valid only if m_iType==CmdVar. - @throw exception_type if token is no variable token. - */ - TBase* GetVar() const - { - if (m_iCode!=cmVAR) - throw QmuParserError(ecINTERNAL_ERROR); - - return (TBase*)m_pTok; - } - - //------------------------------------------------------------------------------ - /** @brief Return the number of function arguments. - - Valid only if m_iType==CmdFUNC. - */ - int GetArgCount() const - { - assert(m_pCallback.get()); - - if (!m_pCallback->GetAddr()) - throw QmuParserError(ecINTERNAL_ERROR); - - return m_pCallback->GetArgc(); - } - - //------------------------------------------------------------------------------ - /** @brief Return the token identifier. - - If #m_iType is cmSTRING the token identifier is the value of the string argument - for a string function. - * @return #m_strTok - @throw nothrow - @sa m_strTok - */ - const TString& GetAsString() const - { - return m_strTok; - } - }; -} // namespace qmu - -#endif +/*************************************************************************************************** + ** + ** Original work Copyright (C) 2013 Ingo Berg + ** Modified work Copyright 2014 Roman Telezhynskyi + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#ifndef QMUPARSERTOKEN_H +#define QMUPARSERTOKEN_H + +#include +#include +#include +#include +#include + +#include "qmuparsererror.h" +#include "qmuparsercallback.h" + +/** @file + @brief This file contains the parser token definition. +*/ + +namespace qmu +{ +/** + * @brief Encapsulation of the data for a single formula token. + * + * Formula token implementation. Part of the Math Parser Package. + * Formula tokens can be either one of the following: + *
    + *
  • value
  • + *
  • variable
  • + *
  • function with numerical arguments
  • + *
  • functions with a string as argument
  • + *
  • prefix operators
  • + *
  • infix operators
  • + *
  • binary operator
  • + *
+ * + * @author (C) 2004-2013 Ingo Berg + */ +template +class QmuParserToken +{ +public: + //--------------------------------------------------------------------------- + /** + * @brief Constructor (default). + * + * Sets token to an neutral state of type cmUNKNOWN. + * @throw nothrow + * @sa ECmdCode + */ + QmuParserToken() + : m_iCode ( cmUNKNOWN ), m_iType ( tpVOID ), m_pTok ( 0 ), m_iIdx ( -1 ), m_strTok(), m_strVal(), m_fVal(), + m_pCallback() + {} + + //------------------------------------------------------------------------------ + /** + * @brief Create token from another one. + * + * Implemented by calling Assign(...) + * @throw nothrow + * @post m_iType==cmUNKNOWN + * @sa #Assign + */ + QmuParserToken ( const QmuParserToken &a_Tok ) + : m_iCode ( a_Tok.m_iCode ), m_iType ( a_Tok.m_iType ), m_pTok ( a_Tok.m_pTok ), m_iIdx ( a_Tok.m_iIdx ), + m_strTok( a_Tok.m_strTok ), m_strVal(a_Tok.m_strVal), m_fVal(a_Tok.m_fVal), m_pCallback() + { + Assign ( a_Tok ); + } + + //------------------------------------------------------------------------------ + /** + * @brief Assignement operator. + * + * Copy token state from another token and return this. + * Implemented by calling Assign(...). + * @throw nothrow + */ + QmuParserToken& operator= ( const QmuParserToken &a_Tok ) + { + Assign ( a_Tok ); + return *this; + } + + //------------------------------------------------------------------------------ + /** + * @brief Copy token information from argument. + * + * @throw nothrow + */ + void Assign ( const QmuParserToken &a_Tok ) + { + m_iCode = a_Tok.m_iCode; + m_pTok = a_Tok.m_pTok; + m_strTok = a_Tok.m_strTok; + m_iIdx = a_Tok.m_iIdx; + m_strVal = a_Tok.m_strVal; + m_iType = a_Tok.m_iType; + m_fVal = a_Tok.m_fVal; + // create new callback object if a_Tok has one + m_pCallback.reset ( a_Tok.m_pCallback.get() ? a_Tok.m_pCallback->Clone() : 0 ); + } + + //------------------------------------------------------------------------------ + /** + * @brief Assign a token type. + * + * Token may not be of type value, variable or function. Those have seperate set functions. + * + * @pre [assert] a_iType!=cmVAR + * @pre [assert] a_iType!=cmVAL + * @pre [assert] a_iType!=cmFUNC + * @post m_fVal = 0 + * @post m_pTok = 0 + */ + QmuParserToken& Set ( ECmdCode a_iType, const TString &a_strTok = TString() ) + { + // The following types cant be set this way, they have special Set functions + assert ( a_iType != cmVAR ); + assert ( a_iType != cmVAL ); + assert ( a_iType != cmFUNC ); + + m_iCode = a_iType; + m_iType = tpVOID; + m_pTok = 0; + m_strTok = a_strTok; + m_iIdx = -1; + + return *this; + } + + //------------------------------------------------------------------------------ + /** + * @brief Set Callback type. + */ + QmuParserToken& Set ( const QmuParserCallback &a_pCallback, const TString &a_sTok ) + { + assert ( a_pCallback.GetAddr() ); + + m_iCode = a_pCallback.GetCode(); + m_iType = tpVOID; + m_strTok = a_sTok; + m_pCallback.reset ( new QmuParserCallback ( a_pCallback ) ); + + m_pTok = 0; + m_iIdx = -1; + + return *this; + } + + //------------------------------------------------------------------------------ + /** + * @brief Make this token a value token. + * + * Member variables not necessary for value tokens will be invalidated. + * @throw nothrow + */ + QmuParserToken& SetVal ( TBase a_fVal, const TString &a_strTok = TString() ) + { + m_iCode = cmVAL; + m_iType = tpDBL; + m_fVal = a_fVal; + m_strTok = a_strTok; + m_iIdx = -1; + + m_pTok = 0; + m_pCallback.reset ( 0 ); + + return *this; + } + + //------------------------------------------------------------------------------ + /** + * @brief make this token a variable token. + * + * Member variables not necessary for variable tokens will be invalidated. + * @throw nothrow + */ + QmuParserToken& SetVar ( TBase *a_pVar, const TString &a_strTok ) + { + m_iCode = cmVAR; + m_iType = tpDBL; + m_strTok = a_strTok; + m_iIdx = -1; + m_pTok = reinterpret_cast ( a_pVar ); + m_pCallback.reset ( 0 ); + return *this; + } + + //------------------------------------------------------------------------------ + /** + * @brief Make this token a variable token. + * + * Member variables not necessary for variable tokens will be invalidated. + * @throw nothrow + */ + QmuParserToken& SetString ( const TString &a_strTok, std::size_t a_iSize ) + { + m_iCode = cmSTRING; + m_iType = tpSTR; + m_strTok = a_strTok; + m_iIdx = static_cast ( a_iSize ); + + m_pTok = 0; + m_pCallback.reset ( 0 ); + return *this; + } + + //------------------------------------------------------------------------------ + /** + * @brief Set an index associated with the token related data. + * + * 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 + */ + void SetIdx ( int a_iIdx ) + { + if ( m_iCode != cmSTRING || a_iIdx < 0 ) + throw QmuParserError ( ecINTERNAL_ERROR ); + + m_iIdx = a_iIdx; + } + + //------------------------------------------------------------------------------ + /** + * @brief Return Index associated with the token related data. + * + * 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 + * @return The index the result will take in the Bytecode calculatin array (#m_iIdx). + */ + int GetIdx() const + { + if ( m_iIdx < 0 || m_iCode != cmSTRING ) + throw QmuParserError ( ecINTERNAL_ERROR ); + + return m_iIdx; + } + + //------------------------------------------------------------------------------ + /** + * @brief Return the token type. + * + * @return #m_iType + * @throw nothrow + */ + ECmdCode GetCode() const + { + if ( m_pCallback.get() ) + { + return m_pCallback->GetCode(); + } + else + { + return m_iCode; + } + } + + //------------------------------------------------------------------------------ + ETypeCode GetType() const + { + if ( m_pCallback.get() ) + { + return m_pCallback->GetType(); + } + else + { + return m_iType; + } + } + + //------------------------------------------------------------------------------ + int GetPri() const + { + if ( !m_pCallback.get() ) + throw QmuParserError ( ecINTERNAL_ERROR ); + + if ( m_pCallback->GetCode() != cmOPRT_BIN && m_pCallback->GetCode() != cmOPRT_INFIX ) + throw QmuParserError ( ecINTERNAL_ERROR ); + + return m_pCallback->GetPri(); + } + + //------------------------------------------------------------------------------ + EOprtAssociativity GetAssociativity() const + { + if ( m_pCallback.get() == NULL || m_pCallback->GetCode() != cmOPRT_BIN ) + throw QmuParserError ( ecINTERNAL_ERROR ); + + return m_pCallback->GetAssociativity(); + } + + //------------------------------------------------------------------------------ + /** + * @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: + *
    + *
  • cmFUNC
  • + *
  • cmSTRFUNC
  • + *
  • cmPOSTOP
  • + *
  • cmINFIXOP
  • + *
  • cmOPRT_BIN
  • + *
+ * @sa ECmdCode + */ + generic_fun_type GetFuncAddr() const + { + return ( m_pCallback.get() ) ? reinterpret_cast ( m_pCallback->GetAddr() ) : + reinterpret_cast (0); + } + + //------------------------------------------------------------------------------ + /** + * @brief Get value of the token. + * + * Only applicable to variable and value tokens. + * @throw exception_type if token is no value/variable token. + */ + TBase GetVal() const + { + switch ( m_iCode ) + { + case cmVAL: + return m_fVal; + 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; + default: + throw QmuParserError ( ecVAL_EXPECTED ); + } + } + + //------------------------------------------------------------------------------ + /** + * @brief Get address of a variable token. + * + * Valid only if m_iType==CmdVar. + * @throw exception_type if token is no variable token. + */ + TBase* GetVar() const + { + if ( m_iCode != cmVAR ) + { + throw QmuParserError ( ecINTERNAL_ERROR ); + } + + return reinterpret_cast( m_pTok ); + } + + //------------------------------------------------------------------------------ + /** + * @brief Return the number of function arguments. + * + * Valid only if m_iType==CmdFUNC. + */ + int GetArgCount() const + { + assert ( m_pCallback.get() ); + + if ( !m_pCallback->GetAddr() ) + throw QmuParserError ( ecINTERNAL_ERROR ); + + return m_pCallback->GetArgc(); + } + + //------------------------------------------------------------------------------ + /** + * @brief Return the token identifier. + * + * If #m_iType is cmSTRING the token identifier is the value of the string argument + * for a string function. + * @return #m_strTok + * @throw nothrow + * @sa m_strTok + */ + const TString& GetAsString() const + { + return m_strTok; + } +private: + ECmdCode m_iCode; ///< Type of the token; The token type is a constant of type #ECmdCode. + ETypeCode m_iType; + void *m_pTok; ///< Stores Token pointer; not applicable for all tokens + int m_iIdx; ///< An otional index to an external buffer storing the token data + TString m_strTok; ///< Token string + TString m_strVal; ///< Value for string variables + qreal m_fVal; ///< the value + std::unique_ptr m_pCallback; +}; +} // namespace qmu + +#endif diff --git a/src/libs/qmuparser/qmuparsertokenreader.cpp b/src/libs/qmuparser/qmuparsertokenreader.cpp index a87f87548..6ba7a541d 100644 --- a/src/libs/qmuparser/qmuparsertokenreader.cpp +++ b/src/libs/qmuparser/qmuparsertokenreader.cpp @@ -44,9 +44,15 @@ class QmuParserBase; * @throw nothrow */ QmuParserTokenReader::QmuParserTokenReader ( const QmuParserTokenReader &a_Reader ) -{ - Assign ( a_Reader ); -} + :m_pParser( a_Reader.m_pParser ), m_strFormula( a_Reader.m_strFormula ), m_iPos( a_Reader.m_iPos ), + m_iSynFlags( a_Reader.m_iSynFlags ), m_bIgnoreUndefVar( a_Reader.m_bIgnoreUndefVar ), + m_pFunDef( a_Reader.m_pFunDef ), m_pPostOprtDef( a_Reader.m_pPostOprtDef ), + m_pInfixOprtDef( a_Reader.m_pInfixOprtDef ), m_pOprtDef( a_Reader.m_pOprtDef), + m_pConstDef( a_Reader.m_pConstDef ), m_pStrVarDef( a_Reader.m_pStrVarDef ), m_pVarDef( a_Reader.m_pVarDef ), + m_pFactory( a_Reader.m_pFactory ), m_pFactoryData( a_Reader.m_pFactoryData ), m_vIdentFun( a_Reader.m_vIdentFun ), + m_UsedVar( a_Reader.m_UsedVar ), m_fZero(0), m_iBrackets( a_Reader.m_iBrackets ), m_lastTok(), + m_cArgSep( a_Reader.m_cArgSep ) +{} //---------------------------------------------------------------------------------------------------------------------- /** @@ -128,7 +134,7 @@ QmuParserTokenReader::QmuParserTokenReader ( QmuParserBase *a_pParent ) */ QmuParserTokenReader* QmuParserTokenReader::Clone ( QmuParserBase *a_pParent ) const { - std::auto_ptr ptr ( new QmuParserTokenReader ( *this ) ); + std::unique_ptr ptr ( new QmuParserTokenReader ( *this ) ); ptr->SetParent ( a_pParent ); return ptr.release(); } @@ -330,11 +336,11 @@ int QmuParserTokenReader::ExtractToken ( const QString &a_szCharSet, QString &a_ const std::string a_szCharSetStd = a_szCharSet.toStdString(); #endif - int iEnd = ( int ) m_strFormulaStd.find_first_not_of ( a_szCharSetStd, a_iPos ); + int iEnd = static_cast(m_strFormulaStd.find_first_not_of ( a_szCharSetStd, a_iPos )); - if ( iEnd == ( int ) string_type::npos ) + if ( iEnd == static_cast(string_type::npos) ) { - iEnd = ( int ) m_strFormulaStd.length(); + iEnd = static_cast(m_strFormulaStd.length()); } // Assign token string if there was something found @@ -367,10 +373,10 @@ int QmuParserTokenReader::ExtractOperatorToken ( QString &a_sTok, int a_iPos ) c 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 ) + int iEnd = static_cast( m_strFormulaStd.find_first_not_of ( oprtCharsStd, a_iPos ) ); + if ( iEnd == static_cast( string_type::npos ) ) { - iEnd = ( int ) m_strFormulaStd.length(); + iEnd = static_cast( m_strFormulaStd.length() ); } // Assign token string if there was something found @@ -492,7 +498,7 @@ bool QmuParserTokenReader::IsBuiltIn ( token_type &a_Tok ) } // switch operator id m_iPos += len; - a_Tok.Set ( ( ECmdCode ) i, pOprtDef.at ( i ) ); + a_Tok.Set ( static_cast(i), pOprtDef.at ( i ) ); return true; } // if operator string found } // end of for all operator strings @@ -578,7 +584,7 @@ bool QmuParserTokenReader::IsInfixOpTok ( token_type &a_Tok ) continue; a_Tok.Set ( it->second, it->first ); - m_iPos += ( int ) it->first.length(); + m_iPos += static_cast(it->first.length()); if ( m_iSynFlags & noINFIXOP ) Error ( ecUNEXPECTED_OPERATOR, m_iPos, a_Tok.GetAsString() ); @@ -628,7 +634,7 @@ bool QmuParserTokenReader::IsFunTok ( token_type &a_Tok ) m_iPos = iEnd; if ( m_iSynFlags & noFUN ) - Error ( ecUNEXPECTED_FUN, m_iPos - ( int ) a_Tok.GetAsString().length(), a_Tok.GetAsString() ); + Error ( ecUNEXPECTED_FUN, m_iPos - static_cast(a_Tok.GetAsString().length()), a_Tok.GetAsString() ); m_iSynFlags = noANY ^ noBO; return true; @@ -690,7 +696,7 @@ bool QmuParserTokenReader::IsOprt ( token_type &a_Tok ) } - m_iPos += ( int ) sID.length(); + m_iPos += sID.length(); m_iSynFlags = noBC | noOPT | noARG_SEP | noPOSTOP | noEND | noBC | noASSIGN; return true; } @@ -828,7 +834,7 @@ bool QmuParserTokenReader::IsVarTok ( token_type &a_Tok ) if ( m_iSynFlags & noVAR ) Error ( ecUNEXPECTED_VAR, m_iPos, strTok ); - m_pParser->OnDetectVar ( &m_strFormula, m_iPos, iEnd ); + m_pParser->OnDetectVar ( m_strFormula, m_iPos, iEnd ); m_iPos = iEnd; a_Tok.SetVar ( item->second, strTok ); @@ -893,7 +899,7 @@ bool QmuParserTokenReader::IsUndefVarTok ( token_type &a_Tok ) // token identifier. // related bug report: // http://sourceforge.net/tracker/index.php?func=detail&aid=1578779&group_id=137191&atid=737979 - Error ( ecUNEXPECTED_VAR, m_iPos - ( int ) a_Tok.GetAsString().length(), strTok ); + Error ( ecUNEXPECTED_VAR, m_iPos - a_Tok.GetAsString().length(), strTok ); } // If a factory is available implicitely create new variables @@ -913,7 +919,7 @@ bool QmuParserTokenReader::IsUndefVarTok ( token_type &a_Tok ) } else { - a_Tok.SetVar ( ( qreal* ) &m_fZero, strTok ); + a_Tok.SetVar ( &m_fZero, strTok ); m_UsedVar[strTok] = 0; // Add variable to used-var-list } @@ -960,7 +966,7 @@ bool QmuParserTokenReader::IsString ( token_type &a_Tok ) 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 + iSkip; // +2 wg Anfhrungszeichen; +iSkip fr entfernte escape zeichen + m_iPos += strTok.length() + 2 + iSkip; // +2 wg Anfhrungszeichen; +iSkip fr entfernte escape zeichen m_iSynFlags = noANY ^ ( noARG_SEP | noBC | noOPT | noEND ); return true;