Make parser static locale variable local for each parser instance.
--HG-- branch : feature
This commit is contained in:
parent
cc65f00e2f
commit
8c0bdcc612
|
@ -199,14 +199,14 @@ qreal QmuParser::Max(const qreal *a_afArg, int a_iArgc)
|
||||||
* @param [out] a_fVal Pointer where the value should be stored in case one is found.
|
* @param [out] a_fVal Pointer where the value should be stored in case one is found.
|
||||||
* @return 1 if a value was found 0 otherwise.
|
* @return 1 if a value was found 0 otherwise.
|
||||||
*/
|
*/
|
||||||
int QmuParser::IsVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal)
|
int QmuParser::IsVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal, const std::locale &s_locale)
|
||||||
{
|
{
|
||||||
qreal fVal(0);
|
qreal fVal(0);
|
||||||
|
|
||||||
std::wstring a_szExprStd = a_szExpr.toStdWString();
|
std::wstring a_szExprStd = a_szExpr.toStdWString();
|
||||||
stringstream_type stream(a_szExprStd);
|
stringstream_type stream(a_szExprStd);
|
||||||
stream.seekg(0); // todo: check if this really is necessary
|
stream.seekg(0); // todo: check if this really is necessary
|
||||||
stream.imbue(QmuParser::s_locale);
|
stream.imbue(s_locale);
|
||||||
stream >> fVal;
|
stream >> fVal;
|
||||||
stringstream_type::pos_type iEnd = stream.tellg(); // Position after reading
|
stringstream_type::pos_type iEnd = stream.tellg(); // Position after reading
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ namespace qmu
|
||||||
virtual void OnDetectVar(const QString &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;
|
qreal Diff(qreal *a_Var, qreal a_fPos, qreal a_fEpsilon = 0) const;
|
||||||
protected:
|
protected:
|
||||||
static int IsVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal);
|
static int IsVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal, const std::locale &s_locale);
|
||||||
// Trigonometric functions
|
// Trigonometric functions
|
||||||
static qreal Tan2(qreal, qreal);
|
static qreal Tan2(qreal, qreal);
|
||||||
// hyperbolic functions
|
// hyperbolic functions
|
||||||
|
|
|
@ -37,7 +37,6 @@ using namespace std;
|
||||||
|
|
||||||
namespace qmu
|
namespace qmu
|
||||||
{
|
{
|
||||||
std::locale QmuParserBase::s_locale = std::locale(std::locale::classic(), new change_dec_sep<char_type>('.'));
|
|
||||||
|
|
||||||
bool QmuParserBase::g_DbgDumpCmdCode = false;
|
bool QmuParserBase::g_DbgDumpCmdCode = false;
|
||||||
bool QmuParserBase::g_DbgDumpStack = false;
|
bool QmuParserBase::g_DbgDumpStack = false;
|
||||||
|
@ -57,7 +56,8 @@ const QStringList QmuParserBase::c_DefaultOprt = QStringList()<< "<=" << ">=" <<
|
||||||
* @brief Constructor.
|
* @brief Constructor.
|
||||||
*/
|
*/
|
||||||
QmuParserBase::QmuParserBase()
|
QmuParserBase::QmuParserBase()
|
||||||
:m_pParseFormula(&QmuParserBase::ParseString), m_vRPN(), m_vStringBuf(), m_vStringVarBuf(), m_pTokenReader(),
|
:s_locale(std::locale(std::locale::classic(), new change_dec_sep<char_type>('.'))),
|
||||||
|
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_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_bBuiltInOp(true), m_sNameChars(), m_sOprtChars(), m_sInfixOprtChars(), m_nIfElseCounter(0), m_vStackBuffer(),
|
||||||
m_nFinalResultIdx(0), m_Tokens(QMap<int, QString>()), m_Numbers(QMap<int, QString>()), allowSubexpressions(true)
|
m_nFinalResultIdx(0), m_Tokens(QMap<int, QString>()), m_Numbers(QMap<int, QString>()), allowSubexpressions(true)
|
||||||
|
@ -72,10 +72,11 @@ QmuParserBase::QmuParserBase()
|
||||||
* Tha parser can be safely copy constructed but the bytecode is reset during copy construction.
|
* Tha parser can be safely copy constructed but the bytecode is reset during copy construction.
|
||||||
*/
|
*/
|
||||||
QmuParserBase::QmuParserBase(const QmuParserBase &a_Parser)
|
QmuParserBase::QmuParserBase(const QmuParserBase &a_Parser)
|
||||||
:m_pParseFormula(&QmuParserBase::ParseString), m_vRPN(), m_vStringBuf(), m_vStringVarBuf(), m_pTokenReader(),
|
:s_locale(a_Parser.getLocale()), m_pParseFormula(&QmuParserBase::ParseString), m_vRPN(), m_vStringBuf(),
|
||||||
m_FunDef(), m_PostOprtDef(), m_InfixOprtDef(), m_OprtDef(), m_ConstDef(), m_StrVarDef(), m_VarDef(),
|
m_vStringVarBuf(), m_pTokenReader(), m_FunDef(), m_PostOprtDef(), m_InfixOprtDef(), m_OprtDef(), m_ConstDef(),
|
||||||
m_bBuiltInOp(true), m_sNameChars(), m_sOprtChars(), m_sInfixOprtChars(), m_nIfElseCounter(0), m_vStackBuffer(),
|
m_StrVarDef(), m_VarDef(), m_bBuiltInOp(true), m_sNameChars(), m_sOprtChars(), m_sInfixOprtChars(),
|
||||||
m_nFinalResultIdx(0), m_Tokens(QMap<int, QString>()), m_Numbers(QMap<int, QString>()), allowSubexpressions(true)
|
m_nIfElseCounter(0), m_vStackBuffer(), m_nFinalResultIdx(0), m_Tokens(QMap<int, QString>()),
|
||||||
|
m_Numbers(QMap<int, QString>()), allowSubexpressions(true)
|
||||||
{
|
{
|
||||||
m_pTokenReader.reset(new token_reader_type(this));
|
m_pTokenReader.reset(new token_reader_type(this));
|
||||||
Assign(a_Parser);
|
Assign(a_Parser);
|
||||||
|
@ -220,6 +221,18 @@ void QmuParserBase::setAllowSubexpressions(bool value)
|
||||||
allowSubexpressions = value;
|
allowSubexpressions = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
std::locale QmuParserBase::getLocale() const
|
||||||
|
{
|
||||||
|
return s_locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void QmuParserBase::setLocale(const std::locale &value)
|
||||||
|
{
|
||||||
|
s_locale = value;
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* @brief Returns the version of muparser.
|
* @brief Returns the version of muparser.
|
||||||
|
@ -1300,7 +1313,7 @@ void QmuParserBase::CreateRPN() const
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
opt = m_pTokenReader->ReadNextToken();
|
opt = m_pTokenReader->ReadNextToken(s_locale);
|
||||||
|
|
||||||
switch (opt.GetCode())
|
switch (opt.GetCode())
|
||||||
{
|
{
|
||||||
|
|
|
@ -122,9 +122,12 @@ public:
|
||||||
}
|
}
|
||||||
void setAllowSubexpressions(bool value);
|
void setAllowSubexpressions(bool value);
|
||||||
|
|
||||||
|
std::locale getLocale() const;
|
||||||
|
void setLocale(const std::locale &value);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static const QStringList c_DefaultOprt;
|
static const QStringList c_DefaultOprt;
|
||||||
static std::locale s_locale; ///< The locale used by the parser
|
std::locale s_locale; ///< The locale used by the parser
|
||||||
static bool g_DbgDumpCmdCode;
|
static bool g_DbgDumpCmdCode;
|
||||||
static bool g_DbgDumpStack;
|
static bool g_DbgDumpStack;
|
||||||
void Init();
|
void Init();
|
||||||
|
|
|
@ -275,7 +275,7 @@ typedef qreal ( *strfun_type2 ) ( const QString &, qreal );
|
||||||
typedef qreal ( *strfun_type3 ) ( const QString &, qreal, qreal );
|
typedef qreal ( *strfun_type3 ) ( const QString &, qreal, qreal );
|
||||||
|
|
||||||
/** @brief Callback used for functions that identify values in a string. */
|
/** @brief Callback used for functions that identify values in a string. */
|
||||||
typedef int ( *identfun_type ) ( const QString &sExpr, int *nPos, qreal *fVal );
|
typedef int ( *identfun_type ) ( const QString &sExpr, int *nPos, qreal *fVal, const std::locale &s_locale );
|
||||||
|
|
||||||
/** @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* );
|
||||||
|
|
|
@ -62,8 +62,9 @@ QmuParserTester::QmuParserTester()
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
int QmuParserTester::IsHexVal ( const QString &a_szExpr, int *a_iPos, qreal *a_fVal )
|
int QmuParserTester::IsHexVal ( const QString &a_szExpr, int *a_iPos, qreal *a_fVal, const std::locale &s_locale )
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(s_locale)
|
||||||
if ( a_szExpr.data()[1] == 0 || ( a_szExpr.data()[0] != '0' || a_szExpr.data()[1] != 'x' ) )
|
if ( a_szExpr.data()[1] == 0 || ( a_szExpr.data()[0] != '0' || a_szExpr.data()[1] != 'x' ) )
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -276,7 +276,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Custom value recognition
|
// Custom value recognition
|
||||||
static int IsHexVal ( const QString &a_szExpr, int *a_iPos, qreal *a_fVal );
|
static int IsHexVal (const QString &a_szExpr, int *a_iPos, qreal *a_fVal , const std::locale &s_locale);
|
||||||
|
|
||||||
// cppcheck-suppress functionStatic
|
// cppcheck-suppress functionStatic
|
||||||
int TestNames();
|
int TestNames();
|
||||||
|
|
|
@ -204,7 +204,7 @@ void QmuParserTokenReader::ReInit()
|
||||||
/**
|
/**
|
||||||
* @brief Read the next token from the string.
|
* @brief Read the next token from the string.
|
||||||
*/
|
*/
|
||||||
QmuParserTokenReader::token_type QmuParserTokenReader::ReadNextToken()
|
QmuParserTokenReader::token_type QmuParserTokenReader::ReadNextToken(const std::locale &s_locale)
|
||||||
{
|
{
|
||||||
assert ( m_pParser );
|
assert ( m_pParser );
|
||||||
|
|
||||||
|
@ -236,7 +236,7 @@ QmuParserTokenReader::token_type QmuParserTokenReader::ReadNextToken()
|
||||||
{
|
{
|
||||||
return SaveBeforeReturn ( tok ); // Check for function argument separators
|
return SaveBeforeReturn ( tok ); // Check for function argument separators
|
||||||
}
|
}
|
||||||
if ( IsValTok ( tok ) )
|
if ( IsValTok ( tok, s_locale ) )
|
||||||
{
|
{
|
||||||
return SaveBeforeReturn ( tok ); // Check for values / constant tokens
|
return SaveBeforeReturn ( tok ); // Check for values / constant tokens
|
||||||
}
|
}
|
||||||
|
@ -766,7 +766,7 @@ bool QmuParserTokenReader::IsPostOpTok ( token_type &a_Tok )
|
||||||
* @param a_Tok [out] If a value token is found it will be placed here.
|
* @param a_Tok [out] If a value token is found it will be placed here.
|
||||||
* @return true if a value token has been found.
|
* @return true if a value token has been found.
|
||||||
*/
|
*/
|
||||||
bool QmuParserTokenReader::IsValTok ( token_type &a_Tok )
|
bool QmuParserTokenReader::IsValTok ( token_type &a_Tok, const std::locale &s_locale )
|
||||||
{
|
{
|
||||||
assert ( m_pConstDef );
|
assert ( m_pConstDef );
|
||||||
assert ( m_pParser );
|
assert ( m_pParser );
|
||||||
|
@ -802,7 +802,7 @@ bool QmuParserTokenReader::IsValTok ( token_type &a_Tok )
|
||||||
for ( item = m_vIdentFun.begin(); item != m_vIdentFun.end(); ++item )
|
for ( item = m_vIdentFun.begin(); item != m_vIdentFun.end(); ++item )
|
||||||
{
|
{
|
||||||
int iStart = m_iPos;
|
int iStart = m_iPos;
|
||||||
if ( ( *item ) ( m_strFormula.mid ( m_iPos ), &m_iPos, &fVal ) == 1 )
|
if ( ( *item ) ( m_strFormula.mid ( m_iPos ), &m_iPos, &fVal, s_locale ) == 1 )
|
||||||
{
|
{
|
||||||
// 2013-11-27 Issue 2: https://code.google.com/p/muparser/issues/detail?id=2
|
// 2013-11-27 Issue 2: https://code.google.com/p/muparser/issues/detail?id=2
|
||||||
strTok = m_strFormula.mid ( iStart, m_iPos-iStart );
|
strTok = m_strFormula.mid ( iStart, m_iPos-iStart );
|
||||||
|
|
|
@ -58,7 +58,7 @@ public:
|
||||||
QChar GetArgSep() const;
|
QChar GetArgSep() const;
|
||||||
void IgnoreUndefVar(bool bIgnore);
|
void IgnoreUndefVar(bool bIgnore);
|
||||||
void ReInit();
|
void ReInit();
|
||||||
token_type ReadNextToken();
|
token_type ReadNextToken(const std::locale &s_locale);
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -103,7 +103,7 @@ private:
|
||||||
bool IsFunTok(token_type &a_Tok);
|
bool IsFunTok(token_type &a_Tok);
|
||||||
bool IsPostOpTok(token_type &a_Tok);
|
bool IsPostOpTok(token_type &a_Tok);
|
||||||
bool IsOprt(token_type &a_Tok);
|
bool IsOprt(token_type &a_Tok);
|
||||||
bool IsValTok(token_type &a_Tok);
|
bool IsValTok(token_type &a_Tok, const std::locale &s_locale);
|
||||||
bool IsVarTok(token_type &a_Tok);
|
bool IsVarTok(token_type &a_Tok);
|
||||||
bool IsStrVarTok(token_type &a_Tok);
|
bool IsStrVarTok(token_type &a_Tok);
|
||||||
bool IsUndefVarTok(token_type &a_Tok);
|
bool IsUndefVarTok(token_type &a_Tok);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user