diff --git a/common/base_units.cpp b/common/base_units.cpp
index cfecad0877..af5d545bc1 100644
--- a/common/base_units.cpp
+++ b/common/base_units.cpp
@@ -397,10 +397,10 @@ int ValueFromTextCtrl( const wxTextCtrl& aTextCtr )
{
int value;
wxString msg = aTextCtr.GetValue();
- NumericEvaluator eval;
+ NUMERIC_EVALUATOR eval( g_UserUnit );
- if( eval.process( msg.mb_str() ) )
- msg = wxString::FromUTF8( eval.result() );
+ if( eval.Process( msg ) )
+ msg = eval.Result();
value = ValueFromString( g_UserUnit, msg );
diff --git a/common/libeval/grammar.c b/common/libeval/grammar.c
index cc9eb22186..4551f2d38f 100644
--- a/common/libeval/grammar.c
+++ b/common/libeval/grammar.c
@@ -98,9 +98,9 @@ typedef union {
#ifndef YYSTACKDEPTH
#define YYSTACKDEPTH 100
#endif
-#define ParseARG_SDECL NumericEvaluator* pEval ;
-#define ParseARG_PDECL , NumericEvaluator* pEval
-#define ParseARG_FETCH NumericEvaluator* pEval = yypParser->pEval
+#define ParseARG_SDECL NUMERIC_EVALUATOR* pEval ;
+#define ParseARG_PDECL , NUMERIC_EVALUATOR* pEval
+#define ParseARG_FETCH NUMERIC_EVALUATOR* pEval = yypParser->pEval
#define ParseARG_STORE yypParser->pEval = pEval
#define YYNSTATE 16
#define YYNRULE 16
@@ -757,12 +757,12 @@ static void yy_reduce(
break;
case 9: /* expr ::= VAR */
#line 55 "grammar.lemon"
-{ yygotominor.yy0.dValue = pEval->getVar(yymsp[0].minor.yy0.text); yygotominor.yy0.valid=true; }
+{ yygotominor.yy0.dValue = pEval->GetVar(yymsp[0].minor.yy0.text); yygotominor.yy0.valid=true; }
#line 762 "grammar.c"
break;
case 10: /* expr ::= VAR ASSIGN expr */
#line 56 "grammar.lemon"
-{ pEval->setVar(yymsp[-2].minor.yy0.text, yymsp[0].minor.yy0.dValue); yygotominor.yy0.dValue = yymsp[0].minor.yy0.dValue; yygotominor.yy0.valid=false; }
+{ pEval->SetVar(yymsp[-2].minor.yy0.text, yymsp[0].minor.yy0.dValue); yygotominor.yy0.dValue = yymsp[0].minor.yy0.dValue; yygotominor.yy0.valid=false; }
#line 767 "grammar.c"
break;
case 11: /* expr ::= expr PLUS expr */
diff --git a/common/libeval/grammar.lemon b/common/libeval/grammar.lemon
index d172fd9189..ffe627e9f4 100644
--- a/common/libeval/grammar.lemon
+++ b/common/libeval/grammar.lemon
@@ -52,8 +52,8 @@ stmt ::= expr SEMCOL. { pEval->parseSetResult(NAN); }
expr(A) ::= VALUE(B). { A.dValue = B.dValue; A.valid=true; }
expr(A) ::= expr(B) UNIT(C). { A.dValue = B.dValue * C.dValue; A.valid=B.valid; }
expr(A) ::= MINUS expr(B). { A.dValue = -B.dValue; A.valid=B.valid; }
-expr(A) ::= VAR(B). { A.dValue = pEval->getVar(B.text); A.valid=true; }
-expr(A) ::= VAR(B) ASSIGN expr(C). { pEval->setVar(B.text, C.dValue); A.dValue = C.dValue; A.valid=false; }
+expr(A) ::= VAR(B). { A.dValue = pEval->GetVar(B.text); A.valid=true; }
+expr(A) ::= VAR(B) ASSIGN expr(C). { pEval->SetVar(B.text, C.dValue); A.dValue = C.dValue; A.valid=false; }
expr(A) ::= expr(B) PLUS expr(C). { A.dValue = B.dValue + C.dValue; A.valid=C.valid; }
expr(A) ::= expr(B) MINUS expr(C). { A.dValue = B.dValue - C.dValue; A.valid=C.valid; }
expr(A) ::= expr(B) MULT expr(C). { A.dValue = B.dValue * C.dValue; A.valid=C.valid; }
diff --git a/common/libeval/numeric_evaluator.cpp b/common/libeval/numeric_evaluator.cpp
index 7da81f9ef8..7efb7054bc 100644
--- a/common/libeval/numeric_evaluator.cpp
+++ b/common/libeval/numeric_evaluator.cpp
@@ -17,24 +17,9 @@
along with this program. If not, see .
*/
-#define TESTMODE 0
#include
-#if !TESTMODE
-#include
-#else
-#include
-#endif
-
-
-#include
-#include
-#include
-#include
-#include
-
-
/* The (generated) lemon parser is written in C.
* In order to keep its symbol from the global namespace include the parser code with
* a C++ namespace.
@@ -49,335 +34,330 @@ namespace numEval
#endif
#include "grammar.c"
+
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
} /* namespace numEval */
-// JEY TODO: remove this version;
-NumericEvaluator :: NumericEvaluator() :
- pClParser( 0 )
+NUMERIC_EVALUATOR::NUMERIC_EVALUATOR( EDA_UNITS_T aUnits, bool aUseMils )
{
- struct lconv* lc = localeconv();
- cClDecSep = *lc->decimal_point;
+ struct lconv* lc = localeconv();
+ m_localeDecimalSeparator = *lc->decimal_point;
- bClTextInputStorage = true;
+ m_parseError = false;
+ m_parseFinished = false;
- bClError = false;
- bClParseFinished = false;
+ m_parser = numEval::ParseAlloc( malloc );
- if( pClParser == nullptr )
- pClParser = numEval::ParseAlloc(malloc);
-
- switch( g_UserUnit )
- {
- case INCHES:
- eClUnitDefault = Unit::Inch;
- break;
- case MILLIMETRES:
- eClUnitDefault = Unit::Metric;
- break;
- default:
- eClUnitDefault = Unit::Metric;
- break;
- }
+ switch( aUnits )
+ {
+ case INCHES:
+ if( aUseMils )
+ m_defaultUnits = Unit::Mil;
+ else
+ m_defaultUnits = Unit::Inch;
+ break;
+ case MILLIMETRES:m_defaultUnits = Unit::Metric;
+ break;
+ default:m_defaultUnits = Unit::Metric;
+ break;
+ }
}
-NumericEvaluator::NumericEvaluator( EDA_UNITS_T aUnits, bool aUseMils ) :
- pClParser( 0 )
+
+NUMERIC_EVALUATOR::~NUMERIC_EVALUATOR()
{
- struct lconv* lc = localeconv();
- cClDecSep = *lc->decimal_point;
+ numEval::ParseFree( m_parser, free );
- bClTextInputStorage = true;
- pClParser = numEval::ParseAlloc(malloc);
+ // Allow explicit call to destructor
+ m_parser = nullptr;
- switch( aUnits )
- {
- case INCHES:
- if( aUseMils )
- eClUnitDefault = Unit::Mil;
- else
- eClUnitDefault = Unit::Inch;
- break;
- case MILLIMETRES:
- eClUnitDefault = Unit::Metric;
- break;
- default:
- eClUnitDefault = Unit::Metric;
- break;
- }
+ Clear();
}
-NumericEvaluator :: ~NumericEvaluator()
+
+void NUMERIC_EVALUATOR::Clear()
{
- numEval::ParseFree(pClParser, free);
-
- // Allow explicit call to destructor
- pClParser = nullptr;
-
- clear();
+ free( m_token.token );
+ m_token.token = nullptr;
+ m_token.input = nullptr;
+ m_parseError = true;
+ m_originalText = wxEmptyString;
}
-void
-NumericEvaluator :: clear(const void* pObj)
-{
- free(clToken.token);
- clToken.token = nullptr;
- clToken.input = nullptr;
- bClError = true;
- if (bClTextInputStorage)
- clObjMap.clear();
+void NUMERIC_EVALUATOR::parseError( const char* s )
+{
+ m_parseError = true;
}
-void
-NumericEvaluator :: parse(int token, numEval::TokenType value)
+
+void NUMERIC_EVALUATOR::parseOk()
{
- numEval::Parse(pClParser, token, value, this);
+ m_parseFinished = true;
}
-void
-NumericEvaluator :: parseError(const char* s)
+
+void NUMERIC_EVALUATOR::parseSetResult( double val )
{
- bClError = true;
+ snprintf( m_token.token, m_token.OutLen, "%.10g", val );
}
-void
-NumericEvaluator :: parseOk()
+
+wxString NUMERIC_EVALUATOR::OriginalText() const
{
- bClParseFinished = true;
+ return m_originalText;
}
-void
-NumericEvaluator :: parseSetResult(double val)
+
+bool NUMERIC_EVALUATOR::Process( const wxString& aString )
{
- snprintf(clToken.token, clToken.OutLen, "%.10g", val);
+ m_originalText = aString;
+
+ // Feed parser token after token until end of input.
+
+ newString( aString );
+ m_parseError = false;
+ m_parseFinished = false;
+ Token tok;
+
+ do
+ {
+ tok = getToken();
+ numEval::Parse( m_parser, tok.token, tok.value, this );
+
+ if( m_parseFinished || tok.token == ENDS )
+ {
+ // Reset parser by passing zero as token ID, value is ignored.
+ numEval::Parse( m_parser, 0, tok.value, this );
+ break;
+ }
+ } while( tok.token );
+
+ return !m_parseError;
}
-const char*
-NumericEvaluator :: textInput(const void* pObj) const
-{
- auto it = clObjMap.find(pObj);
- if (it != clObjMap.end()) return it->second.c_str();
- return nullptr;
+void NUMERIC_EVALUATOR::newString( const wxString& aString )
+{
+ Clear();
+ auto len = aString.length();
+ m_token.token = reinterpret_cast( malloc( TokenStat::OutLen + 1 ));
+ strcpy( m_token.token, "0" );
+ m_token.inputLen = len;
+ m_token.pos = 0;
+ m_token.input = aString.mb_str();
+ m_parseFinished = false;
}
-bool
-NumericEvaluator :: process(const char* s)
+
+NUMERIC_EVALUATOR::Token NUMERIC_EVALUATOR::getToken()
{
- /* Process new string.
- * Feed parser token after token until end of input.
- */
+ Token retval;
+ size_t idx;
- newString(s);
+ retval.token = ENDS;
+ retval.value.dValue = 0;
- if (pClParser == nullptr)
- pClParser = numEval::ParseAlloc(malloc);
+ if( m_token.token == nullptr )
+ return retval;
- bClError = false;
- bClParseFinished = false;
+ if( m_token.input == nullptr )
+ return retval;
- Token tok;
- do {
- tok = getToken();
- parse(tok.token, tok.value);
- if (bClParseFinished || tok.token == ENDS) {
- // Reset parser by passing zero as token ID, value is ignored.
- numEval::Parse(pClParser, 0, tok.value, this);
- break;
- }
- //usleep(200000);
- } while (tok.token);
+ if( m_token.pos >= m_token.inputLen )
+ return retval;
- return !bClError;
+ auto isDecimalSeparator = [ & ]( char ch ) -> bool {
+ return ( ch == m_localeDecimalSeparator || ch == '.' || ch == ',' );
+ };
+
+ // Lambda: get value as string, store into clToken.token and update current index.
+ auto extractNumber = [ & ]() {
+ bool haveSeparator = false;
+ idx = 0;
+ auto ch = m_token.input[ m_token.pos ];
+
+ do
+ {
+ if( isDecimalSeparator( ch ) && haveSeparator )
+ break;
+
+ m_token.token[ idx++ ] = ch;
+
+ if( isDecimalSeparator( ch ))
+ haveSeparator = true;
+
+ ch = m_token.input[ ++m_token.pos ];
+ } while( isdigit( ch ) || isDecimalSeparator( ch ));
+
+ m_token.token[ idx ] = 0;
+
+ // Ensure that the systems decimal separator is used
+ for( int i = strlen( m_token.token ); i; i-- )
+ if( isDecimalSeparator( m_token.token[ i - 1 ] ))
+ m_token.token[ i - 1 ] = m_localeDecimalSeparator;
+ };
+
+ // Lamda: Get unit for current token.
+ // Valid units are ", in, mm, mil and thou. Returns Unit::Invalid otherwise.
+ auto checkUnit = [ this ]() -> Unit {
+ char ch = m_token.input[ m_token.pos ];
+
+ if( ch == '"' )
+ {
+ m_token.pos++;
+ return Unit::Inch;
+ }
+
+ // Do not use strcasecmp() as it is not available on all platforms
+ const char* cptr = &m_token.input[ m_token.pos ];
+ const auto sizeLeft = m_token.inputLen - m_token.pos;
+
+ if( sizeLeft >= 2 && ch == 'm' && cptr[ 1 ] == 'm' && !isalnum( cptr[ 2 ] ))
+ {
+ m_token.pos += 2;
+ return Unit::Metric;
+ }
+
+ if( sizeLeft >= 2 && ch == 'i' && cptr[ 1 ] == 'n' && !isalnum( cptr[ 2 ] ))
+ {
+ m_token.pos += 2;
+ return Unit::Inch;
+ }
+
+ if( sizeLeft >= 3 && ch == 'm' && cptr[ 1 ] == 'i' && cptr[ 2 ] == 'l' && !isalnum( cptr[ 3 ] ))
+ {
+ m_token.pos += 3;
+ return Unit::Mil;
+ }
+
+ if( sizeLeft >= 4 && ch == 't' && cptr[ 1 ] == 'h' && cptr[ 2 ] == 'o' && cptr[ 2 ] == 'u' && !isalnum( cptr[ 3 ] ))
+ {
+ m_token.pos += 4;
+ return Unit::Mil;
+ }
+
+ return Unit::Invalid;
+ };
+
+ char ch;
+
+ // Start processing of first/next token: Remove whitespace
+ for( ;; )
+ {
+ ch = m_token.input[ m_token.pos ];
+
+ if( ch == ' ' )
+ m_token.pos++;
+ else
+ break;
+ }
+
+ Unit convertFrom;
+
+ if( ch == 0 )
+ {
+ /* End of input */
+ }
+ else if( isdigit( ch ) || isDecimalSeparator( ch ))
+ {
+ // VALUE
+ extractNumber();
+ retval.token = VALUE;
+ retval.value.dValue = atof( m_token.token );
+ }
+ else if(( convertFrom = checkUnit()) != Unit::Invalid )
+ {
+ // UNIT
+ // Units are appended to a VALUE.
+ // Determine factor to default unit if unit for value is given.
+ // Example: Default is mm, unit is inch: factor is 25.4
+ // The factor is assigned to the terminal UNIT. The actual
+ // conversion is done within a parser action.
+ retval.token = UNIT;
+ if( m_defaultUnits == Unit::Metric )
+ {
+ switch( convertFrom )
+ {
+ case Unit::Inch :retval.value.dValue = 25.4; break;
+ case Unit::Mil :retval.value.dValue = 25.4 / 1000.0; break;
+ case Unit::Metric :retval.value.dValue = 1.0; break;
+ case Unit::Invalid :break;
+ }
+ }
+ else if( m_defaultUnits == Unit::Inch )
+ {
+ switch( convertFrom )
+ {
+ case Unit::Inch :retval.value.dValue = 1.0; break;
+ case Unit::Mil :retval.value.dValue = 1.0 / 1000.0; break;
+ case Unit::Metric :retval.value.dValue = 1.0 / 25.4; break;
+ case Unit::Invalid :break;
+ }
+ }
+ else if( m_defaultUnits == Unit::Mil )
+ {
+ switch( convertFrom )
+ {
+ case Unit::Inch :retval.value.dValue = 1.0 * 1000.0; break;
+ case Unit::Mil :retval.value.dValue = 1.0; break;
+ case Unit::Metric :retval.value.dValue = 1000.0 / 25.4; break;
+ case Unit::Invalid :break;
+ }
+ }
+ }
+ else if( isalpha( ch ))
+ {
+ // VAR
+ const char* cptr = &m_token.input[ m_token.pos ];
+ cptr++;
+
+ while( isalnum( *cptr ))
+ cptr++;
+
+ retval.token = VAR;
+ size_t bytesToCopy = cptr - &m_token.input[ m_token.pos ];
+
+ if( bytesToCopy >= sizeof( retval.value.text ))
+ bytesToCopy = sizeof( retval.value.text ) - 1;
+
+ strncpy( retval.value.text, &m_token.input[ m_token.pos ], bytesToCopy );
+ retval.value.text[ bytesToCopy ] = 0;
+ m_token.pos += cptr - &m_token.input[ m_token.pos ];
+ }
+ else
+ {
+ // Single char tokens
+ switch( ch )
+ {
+ case '+' :retval.token = PLUS; break;
+ case '-' :retval.token = MINUS; break;
+ case '*' :retval.token = MULT; break;
+ case '/' :retval.token = DIVIDE; break;
+ case '(' :retval.token = PARENL; break;
+ case ')' :retval.token = PARENR; break;
+ case '=' :retval.token = ASSIGN; break;
+ case ';' :retval.token = SEMCOL; break;
+ default :m_parseError = true; break; /* invalid character */
+ }
+ m_token.pos++;
+ }
+
+ return retval;
}
-bool
-NumericEvaluator :: process(const char* s, const void* pObj)
+void NUMERIC_EVALUATOR::SetVar( const wxString& aString, double aValue )
{
- if (bClTextInputStorage) // Store input string for (text entry) pObj.
- clObjMap[pObj] = s;
- return process(s);
+ m_varMap[ aString ] = aValue;
}
-void
-NumericEvaluator :: newString(const char* s)
+double NUMERIC_EVALUATOR::GetVar( const wxString& aString )
{
- clear();
- auto len = strlen(s);
- clToken.token = reinterpret_cast(malloc(TokenStat::OutLen+1));
- strcpy(clToken.token, "0");
- clToken.inputLen = len;
- clToken.pos = 0;
- clToken.input = s;
- bClParseFinished = false;
-}
-
-NumericEvaluator::Token NumericEvaluator::getToken()
-{
- Token retval;
- size_t idx;
-
- retval.token = ENDS;
- retval.value.dValue = 0;
-
- if (clToken.token == nullptr) return retval;
- if (clToken.input == nullptr) return retval;
- if (clToken.pos >= clToken.inputLen) return retval;
-
- auto isDecSep = [&](char ch) -> bool {
- if (ch == cClDecSep) return true;
- if (cClDecSep == ',' && ch == '.') return true;
- return false;
- };
-
- // Lambda: get value as string, store into clToken.token and update current index.
- auto extractNumber = [&]() {
- short sepCount = 0;
- idx = 0;
- auto ch = clToken.input[clToken.pos];
- do {
- if (ch == isDecSep(ch) && sepCount) break;
- clToken.token[idx++] = ch;
- if (isDecSep(ch)) sepCount++;
- ch = clToken.input[++clToken.pos];
- } while (isdigit(ch) || isDecSep(ch));
- clToken.token[idx] = 0;
-
- // Ensure that the systems decimal separator is used
- for (int i = strlen(clToken.token); i; i--) if (isDecSep(clToken.token[i-1])) clToken.token[i-1] = cClDecSep;
- };
-
- // Lamda: Get unit for current token.
- // Valid units are ", in, mm, mil and thou. Returns Unit::Invalid otherwise.
- auto checkUnit = [this]() -> Unit {
- char ch = clToken.input[clToken.pos];
- if (ch == '"') {
- clToken.pos++;
- return Unit::Inch;
- }
- // Do not use strcasecmp() as it is not available on all platforms
- const char* cptr = &clToken.input[clToken.pos];
- const auto sizeLeft = clToken.inputLen - clToken.pos;
- if (sizeLeft >= 2 && ch == 'm' && tolower(cptr[1]) == 'm' && !isalnum(cptr[2])) {
- clToken.pos += 2;
- return Unit::Metric;
- }
- if (sizeLeft >= 2 && ch == 'i' && tolower(cptr[1]) == 'n' && !isalnum(cptr[2])) {
- clToken.pos += 2;
- return Unit::Inch;
- }
- if (sizeLeft >= 3 && ch == 'm' && tolower(cptr[1]) == 'i' && tolower(cptr[2]) == 'l' && !isalnum(cptr[3])) {
- clToken.pos += 3;
- return Unit::Mil;
- }
- if (sizeLeft >= 4 && ch == 't' && tolower(cptr[1]) == 'h' && tolower(cptr[2]) == 'o' && tolower(cptr[2]) == 'u' && !isalnum(cptr[3])) {
- clToken.pos += 4;
- return Unit::Mil;
- }
-
- return Unit::Invalid;
- };
-
- // Start processing of first/next token: Remove whitespace
- char ch;
- for (;;) {
- ch = clToken.input[clToken.pos];
- if (ch == ' ') {
- clToken.pos++;
- }
- else break;
- }
-
- Unit convertFrom;
-
- if (ch == 0) {
- /* End of input */
- }
- else if (isdigit(ch) || isDecSep(ch)) { // VALUE
- extractNumber();
- retval.token = VALUE;
- retval.value.dValue = atof(clToken.token);
- }
- else if ((convertFrom = checkUnit()) != Unit::Invalid) { // UNIT
- /* Units are appended to a VALUE.
- * Determine factor to default unit if unit for value is given.
- * Example: Default is mm, unit is inch: factor is 25.4
- * The factor is assigned to the terminal UNIT. The actual
- * conversion is done within a parser action.
- */
- retval.token = UNIT;
- if (eClUnitDefault == Unit::Metric)
- {
- switch (convertFrom) {
- case Unit::Inch : retval.value.dValue = 25.4; break;
- case Unit::Mil : retval.value.dValue = 25.4/1000.0; break;
- case Unit::Metric : retval.value.dValue = 1.0; break;
- case Unit::Invalid : break;
- }
- }
- else if (eClUnitDefault == Unit::Inch)
- {
- switch (convertFrom) {
- case Unit::Inch : retval.value.dValue = 1.0; break;
- case Unit::Mil : retval.value.dValue = 1.0/1000.0; break;
- case Unit::Metric : retval.value.dValue = 1.0/25.4; break;
- case Unit::Invalid : break;
- }
- }
- else if (eClUnitDefault == Unit::Mil)
- {
- switch (convertFrom)
- {
- case Unit::Inch : retval.value.dValue = 1.0*1000.0; break;
- case Unit::Mil : retval.value.dValue = 1.0; break;
- case Unit::Metric : retval.value.dValue = 1000.0/25.4; break;
- case Unit::Invalid : break;
- }
- }
- }
- else if (isalpha(ch)) { // VAR
- const char* cptr = &clToken.input[clToken.pos];
- cptr++;
- while (isalnum(*cptr)) cptr++;
- retval.token = VAR;
- size_t bytesToCopy = cptr - &clToken.input[clToken.pos];
- if (bytesToCopy >= sizeof(retval.value.text)) bytesToCopy = sizeof(retval.value.text)-1;
- strncpy(retval.value.text, &clToken.input[clToken.pos], bytesToCopy);
- retval.value.text[bytesToCopy] = 0;
- clToken.pos += cptr - &clToken.input[clToken.pos];
- }
- else { // Single char tokens
- switch (ch) {
- case '+' : retval.token = PLUS; break;
- case '-' : retval.token = MINUS; break;
- case '*' : retval.token = MULT; break;
- case '/' : retval.token = DIVIDE; break;
- case '(' : retval.token = PARENL; break;
- case ')' : retval.token = PARENR; break;
- case '=' : retval.token = ASSIGN; break;
- case ';' : retval.token = SEMCOL; break;
- default: bClError = true; break; /* invalid character */
- }
- clToken.pos++;
- }
-
- return retval;
-}
-
-void
-NumericEvaluator :: setVar(const std::string& s, double value)
-{
- clVarMap[s] = value;
-}
-
-double
-NumericEvaluator :: getVar(const std::string& s)
-{
- auto result = clVarMap.find(s);
- if (result != clVarMap.end()) return result->second;
- return 0.0;
+ if( m_varMap[ aString ] )
+ return m_varMap[ aString ];
+ else
+ return 0.0;
}
diff --git a/common/widgets/text_ctrl_eval.cpp b/common/widgets/text_ctrl_eval.cpp
index 6ebba2575b..73a660935f 100644
--- a/common/widgets/text_ctrl_eval.cpp
+++ b/common/widgets/text_ctrl_eval.cpp
@@ -27,7 +27,8 @@
TEXT_CTRL_EVAL::TEXT_CTRL_EVAL( wxWindow* aParent, wxWindowID aId, const
wxString& aValue, const wxPoint& aPos, const wxSize& aSize, long aStyle,
const wxValidator& aValidator, const wxString& aName )
- : wxTextCtrl( aParent, aId, aValue, aPos, aSize, aStyle | wxTE_PROCESS_ENTER, aValidator, aName )
+ : wxTextCtrl( aParent, aId, aValue, aPos, aSize, aStyle | wxTE_PROCESS_ENTER, aValidator, aName ),
+ m_eval( g_UserUnit )
{
Connect( wxEVT_SET_FOCUS,
wxFocusEventHandler( TEXT_CTRL_EVAL::onTextFocusGet ), NULL, this );
@@ -38,19 +39,19 @@ TEXT_CTRL_EVAL::TEXT_CTRL_EVAL( wxWindow* aParent, wxWindowID aId, const
}
-void TEXT_CTRL_EVAL::SetValue( const wxString& aValue )
-{
- wxTextCtrl::SetValue( aValue );
- m_eval.clear( this );
-}
-
-
+void TEXT_CTRL_EVAL::SetValue( const wxString& aValue )
+{
+ wxTextCtrl::SetValue( aValue );
+ m_eval.Clear();
+}
+
+
void TEXT_CTRL_EVAL::onTextFocusGet( wxFocusEvent& aEvent )
{
- auto oldStr = m_eval.textInput( this );
+ wxString oldStr = m_eval.OriginalText();
- if( oldStr )
- wxTextCtrl::SetValue( wxString::FromUTF8( oldStr ) );
+ if( oldStr.length() )
+ SetValue( oldStr );
aEvent.Skip();
}
@@ -76,8 +77,8 @@ void TEXT_CTRL_EVAL::onTextEnter( wxCommandEvent& aEvent )
void TEXT_CTRL_EVAL::evaluate()
{
if( GetValue().IsEmpty() )
- wxTextCtrl::SetValue( "0" );
+ wxTextCtrl::SetValue( "0" );
- if( m_eval.process( GetValue().mb_str(), this ) )
- wxTextCtrl::SetValue( wxString::FromUTF8( m_eval.result() ) );
+ if( m_eval.Process( GetValue() ) )
+ SetValue( m_eval.Result() );
}
diff --git a/common/widgets/unit_binder.cpp b/common/widgets/unit_binder.cpp
index 3d134e85eb..eabaab88e3 100644
--- a/common/widgets/unit_binder.cpp
+++ b/common/widgets/unit_binder.cpp
@@ -65,10 +65,10 @@ void UNIT_BINDER::onSetFocus( wxFocusEvent& aEvent )
{
if( m_allowEval )
{
- auto oldStr = m_eval.textInput( this );
+ wxString oldStr = m_eval.OriginalText();
- if( oldStr )
- m_textEntry->SetValue( wxString::FromUTF8( oldStr ) );
+ if( oldStr.length() )
+ m_textEntry->SetValue( oldStr );
}
aEvent.Skip();
@@ -104,10 +104,10 @@ void UNIT_BINDER::onTextEnter( wxCommandEvent& aEvent )
void UNIT_BINDER::evaluate()
{
if( m_textEntry->GetValue().IsEmpty() )
- m_textEntry->SetValue( "0" );
+ m_textEntry->ChangeValue( "0" );
- if( m_eval.process( m_textEntry->GetValue().mb_str(), this ) )
- m_textEntry->SetValue( wxString::FromUTF8( m_eval.result() ) );
+ if( m_eval.Process( m_textEntry->GetValue() ) )
+ m_textEntry->ChangeValue( m_eval.Result() );
}
@@ -137,7 +137,7 @@ bool UNIT_BINDER::Validate( bool setFocusOnError )
{
wxString msg = wxString::Format( _( "%s must be larger than %s." ),
valueDescriptionFromLabel( m_label ),
- StringFromValue( EDA_UNITS_T::MILLIMETRES, m_min, true ) );
+ StringFromValue( m_units, m_min, true ) );
DisplayError( textInput->GetParent(), msg );
if( setFocusOnError )
@@ -154,7 +154,7 @@ bool UNIT_BINDER::Validate( bool setFocusOnError )
{
wxString msg = wxString::Format( _( "%s must be smaller than %s." ),
valueDescriptionFromLabel( m_label ),
- StringFromValue( EDA_UNITS_T::MILLIMETRES, m_max, true ) );
+ StringFromValue( m_units, m_max, true ) );
DisplayError( textInput->GetParent(), msg );
if( setFocusOnError )
@@ -182,7 +182,7 @@ void UNIT_BINDER::SetValue( wxString aValue )
m_textEntry->SetValue( aValue );
if( m_allowEval )
- m_eval.clear();
+ m_eval.Clear();
m_unitLabel->SetLabel( GetAbbreviatedUnitsLabel( m_units, m_useMils ) );
}
diff --git a/include/libeval/numeric_evaluator.h b/include/libeval/numeric_evaluator.h
index e2ffbdf5b6..4de591fca1 100644
--- a/include/libeval/numeric_evaluator.h
+++ b/include/libeval/numeric_evaluator.h
@@ -80,39 +80,32 @@ Supported units are millimeters (mm), Mil (mil) and inch (")
namespace numEval
{
-struct TokenType
-{
- union {
- double dValue;
- int iValue;
- };
+ struct TokenType
+ {
+ union
+ {
+ double dValue;
+ int iValue;
+ };
- bool valid;
- char text[32];
-};
+ bool valid;
+ char text[32];
+ };
} // namespace numEval
-class NumericEvaluator {
- enum class Unit { Invalid, Metric, Inch, Mil };
+class NUMERIC_EVALUATOR
+{
+ enum class Unit { Invalid, Metric, Inch, Mil };
public:
- NumericEvaluator();
- NumericEvaluator( EDA_UNITS_T aUnits, bool aUseMils );
- ~NumericEvaluator();
+ NUMERIC_EVALUATOR( EDA_UNITS_T aUnits, bool aUseMils = false );
+ ~NUMERIC_EVALUATOR();
/* clear() should be invoked by the client if a new input string is to be processed. It
* will reset the parser. User defined variables are retained.
*/
- void clear(const void* pObj = nullptr);
-
- /* Set the decimal separator for the input string. Defaults to '.' */
- void setDecimalSeparator(char sep);
-
- /* Enable or disable support for input string storage.
- * If enabled the input string is saved if process(const char*, const void*) is used.
- */
- void enableTextInputStorage(bool w) { bClTextInputStorage = w; }
+ void Clear();
/* Used by the lemon parser */
void parseError(const char* s);
@@ -120,83 +113,76 @@ public:
void parseSetResult(double);
/* Check if previous invokation of process() was successful */
- inline bool isValid() const { return !bClError; }
+ inline bool IsValid() const { return !m_parseError; }
/* Result of string processing. Undefined if !isValid() */
- inline const char* result() const { return clToken.token; }
-
- /* Numeric result of string processing, in default units. */
- inline const double value() const { return resultValue; }
+ inline wxString Result() const { return wxString::FromUTF8( m_token.token ); }
/* Evaluate input string.
* Result can be retrieved by result().
* Returns true if input string could be evaluated, otherwise false.
*/
- bool process(const char* s);
+ bool Process( const wxString& aString );
- /* Like process(const char*) but also stores input string in a std:map with key pObj. */
- bool process(const char* s, const void* pObj);
-
- /* Retrieve old input string with key pObj. */
- const char* textInput(const void* pObj) const;
+ /* Retrieve the original text before evaluation. */
+ wxString OriginalText() const;
/* Add/set variable with value */
- void setVar(const std::string&, double value);
+ void SetVar( const wxString& aString, double aValue );
/* Get value of variable. Returns 0.0 if not defined. */
- double getVar(const std::string&);
+ double GetVar( const wxString& aString );
/* Remove single variable */
- void removeVar(const std::string& s) { clVarMap.erase(s); }
+ void RemoveVar( const wxString& aString ) { m_varMap.erase( aString ); }
/* Remove all variables */
- void clearVar() { clVarMap.clear(); }
+ void ClearVar() { m_varMap.clear(); }
protected:
- /* Token type used by the tokenizer */
- struct Token {
+ /* Token type used by the tokenizer */
+ struct Token
+ {
int token;
numEval::TokenType value;
};
/* Begin processing of a new input string */
- void newString(const char* s);
+ void newString( const wxString& aString );
/* Tokenizer: Next token/value taken from input string. */
Token getToken();
/* Used by processing loop */
- void parse(int token, numEval::TokenType value);
+ void parse( int token, numEval::TokenType value );
private:
- void* pClParser; // the current lemon parser state machine
+ void* m_parser; // the current lemon parser state machine
/* Token state for input string. */
- struct TokenStat {
- enum { OutLen=32 };
- TokenStat() : input(0), token(0), inputLen(0), pos(0) { /* empty */ }
- const char* input; // current input string ("var=4")
- char* token; // output token ("var", type:VAR; "4", type:VALUE)
- size_t inputLen; // strlen(input)
- size_t pos; // current index
- } clToken;
+ struct TokenStat
+ {
+ enum { OutLen = 32 };
+ TokenStat() : input( 0 ), token( 0 ), inputLen( 0 ), pos( 0 ) { /* empty */ }
+ const char* input; // current input string ("var=4")
+ char* token; // output token ("var", type:VAR; "4", type:VALUE)
+ size_t inputLen; // strlen(input)
+ size_t pos; // current index
+ }
+ m_token;
- char cClDecSep; // decimal separator ('.')
+ char m_localeDecimalSeparator;
/* Parse progress. Set by parser actions. */
- bool bClError;
- bool bClParseFinished;
+ bool m_parseError;
+ bool m_parseFinished;
- /* The result (in eClUnitDefault units) */
- int resultValue;
+ Unit m_defaultUnits; // Default unit for values
- bool bClTextInputStorage; // Enable input string storage used by process(const char*, const void*)
+ wxString m_originalText;
- Unit eClUnitDefault; // Default unit for values
-
- std::map clObjMap; // Map pointer to text entry -> (original) input string
- std::map clVarMap;
+ std::map m_varMap;
};
-#endif /* NUMERIC_EVALUATOR_H_ */
+#endif /* NUMERIC_EVALUATOR_H_ */
\ No newline at end of file
diff --git a/include/widgets/text_ctrl_eval.h b/include/widgets/text_ctrl_eval.h
index 0ad727198f..9a46b066b9 100644
--- a/include/widgets/text_ctrl_eval.h
+++ b/include/widgets/text_ctrl_eval.h
@@ -57,7 +57,7 @@ public:
protected:
///> Numeric expression evaluator
- NumericEvaluator m_eval;
+ NUMERIC_EVALUATOR m_eval;
void onTextFocusGet( wxFocusEvent& aEvent );
void onTextFocusLost( wxFocusEvent& aEvent );
diff --git a/include/widgets/unit_binder.h b/include/widgets/unit_binder.h
index f0c97e962b..bd65c426dc 100644
--- a/include/widgets/unit_binder.h
+++ b/include/widgets/unit_binder.h
@@ -121,7 +121,7 @@ protected:
int m_max;
///> Evaluator
- NumericEvaluator m_eval;
+ NUMERIC_EVALUATOR m_eval;
bool m_allowEval;
};
diff --git a/pcbnew/class_module.cpp b/pcbnew/class_module.cpp
index eaa46517ae..02d844d747 100644
--- a/pcbnew/class_module.cpp
+++ b/pcbnew/class_module.cpp
@@ -1022,7 +1022,6 @@ const BOX2I MODULE::ViewBBox() const
area.Inflate( biggest_clearance );
}
-
return area;
}