Commit fa846932 authored by Maciej Suminski's avatar Maciej Suminski

bugfix 1325375: pcbnew crash while append a board

parent 9cfd1dc4
...@@ -795,6 +795,11 @@ public: ...@@ -795,6 +795,11 @@ public:
*/ */
NETINFO_ITEM* FindNet( const wxString& aNetname ) const; NETINFO_ITEM* FindNet( const wxString& aNetname ) const;
/**
* Function AppendNet
* adds a new net description item to the current board.
* @param aNewNet is the new description item.
*/
void AppendNet( NETINFO_ITEM* aNewNet ) void AppendNet( NETINFO_ITEM* aNewNet )
{ {
m_NetInfo.AppendNet( aNewNet ); m_NetInfo.AppendNet( aNewNet );
......
...@@ -254,6 +254,7 @@ public: ...@@ -254,6 +254,7 @@ public:
NETINFO_ITEM* GetNetItem( int aNetCode ) const NETINFO_ITEM* GetNetItem( int aNetCode ) const
{ {
NETCODES_MAP::const_iterator result = m_netCodes.find( aNetCode ); NETCODES_MAP::const_iterator result = m_netCodes.find( aNetCode );
if( result != m_netCodes.end() ) if( result != m_netCodes.end() )
return (*result).second; return (*result).second;
...@@ -268,6 +269,7 @@ public: ...@@ -268,6 +269,7 @@ public:
NETINFO_ITEM* GetNetItem( const wxString& aNetName ) const NETINFO_ITEM* GetNetItem( const wxString& aNetName ) const
{ {
NETNAMES_MAP::const_iterator result = m_netNames.find( aNetName ); NETNAMES_MAP::const_iterator result = m_netNames.find( aNetName );
if( result != m_netNames.end() ) if( result != m_netNames.end() )
return (*result).second; return (*result).second;
...@@ -283,7 +285,8 @@ public: ...@@ -283,7 +285,8 @@ public:
/** /**
* Function Append * Function Append
* adds \a aNewElement to the end of the list. * adds \a aNewElement to the end of the list. Negative net code means it is going to be
* auto-assigned.
*/ */
void AppendNet( NETINFO_ITEM* aNewElement ); void AppendNet( NETINFO_ITEM* aNewElement );
...@@ -421,7 +424,7 @@ private: ...@@ -421,7 +424,7 @@ private:
* Function getFreeNetCode * Function getFreeNetCode
* returns the first available net code that is not used by any other net. * returns the first available net code that is not used by any other net.
*/ */
int getFreeNetCode() const; int getFreeNetCode();
BOARD* m_Parent; BOARD* m_Parent;
...@@ -430,6 +433,8 @@ private: ...@@ -430,6 +433,8 @@ private:
std::vector<D_PAD*> m_PadsFullList; ///< contains all pads, sorted by pad's netname. std::vector<D_PAD*> m_PadsFullList; ///< contains all pads, sorted by pad's netname.
///< can be used in ratsnest calculations. ///< can be used in ratsnest calculations.
int m_newNetCode; ///< possible value for new net code assignment
}; };
......
...@@ -45,6 +45,8 @@ NETINFO_LIST::NETINFO_LIST( BOARD* aParent ) : m_Parent( aParent ) ...@@ -45,6 +45,8 @@ NETINFO_LIST::NETINFO_LIST( BOARD* aParent ) : m_Parent( aParent )
{ {
// Make sure that the unconnected net has number 0 // Make sure that the unconnected net has number 0
AppendNet( new NETINFO_ITEM( aParent, wxEmptyString, 0 ) ); AppendNet( new NETINFO_ITEM( aParent, wxEmptyString, 0 ) );
m_newNetCode = 0;
} }
...@@ -63,14 +65,27 @@ void NETINFO_LIST::clear() ...@@ -63,14 +65,27 @@ void NETINFO_LIST::clear()
m_PadsFullList.clear(); m_PadsFullList.clear();
m_netNames.clear(); m_netNames.clear();
m_netCodes.clear(); m_netCodes.clear();
m_newNetCode = 0;
} }
void NETINFO_LIST::AppendNet( NETINFO_ITEM* aNewElement ) void NETINFO_LIST::AppendNet( NETINFO_ITEM* aNewElement )
{ {
// if there is a net with such name then just assign the correct number
NETINFO_ITEM* sameName = GetNetItem( aNewElement->GetNetname() );
if( sameName != NULL )
{
aNewElement->m_NetCode = sameName->GetNet();
return;
}
// be sure that net codes are consecutive
// negative net code means that it has to be auto assigned // negative net code means that it has to be auto assigned
if( aNewElement->m_NetCode < 0 ) else if( ( aNewElement->m_NetCode != (int) m_netCodes.size() ) || ( aNewElement->m_NetCode < 0 ) )
const_cast<int&>( aNewElement->m_NetCode ) = getFreeNetCode(); {
aNewElement->m_NetCode = getFreeNetCode();
}
// net names & codes are supposed to be unique // net names & codes are supposed to be unique
assert( GetNetItem( aNewElement->GetNetname() ) == NULL ); assert( GetNetItem( aNewElement->GetNetname() ) == NULL );
...@@ -201,10 +216,8 @@ void NETINFO_LIST::buildPadsFullList() ...@@ -201,10 +216,8 @@ void NETINFO_LIST::buildPadsFullList()
} }
int NETINFO_LIST::getFreeNetCode() const int NETINFO_LIST::getFreeNetCode()
{ {
static int m_newNetCode = 0;
do { do {
if( m_newNetCode < 0 ) if( m_newNetCode < 0 )
m_newNetCode = 0; m_newNetCode = 0;
......
...@@ -502,13 +502,12 @@ void LEGACY_PLUGIN::loadGENERAL() ...@@ -502,13 +502,12 @@ void LEGACY_PLUGIN::loadGENERAL()
else if( TESTLINE( "Nmodule" ) ) else if( TESTLINE( "Nmodule" ) )
{ {
NbMod = intParse( line + SZ( "Nmodule" ) ); NbMod = intParse( line + SZ( "Nmodule" ) );
} }*/
else if( TESTLINE( "Nnets" ) ) else if( TESTLINE( "Nnets" ) )
{ {
NbNets = intParse( line + SZ( "Nnets" ) ); m_netCodes.resize( intParse( line + SZ( "Nnets" ) ) );
} }
*/
else if( TESTLINE( "$EndGENERAL" ) ) else if( TESTLINE( "$EndGENERAL" ) )
return; // preferred exit return; // preferred exit
...@@ -1305,13 +1304,15 @@ void LEGACY_PLUGIN::loadPAD( MODULE* aModule ) ...@@ -1305,13 +1304,15 @@ void LEGACY_PLUGIN::loadPAD( MODULE* aModule )
char buf[1024]; // can be fairly long char buf[1024]; // can be fairly long
int netcode = intParse( line + SZ( "Ne" ), &data ); int netcode = intParse( line + SZ( "Ne" ), &data );
pad->SetNetCode( netcode ); // Store the new code mapping
pad->SetNetCode( m_netCodes[netcode] );
// read Netname // read Netname
ReadDelimitedText( buf, data, sizeof(buf) ); ReadDelimitedText( buf, data, sizeof(buf) );
#ifndef NDEBUG #ifndef NDEBUG
if( m_board ) if( m_board )
assert( m_board->FindNet( netcode )->GetNetname() == FROM_UTF8( StrPurge( buf ) ) ); assert( m_board->FindNet( m_netCodes[netcode] )->GetNetname() ==
FROM_UTF8( StrPurge( buf ) ) );
#endif /* NDEBUG */ #endif /* NDEBUG */
} }
...@@ -1822,6 +1823,7 @@ void LEGACY_PLUGIN::loadNETINFO_ITEM() ...@@ -1822,6 +1823,7 @@ void LEGACY_PLUGIN::loadNETINFO_ITEM()
NETINFO_ITEM* net = NULL; NETINFO_ITEM* net = NULL;
char* line; char* line;
int netCode;
while( ( line = READLINE( m_reader ) ) != NULL ) while( ( line = READLINE( m_reader ) ) != NULL )
{ {
...@@ -1831,7 +1833,7 @@ void LEGACY_PLUGIN::loadNETINFO_ITEM() ...@@ -1831,7 +1833,7 @@ void LEGACY_PLUGIN::loadNETINFO_ITEM()
{ {
// e.g. "Na 58 "/cpu.sch/PAD7"\r\n" // e.g. "Na 58 "/cpu.sch/PAD7"\r\n"
int netCode = intParse( line + SZ( "Na" ), &data ); netCode = intParse( line + SZ( "Na" ), &data );
ReadDelimitedText( buf, data, sizeof(buf) ); ReadDelimitedText( buf, data, sizeof(buf) );
net = new NETINFO_ITEM( m_board, FROM_UTF8( buf ), netCode ); net = new NETINFO_ITEM( m_board, FROM_UTF8( buf ), netCode );
...@@ -1842,9 +1844,15 @@ void LEGACY_PLUGIN::loadNETINFO_ITEM() ...@@ -1842,9 +1844,15 @@ void LEGACY_PLUGIN::loadNETINFO_ITEM()
// net 0 should be already in list, so store this net // net 0 should be already in list, so store this net
// if it is not the net 0, or if the net 0 does not exists. // if it is not the net 0, or if the net 0 does not exists.
if( net != NULL && ( net->GetNet() > 0 || m_board->FindNet( 0 ) == NULL ) ) if( net != NULL && ( net->GetNet() > 0 || m_board->FindNet( 0 ) == NULL ) )
{
m_board->AppendNet( net ); m_board->AppendNet( net );
m_netCodes[netCode] = net->GetNet();
}
else else
{
delete net; delete net;
}
return; // preferred exit return; // preferred exit
} }
} }
...@@ -2094,7 +2102,7 @@ void LEGACY_PLUGIN::loadTrackList( int aStructType ) ...@@ -2094,7 +2102,7 @@ void LEGACY_PLUGIN::loadTrackList( int aStructType )
via->SetLayerPair( LAYER_N_FRONT, LAYER_N_BACK ); via->SetLayerPair( LAYER_N_FRONT, LAYER_N_BACK );
} }
newTrack->SetNetCode( net_code ); newTrack->SetNetCode( m_netCodes[net_code] );
newTrack->SetState( flags, true ); newTrack->SetState( flags, true );
m_board->Add( newTrack ); m_board->Add( newTrack );
...@@ -2242,7 +2250,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER() ...@@ -2242,7 +2250,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
// Init the net code only, not the netname, to be sure // Init the net code only, not the netname, to be sure
// the zone net name is the name read in file. // the zone net name is the name read in file.
// (When mismatch, the user will be prompted in DRC, to fix the actual name) // (When mismatch, the user will be prompted in DRC, to fix the actual name)
zc->BOARD_CONNECTED_ITEM::SetNetCode( netcode ); zc->BOARD_CONNECTED_ITEM::SetNetCode( m_netCodes[netcode] );
} }
else if( TESTLINE( "ZLayer" ) ) // layer found else if( TESTLINE( "ZLayer" ) ) // layer found
......
...@@ -126,8 +126,9 @@ protected: ...@@ -126,8 +126,9 @@ protected:
int m_loading_format_version; ///< which BOARD_FORMAT_VERSION am I Load()ing? int m_loading_format_version; ///< which BOARD_FORMAT_VERSION am I Load()ing?
LP_CACHE* m_cache; LP_CACHE* m_cache;
NETINFO_MAPPING* m_mapping; ///< mapping for net codes, so only not empty net codes NETINFO_MAPPING* m_mapping; ///< mapping for net codes, so only not empty nets
///< are stored with consecutive integers as net codes ///< are stored with consecutive integers as net codes
std::vector<int> m_netCodes; ///< net codes mapping for boards being loaded
/// initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed. /// initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed.
void init( const PROPERTIES* aProperties ); void init( const PROPERTIES* aProperties );
......
...@@ -504,6 +504,11 @@ void PCB_PARSER::parseGeneralSection() throw( IO_ERROR, PARSE_ERROR ) ...@@ -504,6 +504,11 @@ void PCB_PARSER::parseGeneralSection() throw( IO_ERROR, PARSE_ERROR )
NeedRIGHT(); NeedRIGHT();
break; break;
case T_nets:
m_netCodes.resize( parseInt( "nets number" ) );
NeedRIGHT();
break;
case T_no_connects: case T_no_connects:
m_board->SetUnconnectedNetCount( parseInt( "no connect count" ) ); m_board->SetUnconnectedNetCount( parseInt( "no connect count" ) );
NeedRIGHT(); NeedRIGHT();
...@@ -1059,7 +1064,7 @@ void PCB_PARSER::parseNETINFO_ITEM() throw( IO_ERROR, PARSE_ERROR ) ...@@ -1059,7 +1064,7 @@ void PCB_PARSER::parseNETINFO_ITEM() throw( IO_ERROR, PARSE_ERROR )
wxCHECK_RET( CurTok() == T_net, wxCHECK_RET( CurTok() == T_net,
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as net." ) ); wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as net." ) );
int number = parseInt( "net number" ); int netCode = parseInt( "net number" );
NeedSYMBOLorNUMBER(); NeedSYMBOLorNUMBER();
wxString name = FromUTF8(); wxString name = FromUTF8();
...@@ -1069,10 +1074,13 @@ void PCB_PARSER::parseNETINFO_ITEM() throw( IO_ERROR, PARSE_ERROR ) ...@@ -1069,10 +1074,13 @@ void PCB_PARSER::parseNETINFO_ITEM() throw( IO_ERROR, PARSE_ERROR )
// net 0 should be already in list, so store this net // net 0 should be already in list, so store this net
// if it is not the net 0, or if the net 0 does not exists. // if it is not the net 0, or if the net 0 does not exists.
// (TODO: a better test.) // (TODO: a better test.)
if( number > 0 || m_board->FindNet( 0 ) == NULL ) if( netCode > 0 || m_board->FindNet( 0 ) == NULL )
{ {
NETINFO_ITEM* net = new NETINFO_ITEM( m_board, name, number ); NETINFO_ITEM* net = new NETINFO_ITEM( m_board, name, netCode );
m_board->AppendNet( net ); m_board->AppendNet( net );
// Store the new code mapping
m_netCodes[netCode] = net->GetNet();
} }
} }
...@@ -2193,7 +2201,7 @@ D_PAD* PCB_PARSER::parseD_PAD( MODULE* aParent ) throw( IO_ERROR, PARSE_ERROR ) ...@@ -2193,7 +2201,7 @@ D_PAD* PCB_PARSER::parseD_PAD( MODULE* aParent ) throw( IO_ERROR, PARSE_ERROR )
break; break;
case T_net: case T_net:
pad->SetNetCode( parseInt( "net number" ) ); pad->SetNetCode( m_netCodes[parseInt( "net number" )] );
NeedSYMBOLorNUMBER(); NeedSYMBOLorNUMBER();
assert( FromUTF8() == m_board->FindNet( pad->GetNetCode() )->GetNetname() ); assert( FromUTF8() == m_board->FindNet( pad->GetNetCode() )->GetNetname() );
NeedRIGHT(); NeedRIGHT();
...@@ -2291,7 +2299,7 @@ TRACK* PCB_PARSER::parseTRACK() throw( IO_ERROR, PARSE_ERROR ) ...@@ -2291,7 +2299,7 @@ TRACK* PCB_PARSER::parseTRACK() throw( IO_ERROR, PARSE_ERROR )
break; break;
case T_net: case T_net:
track->SetNetCode( parseInt( "net number" ) ); track->SetNetCode( m_netCodes[parseInt( "net number" )] );
break; break;
case T_tstamp: case T_tstamp:
...@@ -2369,7 +2377,7 @@ VIA* PCB_PARSER::parseVIA() throw( IO_ERROR, PARSE_ERROR ) ...@@ -2369,7 +2377,7 @@ VIA* PCB_PARSER::parseVIA() throw( IO_ERROR, PARSE_ERROR )
break; break;
case T_net: case T_net:
via->SetNetCode( parseInt( "net number" ) ); via->SetNetCode( m_netCodes[parseInt( "net number" )] );
NeedRIGHT(); NeedRIGHT();
break; break;
...@@ -2421,7 +2429,7 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR ) ...@@ -2421,7 +2429,7 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR )
// Init the net code only, not the netname, to be sure // Init the net code only, not the netname, to be sure
// the zone net name is the name read in file. // the zone net name is the name read in file.
// (When mismatch, the user will be prompted in DRC, to fix the actual name) // (When mismatch, the user will be prompted in DRC, to fix the actual name)
zone->SetNetCode( parseInt( "net number" ) ); zone->SetNetCode( m_netCodes[parseInt( "net number" )] );
NeedRIGHT(); NeedRIGHT();
break; break;
......
...@@ -64,10 +64,10 @@ class PCB_PARSER : public PCB_LEXER ...@@ -64,10 +64,10 @@ class PCB_PARSER : public PCB_LEXER
typedef boost::unordered_map< std::string, LAYER_NUM > LAYER_NUM_MAP; typedef boost::unordered_map< std::string, LAYER_NUM > LAYER_NUM_MAP;
typedef boost::unordered_map< std::string, LAYER_MSK > LAYER_MSK_MAP; typedef boost::unordered_map< std::string, LAYER_MSK > LAYER_MSK_MAP;
BOARD* m_board; BOARD* m_board;
LAYER_NUM_MAP m_layerIndices; ///< map layer name to it's index LAYER_NUM_MAP m_layerIndices; ///< map layer name to it's index
LAYER_MSK_MAP m_layerMasks; ///< map layer names to their masks LAYER_MSK_MAP m_layerMasks; ///< map layer names to their masks
std::vector<int> m_netCodes; ///< net codes mapping for boards being loaded
/** /**
* Function init * Function init
......
...@@ -993,6 +993,9 @@ void RN_DATA::ProcessBoard() ...@@ -993,6 +993,9 @@ void RN_DATA::ProcessBoard()
void RN_DATA::Recalculate( int aNet ) void RN_DATA::Recalculate( int aNet )
{ {
if( m_board->GetNetCount() > m_nets.size() )
m_nets.resize( m_board->GetNetCount() );
if( aNet < 0 ) // Recompute everything if( aNet < 0 ) // Recompute everything
{ {
unsigned int i, netCount; unsigned int i, netCount;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment