Eeschema: minor s-expression file format improvements.

I could not find a reasonable solution to the mandatory field canonical
name issue so field indices are back in play as much as I did not want
to use them.  They really only have meaning for the mandatory fields.
For all other fields, the index number is meaningless and the field name
is the primary means for searching.

Fix a broken field size bug in the symbol library formatter.
This commit is contained in:
Wayne Stambaugh 2020-04-05 17:11:31 -04:00
parent 992d141292
commit c9b00e3898
3 changed files with 102 additions and 108 deletions

View File

@ -619,7 +619,8 @@ void SCH_SEXPR_PARSER::parseHeader( TSCHEMATIC_T::T aHeaderType, int aFileVersio
void SCH_SEXPR_PARSER::parsePinNames( std::unique_ptr<LIB_PART>& aSymbol ) void SCH_SEXPR_PARSER::parsePinNames( std::unique_ptr<LIB_PART>& aSymbol )
{ {
wxCHECK_RET( CurTok() == T_pin_names, wxCHECK_RET( CurTok() == T_pin_names,
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a pin_name token." ) ); wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
wxT( " as a pin_name token." ) );
wxString error; wxString error;
@ -661,7 +662,7 @@ void SCH_SEXPR_PARSER::parseProperty( std::unique_ptr<LIB_PART>& aSymbol )
wxString error; wxString error;
wxString name; wxString name;
wxString value; wxString value;
std::unique_ptr<LIB_FIELD> tmp( new LIB_FIELD( MANDATORY_FIELDS ) ); std::unique_ptr<LIB_FIELD> field( new LIB_FIELD( MANDATORY_FIELDS ) );
T token = NextTok(); T token = NextTok();
@ -681,6 +682,7 @@ void SCH_SEXPR_PARSER::parseProperty( std::unique_ptr<LIB_PART>& aSymbol )
THROW_IO_ERROR( error ); THROW_IO_ERROR( error );
} }
field->SetName( name );
token = NextTok(); token = NextTok();
if( !IsSymbol( token ) ) if( !IsSymbol( token ) )
@ -693,39 +695,61 @@ void SCH_SEXPR_PARSER::parseProperty( std::unique_ptr<LIB_PART>& aSymbol )
// Empty property values are valid. // Empty property values are valid.
value = FromUTF8(); value = FromUTF8();
LIB_FIELD* field; field->SetText( value );
if( name == "ki_reference" ) for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{ {
field = &aSymbol->GetReferenceField(); if( token != T_LEFT )
field->SetText( value ); Expecting( T_LEFT );
token = NextTok();
switch( token )
{
case T_id:
field->SetId( parseInt( "field ID" ) );
NeedRIGHT();
break;
case T_at:
field->SetPosition( parseXY() );
field->SetTextAngle( static_cast<int>( parseDouble( "text angle" ) * 10.0 ) );
NeedRIGHT();
break;
case T_effects:
parseEDA_TEXT( static_cast<EDA_TEXT*>( field.get() ) );
break;
default:
Expecting( "id, at or effects" );
}
} }
else if( name == "ki_value" )
LIB_FIELD* existingField;
if( field->GetId() < MANDATORY_FIELDS )
{ {
field = &aSymbol->GetValueField(); existingField = aSymbol->GetField( field->GetId() );
field->SetText( value );
} /// @todo Remove this once the legacy file format is deprecated.
else if( name == "ki_footprint" ) if( field->GetId() == DATASHEET )
{ {
field = &aSymbol->GetFootprintField(); aSymbol->SetDocFileName( value );
field->SetText( value ); field->SetText( wxEmptyString );
} }
else if( name == "ki_datasheet" )
{ *existingField = *field;
field = aSymbol->GetField( DATASHEET );
aSymbol->SetDocFileName( value );
} }
else if( name == "ki_keywords" ) else if( name == "ki_keywords" )
{ {
// Not a LIB_FIELD object yet. // Not a LIB_FIELD object yet.
aSymbol->SetKeyWords( value ); aSymbol->SetKeyWords( value );
field = tmp.get();
} }
else if( name == "ki_description" ) else if( name == "ki_description" )
{ {
// Not a LIB_FIELD object yet. // Not a LIB_FIELD object yet.
aSymbol->SetDescription( value ); aSymbol->SetDescription( value );
field = tmp.get();
} }
else if( name == "ki_fp_filters" ) else if( name == "ki_fp_filters" )
{ {
@ -737,48 +761,24 @@ void SCH_SEXPR_PARSER::parseProperty( std::unique_ptr<LIB_PART>& aSymbol )
filters.Add( tokenizer.GetNextToken() ); filters.Add( tokenizer.GetNextToken() );
aSymbol->SetFootprintFilters( filters ); aSymbol->SetFootprintFilters( filters );
field = tmp.get();
} }
else if( name == "ki_locked" ) else if( name == "ki_locked" )
{ {
// This is a temporary LIB_FIELD object until interchangeable units are determined on
// the fly.
aSymbol->LockUnits( true ); aSymbol->LockUnits( true );
field = tmp.get();
} }
else else
{ {
field = aSymbol->FindField( name ); existingField = aSymbol->GetField( field->GetId() );
if( !field ) if( !existingField )
{ {
field = new LIB_FIELD( m_fieldId, name ); aSymbol->AddDrawItem( field.release() );
aSymbol->AddDrawItem( field );
m_fieldId += 1;
} }
else
field->SetText( value );
}
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
if( token != T_LEFT )
Expecting( T_LEFT );
token = NextTok();
switch( token )
{ {
case T_at: *existingField = *field;
field->SetPosition( parseXY() );
field->SetTextAngle( static_cast<int>( parseDouble( "text angle" ) * 10.0 ) );
NeedRIGHT();
break;
case T_effects:
parseEDA_TEXT( static_cast<EDA_TEXT*>( field ) );
break;
default:
Expecting( "at or effects" );
} }
} }
} }
@ -1646,6 +1646,11 @@ SCH_FIELD* SCH_SEXPR_PARSER::parseSchField()
switch( token ) switch( token )
{ {
case T_id:
field->SetId( parseInt( "field ID" ) );
NeedRIGHT();
break;
case T_at: case T_at:
field->SetPosition( parseXY() ); field->SetPosition( parseXY() );
field->SetTextAngle( static_cast<int>( parseDouble( "text angle" ) * 10.0 ) ); field->SetTextAngle( static_cast<int>( parseDouble( "text angle" ) * 10.0 ) );
@ -1984,46 +1989,23 @@ SCH_COMPONENT* SCH_SEXPR_PARSER::parseSchematicSymbol()
case T_property: case T_property:
{ {
int fieldIndex;
field = parseSchField(); field = parseSchField();
field->SetParent( symbol.get() ); field->SetParent( symbol.get() );
if( field->GetName() == "ki_reference" ) if( field->GetId() == REFERENCE )
{ {
fieldIndex = REFERENCE;
field->SetId( REFERENCE );
field->SetLayer( LAYER_REFERENCEPART ); field->SetLayer( LAYER_REFERENCEPART );
field->SetName( TEMPLATE_FIELDNAME::GetDefaultFieldName( REFERENCE ) );
} }
else if( field->GetName() == "ki_value" ) else if( field->GetId() == VALUE )
{ {
fieldIndex = VALUE;
field->SetId( VALUE );
field->SetLayer( LAYER_VALUEPART ); field->SetLayer( LAYER_VALUEPART );
field->SetName( TEMPLATE_FIELDNAME::GetDefaultFieldName( VALUE ) );
} }
else if( field->GetName() == "ki_footprint" ) else if( field->GetId() >= MANDATORY_FIELDS )
{ {
fieldIndex = FOOTPRINT;
field->SetId( FOOTPRINT );
field->SetName( TEMPLATE_FIELDNAME::GetDefaultFieldName( FOOTPRINT ) );
}
else if( field->GetName() == "ki_datasheet" )
{
fieldIndex = DATASHEET;
field->SetId( DATASHEET );
field->SetName( TEMPLATE_FIELDNAME::GetDefaultFieldName( DATASHEET ) );
}
else
{
fieldIndex = m_fieldId;
field->SetId( m_fieldId );
symbol->AddField( *field ); symbol->AddField( *field );
m_fieldId += 1;
} }
*symbol->GetField( fieldIndex ) = *field; *symbol->GetField( field->GetId() ) = *field;
delete field; delete field;
break; break;
} }

View File

@ -1440,7 +1440,7 @@ void SCH_SEXPR_PLUGIN_CACHE::SaveSymbol( LIB_PART* aSymbol, OUTPUTFORMATTER& aFo
lastFieldId += 1; lastFieldId += 1;
} }
saveDcmInfoAsFields( aSymbol, aFormatter, aNestLevel, fields.back().GetId() + 1 ); saveDcmInfoAsFields( aSymbol, aFormatter, aNestLevel, lastFieldId );
// Save the draw items grouped by units. // Save the draw items grouped by units.
std::vector<PART_UNITS> units = aSymbol->GetUnitDrawItems(); std::vector<PART_UNITS> units = aSymbol->GetUnitDrawItems();
@ -1741,21 +1741,15 @@ void SCH_SEXPR_PLUGIN_CACHE::saveField( LIB_FIELD* aField,
{ {
wxCHECK_RET( aField && aField->Type() == LIB_FIELD_T, "Invalid LIB_FIELD object." ); wxCHECK_RET( aField && aField->Type() == LIB_FIELD_T, "Invalid LIB_FIELD object." );
wxString fieldName = aField->GetCanonicalName(); aFormatter.Print( aNestLevel, "(property %s %s (id %d) (at %s %s %g)",
aFormatter.Quotew( aField->GetName() ).c_str(),
// When saving legacy fields, prefix the field name with "ki_" to prevent name clashes
// with exisiting user defined fields.
if( aField->IsMandatory() && !fieldName.StartsWith( "ki_" ) )
fieldName = "ki_" + fieldName.Lower();
aFormatter.Print( aNestLevel, "(property %s %s (at %s %s %g)",
aFormatter.Quotew( fieldName ).c_str(),
aFormatter.Quotew( aField->GetText() ).c_str(), aFormatter.Quotew( aField->GetText() ).c_str(),
aField->GetId(),
FormatInternalUnits( aField->GetPosition().x ).c_str(), FormatInternalUnits( aField->GetPosition().x ).c_str(),
FormatInternalUnits( aField->GetPosition().y ).c_str(), FormatInternalUnits( aField->GetPosition().y ).c_str(),
static_cast<double>( aField->GetTextAngle() ) / 10.0 ); static_cast<double>( aField->GetTextAngle() ) / 10.0 );
if( aField->IsDefaultFormatting() ) if( aField->IsDefaultFormatting() && ( aField->GetTextHeight() == GetDefaultTextSize() ) )
{ {
aFormatter.Print( 0, ")\n" ); // Close property token if no font effects. aFormatter.Print( 0, ")\n" ); // Close property token if no font effects.
} }
@ -1784,30 +1778,47 @@ void SCH_SEXPR_PLUGIN_CACHE::savePin( LIB_PIN* aPin,
FormatAngle( getPinAngle( aPin->GetOrientation() ) * 10.0 ).c_str(), FormatAngle( getPinAngle( aPin->GetOrientation() ) * 10.0 ).c_str(),
FormatInternalUnits( aPin->GetLength() ).c_str() ); FormatInternalUnits( aPin->GetLength() ).c_str() );
aFormatter.Print( 0, " (name %s", int nestLevel = 0;
aFormatter.Quotew( aPin->GetName() ).c_str() );
// This follows the EDA_TEXT effects formatting for future expansion. if( aPin->GetNameTextSize() != Mils2iu( DEFAULTPINNAMESIZE )
if( aPin->GetNameTextSize() != Mils2iu( DEFAULTPINNAMESIZE ) ) || aPin->GetNumberTextSize() != Mils2iu( DEFAULTPINNUMSIZE ) )
aFormatter.Print( 0, " (effects (font (size %s %s)))", {
FormatInternalUnits( aPin->GetNameTextSize() ).c_str(), aFormatter.Print( 0, "\n" );
FormatInternalUnits( aPin->GetNameTextSize() ).c_str() ); aFormatter.Print( aNestLevel + 1, "(name %s",
aFormatter.Quotew( aPin->GetName() ).c_str() );
aFormatter.Print( 0, ")" ); // This follows the EDA_TEXT effects formatting for future expansion.
aFormatter.Print( 0, " (number %s", if( aPin->GetNameTextSize() != Mils2iu( DEFAULTPINNAMESIZE ) )
aFormatter.Quotew( aPin->GetNumber() ).c_str() ); aFormatter.Print( 0, " (effects (font (size %s %s)))",
FormatInternalUnits( aPin->GetNameTextSize() ).c_str(),
FormatInternalUnits( aPin->GetNameTextSize() ).c_str() );
// This follows the EDA_TEXT effects formatting for future expansion. aFormatter.Print( 0, ")\n" );
if( aPin->GetNumberTextSize() != Mils2iu( DEFAULTPINNUMSIZE ) ) aFormatter.Print( aNestLevel + 1, "(number %s",
aFormatter.Print( 0, " (effects (font (size %s %s)))", aFormatter.Quotew( aPin->GetNumber() ).c_str() );
FormatInternalUnits( aPin->GetNumberTextSize() ).c_str(),
FormatInternalUnits( aPin->GetNumberTextSize() ).c_str() ); // This follows the EDA_TEXT effects formatting for future expansion.
aFormatter.Print( 0, ")" ); if( aPin->GetNumberTextSize() != Mils2iu( DEFAULTPINNUMSIZE ) )
aFormatter.Print( 0, " (effects (font (size %s %s)))",
FormatInternalUnits( aPin->GetNumberTextSize() ).c_str(),
FormatInternalUnits( aPin->GetNumberTextSize() ).c_str() );
aFormatter.Print( 0, ")\n" );
nestLevel = aNestLevel + 1;
}
else
{
aFormatter.Print( 0, " (name %s) (number %s)",
aFormatter.Quotew( aPin->GetName() ).c_str(),
aFormatter.Quotew( aPin->GetNumber() ).c_str() );
}
if( !aPin->IsVisible() ) if( !aPin->IsVisible() )
aFormatter.Print( 0, " hide" ); aFormatter.Print( nestLevel, " hide" );
aFormatter.Print( 0, ")\n" ); if( nestLevel )
nestLevel -= 1;
aFormatter.Print( nestLevel, ")\n" );
} }

View File

@ -35,6 +35,7 @@ hide
hierarchical_label hierarchical_label
hint_alt_swap hint_alt_swap
hint_pin_swap hint_pin_swap
id
image image
input input
input_low input_low