Followed-by-3-digits doesn't guarantee a thousands separator.

Fixes https://gitlab.com/kicad/code/kicad/issues/13708
This commit is contained in:
Jeff Young 2023-01-30 21:09:36 +00:00
parent 44cfb1ea43
commit c939b1ef76
2 changed files with 73 additions and 15 deletions

View File

@ -1131,43 +1131,98 @@ bool SIM_MODEL::InferSimModel( T_symbol& aSymbol, std::vector<T_field>* aFields,
{ {
mantissa->Replace( wxS( " " ), wxEmptyString ); mantissa->Replace( wxS( " " ), wxEmptyString );
wxChar ambiguousSeparator = '?';
wxChar thousandsSeparator = '?'; wxChar thousandsSeparator = '?';
bool thousandsSeparatorFound = false;
wxChar decimalSeparator = '?'; wxChar decimalSeparator = '?';
int length = (int) mantissa->length(); bool decimalSeparatorFound = false;
int radix = length; int digits = 0;
for( int ii = length - 1; ii >= 0; --ii ) for( int ii = (int) mantissa->length() - 1; ii >= 0; --ii )
{ {
wxChar c = mantissa->GetChar( ii ); wxChar c = mantissa->GetChar( ii );
if( c == '.' || c == ',' ) if( c >= '0' && c <= '9' )
{ {
if( ( radix - ii ) % 4 == 0 ) digits += 1;
}
else if( c == '.' || c == ',' )
{ {
if( thousandsSeparator == '?' ) if( decimalSeparator != '?' || thousandsSeparator != '?' )
{ {
thousandsSeparator = c; // We've previously found a non-ambiguous separator...
if( c == decimalSeparator )
{
if( thousandsSeparatorFound )
return false; // decimal before thousands
else if( decimalSeparatorFound )
return false; // more than one decimal
else
decimalSeparatorFound = true;
}
else if( c == thousandsSeparator )
{
if( digits != 3 )
return false; // thousands not followed by 3 digits
else
thousandsSeparatorFound = true;
}
}
else if( ambiguousSeparator != '?' )
{
// We've previously found a separator, but we don't know for sure
// which...
if( c == ambiguousSeparator )
{
// They both must be thousands separators
thousandsSeparator = ambiguousSeparator;
thousandsSeparatorFound = true;
decimalSeparator = c == '.' ? ',' : '.'; decimalSeparator = c == '.' ? ',' : '.';
} }
else if( thousandsSeparator != c ) else
{ {
return false; // The first must have been a decimal, and this must be a
// thousands.
decimalSeparator = ambiguousSeparator;
decimalSeparatorFound = true;
thousandsSeparator = c;
thousandsSeparatorFound = true;
} }
} }
else else
{ {
if( decimalSeparator == '?' ) // This is the first separator...
// If it's followed by 3 digits then it could be either.
// Otherwise it -must- be a decimal separator (and the thousands
// separator must be the other).
if( digits == 3 )
{
ambiguousSeparator = c;
}
else
{ {
decimalSeparator = c; decimalSeparator = c;
decimalSeparatorFound = true;
thousandsSeparator = c == '.' ? ',' : '.'; thousandsSeparator = c == '.' ? ',' : '.';
radix = ii; }
}
digits = 0;
} }
else else
{ {
return false; digits = 0;
}
} }
} }
// If we found nothing difinitive then we have to assume SPICE-native syntax
if( decimalSeparator == '?' && thousandsSeparator == '?' )
{
decimalSeparator = '.';
thousandsSeparator = ',';
} }
mantissa->Replace( thousandsSeparator, wxEmptyString ); mantissa->Replace( thousandsSeparator, wxEmptyString );

View File

@ -71,12 +71,15 @@ BOOST_AUTO_TEST_CASE( InferPassiveValues )
{ wxString( "R4" ), wxString( "3,000.5" ), wxString( "r=\"3000.5\"" ) }, { wxString( "R4" ), wxString( "3,000.5" ), wxString( "r=\"3000.5\"" ) },
{ wxString( "R5" ), wxString( "3.000,5" ), wxString( "r=\"3000.5\"" ) }, { wxString( "R5" ), wxString( "3.000,5" ), wxString( "r=\"3000.5\"" ) },
{ wxString( "R6" ), wxString( "3000.5" ), wxString( "r=\"3000.5\"" ) }, { wxString( "R6" ), wxString( "3000.5" ), wxString( "r=\"3000.5\"" ) },
{ wxString( "R7" ), wxString( "3,000K" ), wxString( "r=\"3000K\"" ) },
{ wxString( "R8" ), wxString( "3.000K" ), wxString( "r=\"3.000K\"" ) },
{ wxString( "R9" ), wxString( "3.0,000,000" ), wxString( "" ) },
{ wxString( "X1" ), wxString( "3.3K" ), wxString( "" ) }, { wxString( "X1" ), wxString( "3.3K" ), wxString( "" ) },
{ wxString( "C14" ), wxString( "33,000,000uF" ), wxString( "c=\"33000000u\"" ) }, { wxString( "C14" ), wxString( "33,000,000uF" ), wxString( "c=\"33000000u\"" ) },
{ wxString( "C15" ), wxString( "33 000 000uF" ), wxString( "c=\"33000000u\"" ) }, { wxString( "C15" ), wxString( "33 000 000uF" ), wxString( "c=\"33000000u\"" ) },
{ wxString( "C16" ), wxString( "33.000,000uF" ), wxString( "" ) } { wxString( "C16" ), wxString( "33.000,000uF" ), wxString( "c=\"33000.000u\"" )},
}; };
std::unique_ptr<LIB_SYMBOL> symbol = std::make_unique<LIB_SYMBOL>( "symbol", nullptr ); std::unique_ptr<LIB_SYMBOL> symbol = std::make_unique<LIB_SYMBOL>( "symbol", nullptr );