Eeschema: fix and other case where the UFT8 strings are not correctly read on Windows (part name and ref in schematic files correctly saved but not correctly read)

This commit is contained in:
jean-pierre charras 2015-08-13 12:48:14 +02:00
parent e342744a32
commit ef0e13331d
2 changed files with 54 additions and 50 deletions

View File

@ -721,7 +721,6 @@ bool LIB_PIN::Save( OUTPUTFORMATTER& aFormatter )
bool LIB_PIN::Load( LINE_READER& aLineReader, wxString& aErrorMsg ) bool LIB_PIN::Load( LINE_READER& aLineReader, wxString& aErrorMsg )
{ {
int i, j;
char pinAttrs[64]; char pinAttrs[64];
char pinOrient[64]; char pinOrient[64];
char pinType[64]; char pinType[64];
@ -738,11 +737,11 @@ bool LIB_PIN::Load( LINE_READER& aLineReader, wxString& aErrorMsg )
// the full line starts by "X ". The pin data starts at line + 2. // the full line starts by "X ". The pin data starts at line + 2.
wxString utf8line = FROM_UTF8( aLineReader.Line() + 2 ); wxString utf8line = FROM_UTF8( aLineReader.Line() + 2 );
wxStringTokenizer tokenizer( utf8line, wxT(" \n\r" ) ); wxStringTokenizer tokenizer( utf8line, wxT(" \n\r" ) );
i = tokenizer.CountTokens(); int prms_count = tokenizer.CountTokens();
if( i < 11 ) if( prms_count < 11 )
{ {
aErrorMsg.Printf( wxT( "pin had %d parameters of the required 11 or 12" ), i ); aErrorMsg.Printf( wxT( "pin had %d parameters of the required 11 or 12" ), prms_count );
return false; return false;
} }
@ -767,10 +766,15 @@ bool LIB_PIN::Load( LINE_READER& aLineReader, wxString& aErrorMsg )
strncpy( line, TO_UTF8( tmp ), len ); strncpy( line, TO_UTF8( tmp ), len );
line[len] = 0; line[len] = 0;
sscanf( line, "%d %d %d %63s %d %d %d %d %63s %63s", int cnt = sscanf( line, "%d %d %d %63s %d %d %d %d %63s %63s",
&m_position.x, &m_position.y, &m_length, pinOrient, &m_numTextSize, &m_position.x, &m_position.y, &m_length, pinOrient, &m_numTextSize,
&m_nameTextSize, &m_Unit, &m_Convert, pinType, pinAttrs ); &m_nameTextSize, &m_Unit, &m_Convert, pinType, pinAttrs );
if( cnt != (prms_count - 2) )
{
aErrorMsg.Printf( wxT( "pin parameters read issue" ) );
return false;
}
m_orientation = pinOrient[0] & 255; m_orientation = pinOrient[0] & 255;
@ -825,9 +829,9 @@ bool LIB_PIN::Load( LINE_READER& aLineReader, wxString& aErrorMsg )
return false; return false;
} }
if( i == 12 ) /* Special Symbol defined */ if( prms_count >= 12 ) /* Special Symbol defined */
{ {
for( j = strlen( pinAttrs ); j > 0; ) for( int j = strlen( pinAttrs ); j > 0; )
{ {
switch( pinAttrs[--j] ) switch( pinAttrs[--j] )
{ {

View File

@ -1130,8 +1130,11 @@ bool SCH_COMPONENT::Save( FILE* f ) const
bool SCH_COMPONENT::Load( LINE_READER& aLine, wxString& aErrorMsg ) bool SCH_COMPONENT::Load( LINE_READER& aLine, wxString& aErrorMsg )
{ {
// Remark: avoid using sscanf to read texts entered by user
// which are UTF8 encoded, because sscanf does not work well on Windows
// with some UTF8 values.
int ii; int ii;
char name1[256], name2[256], char name1[256],
char1[256], char2[256], char3[256]; char1[256], char2[256], char3[256];
int newfmt = 0; int newfmt = 0;
char* ptcar; char* ptcar;
@ -1148,7 +1151,20 @@ bool SCH_COMPONENT::Load( LINE_READER& aLine, wxString& aErrorMsg )
return true; return true;
} }
if( sscanf( &line[1], "%255s %255s", name1, name2 ) != 2 ) // Parse the first line of description:
// like "L partname ref" (for instance "L 74LS00 U4"
// They are UTF8 texts, so do not use sscanf
line += 1;
if( *line == ' ' )
line++;
// line points the first parameter
wxString buffer( FROM_UTF8( line ) );
wxStringTokenizer tokenizer( buffer, wxT( " \r\n" ) );
if( tokenizer.CountTokens() < 2 )
{ {
aErrorMsg.Printf( wxT( "Eeschema component description error at line %d, aborted" ), aErrorMsg.Printf( wxT( "Eeschema component description error at line %d, aborted" ),
aLine.LineNumber() ); aLine.LineNumber() );
@ -1156,18 +1172,15 @@ bool SCH_COMPONENT::Load( LINE_READER& aLine, wxString& aErrorMsg )
return false; return false;
} }
if( strcmp( name1, NULL_STRING ) != 0 ) wxString partname = tokenizer.NextToken();
{ partname.Replace( wxT("~"), wxT(" ") ); // all spaces were replaced by ~ in files.
for( ii = 0; ii < (int) strlen( name1 ); ii++ )
{
if( name1[ii] == '~' )
name1[ii] = ' ';
}
SetPartName( FROM_UTF8( name1 ) ); if( partname != NULL_STRING )
{
SetPartName( partname );
if( !newfmt ) if( !newfmt )
GetField( VALUE )->SetText( FROM_UTF8( name1 ) ); GetField( VALUE )->SetText( partname );
} }
else else
{ {
@ -1177,48 +1190,35 @@ bool SCH_COMPONENT::Load( LINE_READER& aLine, wxString& aErrorMsg )
GetField( VALUE )->SetVisible( false ); GetField( VALUE )->SetVisible( false );
} }
if( strcmp( name2, NULL_STRING ) != 0 ) wxString reference = tokenizer.NextToken();
{ reference.Replace( wxT("~"), wxT(" ") ); // all spaces were replaced by ~ in files.
bool isDigit = false; reference.Trim( true );
reference.Trim( false );
for( ii = 0; ii < (int) strlen( name2 ); ii++ ) if( reference != NULL_STRING )
{ {
if( name2[ii] == '~' ) wxString prefix = reference;
name2[ii] = ' '; // Build reference prefix from the actual reference by removing trailing digits
// (Perhaps outdated code, only for very old schematic files)
while( prefix.Length() )
{
if( ( prefix.Last() < '0' || prefix.Last() > '9') && prefix.Last() != '?' )
break;
// get RefBase from this, too. store in name1. prefix.RemoveLast();
if( name2[ii] >= '0' && name2[ii] <= '9' )
{
isDigit = true;
name1[ii] = 0; //null-terminate.
} }
if( !isDigit ) // Avoid a prefix containing trailing/leading spaces
{ prefix.Trim( true );
name1[ii] = name2[ii]; prefix.Trim( false );
}
}
name1[ii] = 0; //just in case if( prefix.IsEmpty() )
int jj;
for( jj = 0; jj<ii && name1[jj] == ' '; jj++ )
;
if( jj == ii )
{
// blank string.
m_prefix = wxT( "U" ); m_prefix = wxT( "U" );
}
else else
{ m_prefix = prefix;
m_prefix = FROM_UTF8( &name1[jj] );
//printf("prefix: %s\n", TO_UTF8(component->m_prefix));
}
if( !newfmt ) if( !newfmt )
GetField( REFERENCE )->SetText( FROM_UTF8( name2 ) ); GetField( REFERENCE )->SetText( reference );
} }
else else
{ {