Browse Source

Allow parsing into existing elements

Dimensions are parsed before the text elements embedded in them are.  So
we need to handle the existing pointer without copying to avoid dangling
pointers in the font map later.  Based on suggested patch from
@charrasjp

Fixes https://gitlab.com/kicad/code/kicad/-/issues/18853
pcb_db
Seth Hillbrand 1 year ago
parent
commit
1a24c99a2a
  1. 24
      pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.cpp
  2. 2
      pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.h

24
pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.cpp

@ -3296,7 +3296,7 @@ PCB_REFERENCE_IMAGE* PCB_IO_KICAD_SEXPR_PARSER::parsePCB_REFERENCE_IMAGE( BOARD_
}
PCB_TEXT* PCB_IO_KICAD_SEXPR_PARSER::parsePCB_TEXT( BOARD_ITEM* aParent )
PCB_TEXT* PCB_IO_KICAD_SEXPR_PARSER::parsePCB_TEXT( BOARD_ITEM* aParent, PCB_TEXT* aBaseText )
{
wxCHECK_MSG( CurTok() == T_gr_text || CurTok() == T_fp_text, nullptr,
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as PCB_TEXT." ) );
@ -3306,7 +3306,12 @@ PCB_TEXT* PCB_IO_KICAD_SEXPR_PARSER::parsePCB_TEXT( BOARD_ITEM* aParent )
T token = NextTok();
if( parentFP )
// If a base text is provided, we have a derived text already parsed and just need to update it
if( aBaseText )
{
text = std::unique_ptr<PCB_TEXT>( aBaseText );
}
else if( parentFP )
{
switch( token )
{
@ -3930,24 +3935,18 @@ PCB_DIMENSION_BASE* PCB_IO_KICAD_SEXPR_PARSER::parseDIMENSION( BOARD_ITEM* aPare
case T_gr_text:
{
PCB_TEXT* text = parsePCB_TEXT( m_board );
dim->EDA_TEXT::operator=( *text );
// Fetch other dim properties out of the text item
dim->SetTextPos( text->GetTextPos() );
parsePCB_TEXT( m_board, dim.get() );
if( isLegacyDimension )
{
EDA_UNITS units = EDA_UNITS::MILLIMETRES;
if( !EDA_UNIT_UTILS::FetchUnitsFromString( text->GetText(), units ) )
if( !EDA_UNIT_UTILS::FetchUnitsFromString( dim->GetText(), units ) )
dim->SetAutoUnits( true ); //Not determined => use automatic units
dim->SetUnits( units );
}
delete text;
break;
}
@ -4503,8 +4502,13 @@ FOOTPRINT* PCB_IO_KICAD_SEXPR_PARSER::parseFOOTPRINT_unchecked( wxArrayString* a
// with no text effects, but will also handle parsing the text effects. We just drop the effects
// if they're present.
PCB_FIELD ignored = PCB_FIELD( footprint.get(), footprint->GetFieldCount(), pName );
parsePCB_TEXT_effects( &ignored );
// This doesn't currently happen, but if it does, we don't want to leave a dangling pointer in the map
if( auto it = m_fontTextMap.find( &ignored ); it != m_fontTextMap.end() )
m_fontTextMap.erase( it );
break;
}

2
pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.h

@ -217,7 +217,7 @@ private:
void parseTextBoxContent( PCB_TEXTBOX* aTextBox );
PCB_SHAPE* parsePCB_SHAPE( BOARD_ITEM* aParent );
PCB_TEXT* parsePCB_TEXT( BOARD_ITEM* aParent );
PCB_TEXT* parsePCB_TEXT( BOARD_ITEM* aParent, PCB_TEXT* aBaseText = nullptr );
void parsePCB_TEXT_effects( PCB_TEXT* aText );
PCB_REFERENCE_IMAGE* parsePCB_REFERENCE_IMAGE( BOARD_ITEM* aParent );
PCB_TEXTBOX* parsePCB_TEXTBOX( BOARD_ITEM* aParent );

Loading…
Cancel
Save