Save all variable in dynamic array.

--HG--
branch : feature
This commit is contained in:
dismine 2014-05-21 16:51:47 +03:00
parent e4ab794211
commit 5adc0555ef
10 changed files with 147 additions and 93 deletions

View file

@ -36,7 +36,7 @@
* @param data pointer to a variable container. * @param data pointer to a variable container.
*/ */
Calculator::Calculator(const VContainer *data) Calculator::Calculator(const VContainer *data)
:QmuParser() :QmuParser(), vVarVal(nullptr)
{ {
//String with all unique symbols for supported alpabets. //String with all unique symbols for supported alpabets.
// See script alphabets.py for generation and more information. // See script alphabets.py for generation and more information.
@ -62,6 +62,11 @@ Calculator::Calculator(const VContainer *data)
DefinePostfixOprt(in_Oprt, InchUnit); DefinePostfixOprt(in_Oprt, InchUnit);
} }
Calculator::~Calculator()
{
delete [] vVarVal;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
/** /**
* @brief eval calculate formula. * @brief eval calculate formula.
@ -77,81 +82,123 @@ qreal Calculator::EvalFormula(const QString &formula)
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void Calculator::InitVariables(const VContainer *data) void Calculator::InitVariables(const VContainer *data)
{ {
int num = 0;
if (qApp->patternType() == Pattern::Standard) if (qApp->patternType() == Pattern::Standard)
{ {
DefineVar(data->SizeName(), data->size()); num +=2;
DefineVar(data->HeightName(), data->height()); }
const QHash<QString, qreal> *lengthLines = data->DataLengthLines();
num += lengthLines->size();
const QHash<QString, qreal> *lengthSplines = data->DataLengthSplines();
num += lengthSplines->size();
const QHash<QString, qreal> *lengthArcs = data->DataLengthArcs();
num += lengthArcs->size();
const QHash<QString, qreal> *lineAngles = data->DataLineAngles();
num += lineAngles->size();
const QHash<QString, VMeasurement> *measurements = data->DataMeasurements();
num += measurements->size();
const QHash<QString, VIncrement> *increments = data->DataIncrements();
num += increments->size();
vVarVal = new qreal[num];
int j = 0;
if (qApp->patternType() == Pattern::Standard)
{
vVarVal[j] = data->size();
DefineVar(data->SizeName(), &vVarVal[j]);
++j;
vVarVal[j] = data->height();
DefineVar(data->HeightName(), &vVarVal[j]);
++j;
} }
{ {
const QHash<QString, qreal> *lengthLines = data->DataLengthLines();
QHash<QString, qreal>::const_iterator i = lengthLines->constBegin(); QHash<QString, qreal>::const_iterator i = lengthLines->constBegin();
while (i != lengthLines->constEnd()) while (i != lengthLines->constEnd())
{ {
DefineVar(i.key(), i.value()); vVarVal[j] = i.value();
DefineVar(i.key(), &vVarVal[j]);
++j;
++i; ++i;
} }
} }
{ {
const QHash<QString, qreal> *lengthSplines = data->DataLengthSplines();
QHash<QString, qreal>::const_iterator i = lengthSplines->constBegin(); QHash<QString, qreal>::const_iterator i = lengthSplines->constBegin();
while (i != lengthSplines->constEnd()) while (i != lengthSplines->constEnd())
{ {
DefineVar(i.key(), i.value()); vVarVal[j] = i.value();
DefineVar(i.key(), &vVarVal[j]);
++j;
++i; ++i;
} }
} }
{ {
const QHash<QString, qreal> *lengthArcs = data->DataLengthArcs();
QHash<QString, qreal>::const_iterator i = lengthArcs->constBegin(); QHash<QString, qreal>::const_iterator i = lengthArcs->constBegin();
while (i != lengthArcs->constEnd()) while (i != lengthArcs->constEnd())
{ {
DefineVar(i.key(), i.value()); vVarVal[j] = i.value();
DefineVar(i.key(), &vVarVal[j]);
++j;
++i; ++i;
} }
} }
{ {
const QHash<QString, qreal> *lineAngles = data->DataLineAngles();
QHash<QString, qreal>::const_iterator i = lineAngles->constBegin(); QHash<QString, qreal>::const_iterator i = lineAngles->constBegin();
while (i != lineAngles->constEnd()) while (i != lineAngles->constEnd())
{ {
DefineVar(i.key(), i.value()); vVarVal[j] = i.value();
DefineVar(i.key(), &vVarVal[j]);
++j;
++i; ++i;
} }
} }
{ {
const QHash<QString, VMeasurement> *measurements = data->DataMeasurements();
QHash<QString, VMeasurement>::const_iterator i = measurements->constBegin(); QHash<QString, VMeasurement>::const_iterator i = measurements->constBegin();
while (i != measurements->constEnd()) while (i != measurements->constEnd())
{ {
if (qApp->patternType() == Pattern::Standard) if (qApp->patternType() == Pattern::Standard)
{ {
DefineVar(i.key(), i.value().GetValue(data->size(), data->height())); vVarVal[j] = i.value().GetValue(data->size(), data->height());
DefineVar(i.key(), &vVarVal[j]);
++j;
} }
else else
{ {
DefineVar(i.key(), i.value().GetValue()); vVarVal[j] = i.value().GetValue();
DefineVar(i.key(), &vVarVal[j]);
++j;
} }
++i; ++i;
} }
} }
{ {
const QHash<QString, VIncrement> *increments = data->DataIncrements();
QHash<QString, VIncrement>::const_iterator i = increments->constBegin(); QHash<QString, VIncrement>::const_iterator i = increments->constBegin();
while (i != increments->constEnd()) while (i != increments->constEnd())
{ {
if (qApp->patternType() == Pattern::Standard) if (qApp->patternType() == Pattern::Standard)
{ {
DefineVar(i.key(), i.value().GetValue(data->size(), data->height())); vVarVal[j] = i.value().GetValue(data->size(), data->height());
DefineVar(i.key(), &vVarVal[j]);
++j;
} }
else else
{ {
DefineVar(i.key(), i.value().GetValue()); vVarVal[j] = i.value().GetValue();
DefineVar(i.key(), &vVarVal[j]);
++j;
} }
++i; ++i;
} }

View file

@ -38,9 +38,11 @@ class Calculator:public QmuParser
{ {
public: public:
explicit Calculator(const VContainer *data); explicit Calculator(const VContainer *data);
~Calculator();
qreal EvalFormula(const QString &formula); qreal EvalFormula(const QString &formula);
private: private:
Q_DISABLE_COPY(Calculator) Q_DISABLE_COPY(Calculator)
qreal *vVarVal;
void InitVariables(const VContainer *data); void InitVariables(const VContainer *data);
static qreal CmUnit(qreal val); static qreal CmUnit(qreal val);
static qreal MmUnit(qreal val); static qreal MmUnit(qreal val);

View file

@ -555,12 +555,17 @@ void QmuParserBase::DefineStrConst(const QString &a_strName, const QString &a_st
/** /**
* @brief Add a user defined variable. * @brief Add a user defined variable.
* @param [in] a_sName the variable name * @param [in] a_sName the variable name
* @param [in] a_pVar the variable vaule. * @param [in] a_pVar A pointer to the variable vaule.
* @post Will reset the Parser to string parsing mode. * @post Will reset the Parser to string parsing mode.
* @throw ParserException in case the name contains invalid signs. * @throw ParserException in case the name contains invalid signs or a_pVar is NULL.
*/ */
void QmuParserBase::DefineVar(const QString &a_sName, qreal a_pVar) void QmuParserBase::DefineVar(const QString &a_sName, qreal *a_pVar)
{ {
if (a_pVar==0)
{
Error(ecINVALID_VAR_PTR);
}
// Test if a constant with that names already exists // Test if a constant with that names already exists
if (m_ConstDef.find(a_sName)!=m_ConstDef.end()) if (m_ConstDef.find(a_sName)!=m_ConstDef.end())
{ {
@ -1236,25 +1241,25 @@ qreal QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const
// value and variable tokens // value and variable tokens
case cmVAR: case cmVAR:
Stack[++sidx] = *(&pTok->Val.ptr + nOffset); Stack[++sidx] = *(pTok->Val.ptr + nOffset);
continue; continue;
case cmVAL: case cmVAL:
Stack[++sidx] = pTok->Val.data2; Stack[++sidx] = pTok->Val.data2;
continue; continue;
case cmVARPOW2: case cmVARPOW2:
buf = *(&pTok->Val.ptr + nOffset); buf = *(pTok->Val.ptr + nOffset);
Stack[++sidx] = buf*buf; Stack[++sidx] = buf*buf;
continue; continue;
case cmVARPOW3: case cmVARPOW3:
buf = *(&pTok->Val.ptr + nOffset); buf = *(pTok->Val.ptr + nOffset);
Stack[++sidx] = buf*buf*buf; Stack[++sidx] = buf*buf*buf;
continue; continue;
case cmVARPOW4: case cmVARPOW4:
buf = *(&pTok->Val.ptr + nOffset); buf = *(pTok->Val.ptr + nOffset);
Stack[++sidx] = buf*buf*buf*buf; Stack[++sidx] = buf*buf*buf*buf;
continue; continue;
case cmVARMUL: case cmVARMUL:
Stack[++sidx] = *(&pTok->Val.ptr + nOffset) * pTok->Val.data + pTok->Val.data2; Stack[++sidx] = *(pTok->Val.ptr + nOffset) * pTok->Val.data + pTok->Val.data2;
continue; continue;
// Next is treatment of numeric functions // Next is treatment of numeric functions
case cmFUNC: case cmFUNC:
@ -1492,7 +1497,7 @@ void QmuParserBase::CreateRPN() const
break; break;
case cmVAR: case cmVAR:
stVal.push(opt); stVal.push(opt);
m_vRPN.AddVar( opt.GetVar() ); m_vRPN.AddVar( static_cast<qreal*>(opt.GetVar()) );
break; break;
case cmVAL: case cmVAL:
stVal.push(opt); stVal.push(opt);

View file

@ -79,7 +79,7 @@ public:
EOprtAssociativity a_eAssociativity = oaLEFT, bool a_bAllowOpt = false); EOprtAssociativity a_eAssociativity = oaLEFT, bool a_bAllowOpt = false);
void DefineConst(const QString &a_sName, qreal a_fVal); void DefineConst(const QString &a_sName, qreal a_fVal);
void DefineStrConst(const QString &a_sName, const QString &a_strVal); void DefineStrConst(const QString &a_sName, const QString &a_strVal);
void DefineVar(const QString &a_sName, qreal a_fVar); void DefineVar(const QString &a_sName, qreal *a_fVar);
void DefinePostfixOprt(const QString &a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt=true); 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, void DefineInfixOprt(const QString &a_strName, fun_type1 a_pOprt, int a_iPrec=prINFIX,
bool a_bAllowOpt=true); bool a_bAllowOpt=true);

View file

@ -98,7 +98,7 @@ void QmuParserByteCode::Assign(const QmuParserByteCode &a_ByteCode) Q_DECL_NOEXC
* @param a_pVar Pointer to be added. * @param a_pVar Pointer to be added.
* @throw nothrow * @throw nothrow
*/ */
void QmuParserByteCode::AddVar(qreal a_pVar) Q_DECL_NOEXCEPT void QmuParserByteCode::AddVar(qreal *a_pVar) Q_DECL_NOEXCEPT
{ {
++m_iStackPos; ++m_iStackPos;
m_iMaxStackSize = qMax(m_iMaxStackSize, static_cast<size_t>(m_iStackPos)); m_iMaxStackSize = qMax(m_iMaxStackSize, static_cast<size_t>(m_iStackPos));
@ -134,7 +134,7 @@ void QmuParserByteCode::AddVal(qreal a_fVal) Q_DECL_NOEXCEPT
// If optimization does not apply // If optimization does not apply
SToken tok; SToken tok;
tok.Cmd = cmVAL; tok.Cmd = cmVAL;
tok.Val.ptr = 0; tok.Val.ptr = nullptr;
tok.Val.data = 0; tok.Val.data = 0;
tok.Val.data2 = a_fVal; tok.Val.data2 = a_fVal;
m_vRPN.push_back(tok); m_vRPN.push_back(tok);
@ -355,14 +355,14 @@ void QmuParserByteCode::AddOp(ECmdCode a_Oprt)
(m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVARMUL && (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVARMUL &&
m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ) m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) )
{ {
assert( (m_vRPN[sz-2].Val.ptr==0 && m_vRPN[sz-1].Val.ptr!=0) || assert( (m_vRPN[sz-2].Val.ptr==nullptr && m_vRPN[sz-1].Val.ptr!=nullptr) ||
(m_vRPN[sz-2].Val.ptr!=0 && m_vRPN[sz-1].Val.ptr==0) || (m_vRPN[sz-2].Val.ptr!=nullptr && m_vRPN[sz-1].Val.ptr==nullptr) ||
(m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ); (m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) );
m_vRPN[sz-2].Cmd = cmVARMUL; m_vRPN[sz-2].Cmd = cmVARMUL;
m_vRPN[sz-2].Val.ptr = static_cast<qreal>( m_vRPN[sz-2].Val.ptr = reinterpret_cast<qreal*>(
static_cast<qlonglong>(m_vRPN[sz-2].Val.ptr) | reinterpret_cast<qlonglong>(m_vRPN[sz-2].Val.ptr) |
static_cast<qlonglong>(m_vRPN[sz-1].Val.ptr)); // variable reinterpret_cast<qlonglong>(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.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[sz-2].Val.data += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].Val.data; // multiplikatior
m_vRPN.pop_back(); m_vRPN.pop_back();
@ -374,9 +374,9 @@ void QmuParserByteCode::AddOp(ECmdCode a_Oprt)
(m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVAR) ) (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVAR) )
{ {
m_vRPN[sz-2].Cmd = cmVARMUL; m_vRPN[sz-2].Cmd = cmVARMUL;
m_vRPN[sz-2].Val.ptr = static_cast<qreal>( m_vRPN[sz-2].Val.ptr = reinterpret_cast<qreal*>(
static_cast<qlonglong>(m_vRPN[sz-2].Val.ptr) | reinterpret_cast<qlonglong>(m_vRPN[sz-2].Val.ptr) |
static_cast<qlonglong>(m_vRPN[sz-1].Val.ptr)); reinterpret_cast<qlonglong>(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.data = m_vRPN[sz-2].Val.data2 + m_vRPN[sz-1].Val.data2;
m_vRPN[sz-2].Val.data2 = 0; m_vRPN[sz-2].Val.data2 = 0;
m_vRPN.pop_back(); m_vRPN.pop_back();
@ -387,9 +387,9 @@ void QmuParserByteCode::AddOp(ECmdCode a_Oprt)
{ {
// Optimization: 2*(3*b+1) or (3*b+1)*2 -> 6*b+2 // Optimization: 2*(3*b+1) or (3*b+1)*2 -> 6*b+2
m_vRPN[sz-2].Cmd = cmVARMUL; m_vRPN[sz-2].Cmd = cmVARMUL;
m_vRPN[sz-2].Val.ptr = static_cast<qreal>( m_vRPN[sz-2].Val.ptr = reinterpret_cast<qreal*>(
static_cast<qlonglong>(m_vRPN[sz-2].Val.ptr) | reinterpret_cast<qlonglong>(m_vRPN[sz-2].Val.ptr) |
static_cast<qlonglong>(m_vRPN[sz-1].Val.ptr)); reinterpret_cast<qlonglong>(m_vRPN[sz-1].Val.ptr));
if (m_vRPN[sz-1].Cmd == cmVAL) if (m_vRPN[sz-1].Cmd == cmVAL)
{ {
m_vRPN[sz-2].Val.data *= m_vRPN[sz-1].Val.data2; m_vRPN[sz-2].Val.data *= m_vRPN[sz-1].Val.data2;
@ -491,7 +491,7 @@ void QmuParserByteCode::AddIfElse(ECmdCode a_Oprt) Q_DECL_NOEXCEPT
* *
* @sa ParserToken::ECmdCode * @sa ParserToken::ECmdCode
*/ */
void QmuParserByteCode::AddAssignOp(qreal a_pVar) Q_DECL_NOEXCEPT void QmuParserByteCode::AddAssignOp(qreal *a_pVar) Q_DECL_NOEXCEPT
{ {
--m_iStackPos; --m_iStackPos;
@ -691,19 +691,19 @@ void QmuParserByteCode::AsciiDump()
qDebug() << "VAL \t" << "[" << m_vRPN[i].Val.data2 << "]\n"; qDebug() << "VAL \t" << "[" << m_vRPN[i].Val.data2 << "]\n";
break; break;
case cmVAR: case cmVAR:
qDebug() << "VAR \t" << "[ADDR: 0x" << QString::number(m_vRPN[i].Val.ptr, 'f', 16) << "]\n"; qDebug() << "VAR \t" << "[ADDR: 0x" << QString::number(*m_vRPN[i].Val.ptr, 'f', 16) << "]\n";
break; break;
case cmVARPOW2: case cmVARPOW2:
qDebug() << "VARPOW2 \t" << "[ADDR: 0x" << QString::number(m_vRPN[i].Val.ptr, 'f', 16) << "]\n"; qDebug() << "VARPOW2 \t" << "[ADDR: 0x" << QString::number(*m_vRPN[i].Val.ptr, 'f', 16) << "]\n";
break; break;
case cmVARPOW3: case cmVARPOW3:
qDebug() << "VARPOW3 \t" << "[ADDR: 0x" << QString::number(m_vRPN[i].Val.ptr, 'f', 16) << "]\n"; qDebug() << "VARPOW3 \t" << "[ADDR: 0x" << QString::number(*m_vRPN[i].Val.ptr, 'f', 16) << "]\n";
break; break;
case cmVARPOW4: case cmVARPOW4:
qDebug() << "VARPOW4 \t" << "[ADDR: 0x" << QString::number(m_vRPN[i].Val.ptr, 'f', 16) << "]\n"; qDebug() << "VARPOW4 \t" << "[ADDR: 0x" << QString::number(*m_vRPN[i].Val.ptr, 'f', 16) << "]\n";
break; break;
case cmVARMUL: case cmVARMUL:
qDebug() << "VARMUL \t" << "[ADDR: 0x" << QString::number(m_vRPN[i].Val.ptr, 'f', 16) << "]" << " * [" qDebug() << "VARMUL \t" << "[ADDR: 0x" << QString::number(*m_vRPN[i].Val.ptr, 'f', 16) << "]" << " * ["
<< m_vRPN[i].Val.data << "]" << " + [" << m_vRPN[i].Val.data2 << "]\n"; << m_vRPN[i].Val.data << "]" << " + [" << m_vRPN[i].Val.data2 << "]\n";
break; break;
case cmFUNC: case cmFUNC:

View file

@ -43,7 +43,7 @@ struct SToken
{ {
struct //SValData struct //SValData
{ {
qreal ptr; qreal *ptr;
qreal data; qreal data;
qreal data2; qreal data2;
} Val; } Val;
@ -85,11 +85,11 @@ public:
QmuParserByteCode(const QmuParserByteCode &a_ByteCode) Q_DECL_NOEXCEPT; QmuParserByteCode(const QmuParserByteCode &a_ByteCode) Q_DECL_NOEXCEPT;
QmuParserByteCode& operator=(const QmuParserByteCode &a_ByteCode) Q_DECL_NOEXCEPT; QmuParserByteCode& operator=(const QmuParserByteCode &a_ByteCode) Q_DECL_NOEXCEPT;
void Assign(const QmuParserByteCode &a_ByteCode) Q_DECL_NOEXCEPT; void Assign(const QmuParserByteCode &a_ByteCode) Q_DECL_NOEXCEPT;
void AddVar(qreal a_pVar) Q_DECL_NOEXCEPT; void AddVar(qreal *a_pVar) Q_DECL_NOEXCEPT;
void AddVal(qreal a_fVal) Q_DECL_NOEXCEPT; void AddVal(qreal a_fVal) Q_DECL_NOEXCEPT;
void AddOp(ECmdCode a_Oprt); void AddOp(ECmdCode a_Oprt);
void AddIfElse(ECmdCode a_Oprt) Q_DECL_NOEXCEPT; void AddIfElse(ECmdCode a_Oprt) Q_DECL_NOEXCEPT;
void AddAssignOp(qreal a_pVar) Q_DECL_NOEXCEPT; void AddAssignOp(qreal *a_pVar) Q_DECL_NOEXCEPT;
void AddFun(generic_fun_type a_pFun, int a_iArgc) Q_DECL_NOEXCEPT; void AddFun(generic_fun_type a_pFun, int a_iArgc) Q_DECL_NOEXCEPT;
void AddBulkFun(generic_fun_type a_pFun, int a_iArgc) Q_DECL_NOEXCEPT; void AddBulkFun(generic_fun_type a_pFun, int a_iArgc) Q_DECL_NOEXCEPT;
void AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx) Q_DECL_NOEXCEPT; void AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx) Q_DECL_NOEXCEPT;

View file

@ -173,7 +173,7 @@ typedef std::basic_stringstream < char_type, std::char_traits<char_type>, std::a
// Data container types // Data container types
/** @brief Type used for storing variables. */ /** @brief Type used for storing variables. */
typedef std::map<QString, qreal> varmap_type; typedef std::map<QString, qreal*> varmap_type;
/** @brief Type used for storing constants. */ /** @brief Type used for storing constants. */
typedef std::map<QString, qreal> valmap_type; typedef std::map<QString, qreal> valmap_type;
@ -268,7 +268,7 @@ typedef qreal ( *strfun_type3 ) ( const QString &, qreal, qreal );
typedef int ( *identfun_type ) ( const QString &sExpr, int *nPos, qreal *fVal ); typedef int ( *identfun_type ) ( const QString &sExpr, int *nPos, qreal *fVal );
/** @brief Callback used for variable creation factory functions. */ /** @brief Callback used for variable creation factory functions. */
typedef qreal ( *facfun_type ) ( const QString &, void* ); typedef qreal* ( *facfun_type ) ( const QString &, void* );
} // end of namespace } // end of namespace
#endif #endif

View file

@ -103,9 +103,9 @@ int QmuParserTester::TestInterface()
try try
{ {
p.DefineVar ( "a", afVal[0] ); p.DefineVar ( "a", &afVal[0] );
p.DefineVar ( "b", afVal[1] ); p.DefineVar ( "b", &afVal[1] );
p.DefineVar ( "c", afVal[2] ); p.DefineVar ( "c", &afVal[2] );
p.SetExpr ( "a+b+c" ); p.SetExpr ( "a+b+c" );
p.Eval(); p.Eval();
} }
@ -280,21 +280,21 @@ int QmuParserTester::TestNames()
// variable names // variable names
qreal a; qreal a;
p.ClearConst(); p.ClearConst();
PARSER_THROWCHECK ( Var, false, "123abc", a ) PARSER_THROWCHECK ( Var, false, "123abc", &a )
PARSER_THROWCHECK ( Var, false, "9a", a ) PARSER_THROWCHECK ( Var, false, "9a", &a )
PARSER_THROWCHECK ( Var, false, "0a", a ) PARSER_THROWCHECK ( Var, false, "0a", &a )
PARSER_THROWCHECK ( Var, false, "+a", a ) PARSER_THROWCHECK ( Var, false, "+a", &a )
PARSER_THROWCHECK ( Var, false, "-a", a ) PARSER_THROWCHECK ( Var, false, "-a", &a )
PARSER_THROWCHECK ( Var, false, "?a", a ) PARSER_THROWCHECK ( Var, false, "?a", &a )
PARSER_THROWCHECK ( Var, false, "!a", a ) PARSER_THROWCHECK ( Var, false, "!a", &a )
PARSER_THROWCHECK ( Var, false, "a+", a ) PARSER_THROWCHECK ( Var, false, "a+", &a )
PARSER_THROWCHECK ( Var, false, "a-", a ) PARSER_THROWCHECK ( Var, false, "a-", &a )
PARSER_THROWCHECK ( Var, false, "a*", a ) PARSER_THROWCHECK ( Var, false, "a*", &a )
PARSER_THROWCHECK ( Var, false, "a?", a ) PARSER_THROWCHECK ( Var, false, "a?", &a )
PARSER_THROWCHECK ( Var, true, "a", a ) PARSER_THROWCHECK ( Var, true, "a", &a )
PARSER_THROWCHECK ( Var, true, "a_min", a ) PARSER_THROWCHECK ( Var, true, "a_min", &a )
PARSER_THROWCHECK ( Var, true, "a_min0", a ) PARSER_THROWCHECK ( Var, true, "a_min0", &a )
PARSER_THROWCHECK ( Var, true, "a_min9", a ) PARSER_THROWCHECK ( Var, true, "a_min9", &a )
PARSER_THROWCHECK ( Var, false, "a_min9", 0 ) PARSER_THROWCHECK ( Var, false, "a_min9", 0 )
// Postfix operators // Postfix operators
// fail // fail
@ -449,11 +449,11 @@ int QmuParserTester::TestVarConst()
int idx; int idx;
qmu::QmuParser p; qmu::QmuParser p;
qreal vVarVal[] = { 1, 2, 3, 4, 5}; qreal vVarVal[] = { 1, 2, 3, 4, 5};
p.DefineVar ( "a", vVarVal[0] ); p.DefineVar ( "a", &vVarVal[0] );
p.DefineVar ( "b", vVarVal[1] ); p.DefineVar ( "b", &vVarVal[1] );
p.DefineVar ( "c", vVarVal[2] ); p.DefineVar ( "c", &vVarVal[2] );
p.DefineVar ( "d", vVarVal[3] ); p.DefineVar ( "d", &vVarVal[3] );
p.DefineVar ( "e", vVarVal[4] ); p.DefineVar ( "e", &vVarVal[4] );
// Test lookup of defined variables // Test lookup of defined variables
// 4 used variables // 4 used variables
@ -475,7 +475,7 @@ int QmuParserTester::TestVarConst()
qmu::varmap_type::const_iterator item = UsedVar.begin(); qmu::varmap_type::const_iterator item = UsedVar.begin();
for ( idx = 0; item != UsedVar.end(); ++item ) for ( idx = 0; item != UsedVar.end(); ++item )
{ {
if ( vVarVal[idx++] != item->second ) if ( &vVarVal[idx++] != item->second )
{ {
throw false; throw false;
} }
@ -516,7 +516,7 @@ int QmuParserTester::TestVarConst()
item = UsedVar.begin(); item = UsedVar.begin();
for ( idx = 0; item != UsedVar.end(); ++item ) for ( idx = 0; item != UsedVar.end(); ++item )
{ {
if ( vVarVal[idx++] != item->second ) if ( &vVarVal[idx++] != item->second )
{ {
throw false; throw false;
} }
@ -1118,9 +1118,9 @@ int QmuParserTester::ThrowTest ( const QString &a_str, int a_iErrc, bool a_bFail
qreal fVal[] = {1, 1, 1}; qreal fVal[] = {1, 1, 1};
QmuParser p; QmuParser p;
p.DefineVar ( "a", fVal[0] ); p.DefineVar ( "a", &fVal[0] );
p.DefineVar ( "b", fVal[1] ); p.DefineVar ( "b", &fVal[1] );
p.DefineVar ( "c", fVal[2] ); p.DefineVar ( "c", &fVal[2] );
p.DefinePostfixOprt ( "{m}", Milli ); p.DefinePostfixOprt ( "{m}", Milli );
p.DefinePostfixOprt ( "m", Milli ); p.DefinePostfixOprt ( "m", Milli );
p.DefineFun ( "ping", Ping ); p.DefineFun ( "ping", Ping );
@ -1173,7 +1173,7 @@ int QmuParserTester::EqnTestWithVarChange ( const QString &a_str, double a_fVar1
// variable // variable
qreal var = 0; qreal var = 0;
p.DefineVar ( "a", var ); p.DefineVar ( "a", &var );
p.SetExpr ( a_str ); p.SetExpr ( a_str );
var = a_fVar1; var = a_fVar1;
@ -1242,11 +1242,11 @@ int QmuParserTester::EqnTest ( const QString &a_str, double a_fRes, bool a_fPass
p1->DefineConst ( "const2", 3 ); p1->DefineConst ( "const2", 3 );
// variables // variables
qreal vVarVal[] = { 1, 2, 3, -2}; qreal vVarVal[] = { 1, 2, 3, -2};
p1->DefineVar ( "a", vVarVal[0] ); p1->DefineVar ( "a", &vVarVal[0] );
p1->DefineVar ( "aa", vVarVal[1] ); p1->DefineVar ( "aa", &vVarVal[1] );
p1->DefineVar ( "b", vVarVal[1] ); p1->DefineVar ( "b", &vVarVal[1] );
p1->DefineVar ( "c", vVarVal[2] ); p1->DefineVar ( "c", &vVarVal[2] );
p1->DefineVar ( "d", vVarVal[3] ); p1->DefineVar ( "d", &vVarVal[3] );
// custom value ident functions // custom value ident functions
p1->AddValIdent ( &QmuParserTester::IsHexVal ); p1->AddValIdent ( &QmuParserTester::IsHexVal );

View file

@ -196,13 +196,13 @@ public:
* Member variables not necessary for variable tokens will be invalidated. * Member variables not necessary for variable tokens will be invalidated.
* @throw nothrow * @throw nothrow
*/ */
QmuParserToken& SetVar ( TBase a_pVar, const TString &a_strTok ) QmuParserToken& SetVar ( TBase *a_pVar, const TString &a_strTok )
{ {
m_iCode = cmVAR; m_iCode = cmVAR;
m_iType = tpDBL; m_iType = tpDBL;
m_strTok = a_strTok; m_strTok = a_strTok;
m_iIdx = -1; m_iIdx = -1;
m_pTok = a_pVar; m_pTok = reinterpret_cast<void*> ( a_pVar );
m_pCallback.reset ( 0 ); m_pCallback.reset ( 0 );
return *this; return *this;
} }
@ -357,7 +357,7 @@ public:
case cmVAL: case cmVAL:
return m_fVal; return m_fVal;
case cmVAR: case cmVAR:
return m_pTok; return * ( reinterpret_cast<TBase*>(m_pTok) );
case cmLE: case cmLE:
case cmGE: case cmGE:
case cmNEQ: case cmNEQ:
@ -404,14 +404,14 @@ public:
* Valid only if m_iType==CmdVar. * Valid only if m_iType==CmdVar.
* @throw QmuParserError if token is no variable token. * @throw QmuParserError if token is no variable token.
*/ */
TBase GetVar() const TBase* GetVar() const
{ {
if ( m_iCode != cmVAR ) if ( m_iCode != cmVAR )
{ {
throw QmuParserError ( ecINTERNAL_ERROR ); throw QmuParserError ( ecINTERNAL_ERROR );
} }
return m_pTok; return reinterpret_cast<TBase*>( m_pTok );
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -449,7 +449,7 @@ public:
private: private:
ECmdCode m_iCode; ///< Type of the token; The token type is a constant of type #ECmdCode. ECmdCode m_iCode; ///< Type of the token; The token type is a constant of type #ECmdCode.
ETypeCode m_iType; ETypeCode m_iType;
TBase m_pTok; ///< Stores Token pointer; not applicable for all tokens 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 int m_iIdx; ///< An otional index to an external buffer storing the token data
TString m_strTok; ///< Token string TString m_strTok; ///< Token string
TString m_strVal; ///< Value for string variables TString m_strVal; ///< Value for string variables

View file

@ -976,7 +976,7 @@ bool QmuParserTokenReader::IsUndefVarTok ( token_type &a_Tok ) Q_DECL_NOEXCEPT
// If a factory is available implicitely create new variables // If a factory is available implicitely create new variables
if ( m_pFactory ) if ( m_pFactory )
{ {
qreal fVar = m_pFactory ( strTok, m_pFactoryData ); qreal *fVar = m_pFactory ( strTok, m_pFactoryData );
a_Tok.SetVar ( fVar, strTok ); a_Tok.SetVar ( fVar, strTok );
// Do not use m_pParser->DefineVar( strTok, fVar ); // Do not use m_pParser->DefineVar( strTok, fVar );
@ -990,7 +990,7 @@ bool QmuParserTokenReader::IsUndefVarTok ( token_type &a_Tok ) Q_DECL_NOEXCEPT
} }
else else
{ {
a_Tok.SetVar ( m_fZero, strTok ); a_Tok.SetVar ( &m_fZero, strTok );
m_UsedVar[strTok] = 0; // Add variable to used-var-list m_UsedVar[strTok] = 0; // Add variable to used-var-list
} }