bugfix 1325375: pcbnew crash while append a board

This commit is contained in:
Maciej Suminski 2014-06-02 11:41:54 +02:00
parent 9cfd1dc4ea
commit fa846932c1
8 changed files with 70 additions and 27 deletions

View File

@ -795,6 +795,11 @@ public:
*/
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 )
{
m_NetInfo.AppendNet( aNewNet );

View File

@ -254,6 +254,7 @@ public:
NETINFO_ITEM* GetNetItem( int aNetCode ) const
{
NETCODES_MAP::const_iterator result = m_netCodes.find( aNetCode );
if( result != m_netCodes.end() )
return (*result).second;
@ -268,6 +269,7 @@ public:
NETINFO_ITEM* GetNetItem( const wxString& aNetName ) const
{
NETNAMES_MAP::const_iterator result = m_netNames.find( aNetName );
if( result != m_netNames.end() )
return (*result).second;
@ -283,7 +285,8 @@ public:
/**
* 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 );
@ -421,7 +424,7 @@ private:
* Function getFreeNetCode
* returns the first available net code that is not used by any other net.
*/
int getFreeNetCode() const;
int getFreeNetCode();
BOARD* m_Parent;
@ -430,6 +433,8 @@ private:
std::vector<D_PAD*> m_PadsFullList; ///< contains all pads, sorted by pad's netname.
///< can be used in ratsnest calculations.
int m_newNetCode; ///< possible value for new net code assignment
};

View File

@ -45,6 +45,8 @@ NETINFO_LIST::NETINFO_LIST( BOARD* aParent ) : m_Parent( aParent )
{
// Make sure that the unconnected net has number 0
AppendNet( new NETINFO_ITEM( aParent, wxEmptyString, 0 ) );
m_newNetCode = 0;
}
@ -63,14 +65,27 @@ void NETINFO_LIST::clear()
m_PadsFullList.clear();
m_netNames.clear();
m_netCodes.clear();
m_newNetCode = 0;
}
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
if( aNewElement->m_NetCode < 0 )
const_cast<int&>( aNewElement->m_NetCode ) = getFreeNetCode();
else if( ( aNewElement->m_NetCode != (int) m_netCodes.size() ) || ( aNewElement->m_NetCode < 0 ) )
{
aNewElement->m_NetCode = getFreeNetCode();
}
// net names & codes are supposed to be unique
assert( GetNetItem( aNewElement->GetNetname() ) == NULL );
@ -201,10 +216,8 @@ void NETINFO_LIST::buildPadsFullList()
}
int NETINFO_LIST::getFreeNetCode() const
int NETINFO_LIST::getFreeNetCode()
{
static int m_newNetCode = 0;
do {
if( m_newNetCode < 0 )
m_newNetCode = 0;

View File

@ -502,13 +502,12 @@ void LEGACY_PLUGIN::loadGENERAL()
else if( TESTLINE( "Nmodule" ) )
{
NbMod = intParse( line + SZ( "Nmodule" ) );
}
}*/
else if( TESTLINE( "Nnets" ) )
{
NbNets = intParse( line + SZ( "Nnets" ) );
m_netCodes.resize( intParse( line + SZ( "Nnets" ) ) );
}
*/
else if( TESTLINE( "$EndGENERAL" ) )
return; // preferred exit
@ -1305,13 +1304,15 @@ void LEGACY_PLUGIN::loadPAD( MODULE* aModule )
char buf[1024]; // can be fairly long
int netcode = intParse( line + SZ( "Ne" ), &data );
pad->SetNetCode( netcode );
// Store the new code mapping
pad->SetNetCode( m_netCodes[netcode] );
// read Netname
ReadDelimitedText( buf, data, sizeof(buf) );
#ifndef NDEBUG
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 */
}
@ -1822,6 +1823,7 @@ void LEGACY_PLUGIN::loadNETINFO_ITEM()
NETINFO_ITEM* net = NULL;
char* line;
int netCode;
while( ( line = READLINE( m_reader ) ) != NULL )
{
@ -1831,7 +1833,7 @@ void LEGACY_PLUGIN::loadNETINFO_ITEM()
{
// 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) );
net = new NETINFO_ITEM( m_board, FROM_UTF8( buf ), netCode );
@ -1842,9 +1844,15 @@ void LEGACY_PLUGIN::loadNETINFO_ITEM()
// 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( net != NULL && ( net->GetNet() > 0 || m_board->FindNet( 0 ) == NULL ) )
{
m_board->AppendNet( net );
m_netCodes[netCode] = net->GetNet();
}
else
{
delete net;
}
return; // preferred exit
}
}
@ -2094,7 +2102,7 @@ void LEGACY_PLUGIN::loadTrackList( int aStructType )
via->SetLayerPair( LAYER_N_FRONT, LAYER_N_BACK );
}
newTrack->SetNetCode( net_code );
newTrack->SetNetCode( m_netCodes[net_code] );
newTrack->SetState( flags, true );
m_board->Add( newTrack );
@ -2242,7 +2250,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
// Init the net code only, not the netname, to be sure
// the zone net name is the name read in file.
// (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

View File

@ -126,8 +126,9 @@ protected:
int m_loading_format_version; ///< which BOARD_FORMAT_VERSION am I Load()ing?
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
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.
void init( const PROPERTIES* aProperties );

View File

@ -504,6 +504,11 @@ void PCB_PARSER::parseGeneralSection() throw( IO_ERROR, PARSE_ERROR )
NeedRIGHT();
break;
case T_nets:
m_netCodes.resize( parseInt( "nets number" ) );
NeedRIGHT();
break;
case T_no_connects:
m_board->SetUnconnectedNetCount( parseInt( "no connect count" ) );
NeedRIGHT();
@ -1059,7 +1064,7 @@ void PCB_PARSER::parseNETINFO_ITEM() throw( IO_ERROR, PARSE_ERROR )
wxCHECK_RET( CurTok() == T_net,
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as net." ) );
int number = parseInt( "net number" );
int netCode = parseInt( "net number" );
NeedSYMBOLorNUMBER();
wxString name = FromUTF8();
@ -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
// if it is not the net 0, or if the net 0 does not exists.
// (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 );
// 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 )
break;
case T_net:
pad->SetNetCode( parseInt( "net number" ) );
pad->SetNetCode( m_netCodes[parseInt( "net number" )] );
NeedSYMBOLorNUMBER();
assert( FromUTF8() == m_board->FindNet( pad->GetNetCode() )->GetNetname() );
NeedRIGHT();
@ -2291,7 +2299,7 @@ TRACK* PCB_PARSER::parseTRACK() throw( IO_ERROR, PARSE_ERROR )
break;
case T_net:
track->SetNetCode( parseInt( "net number" ) );
track->SetNetCode( m_netCodes[parseInt( "net number" )] );
break;
case T_tstamp:
@ -2369,7 +2377,7 @@ VIA* PCB_PARSER::parseVIA() throw( IO_ERROR, PARSE_ERROR )
break;
case T_net:
via->SetNetCode( parseInt( "net number" ) );
via->SetNetCode( m_netCodes[parseInt( "net number" )] );
NeedRIGHT();
break;
@ -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
// the zone net name is the name read in file.
// (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();
break;

View File

@ -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_MSK > LAYER_MSK_MAP;
BOARD* m_board;
LAYER_NUM_MAP m_layerIndices; ///< map layer name to it's index
LAYER_MSK_MAP m_layerMasks; ///< map layer names to their masks
BOARD* m_board;
LAYER_NUM_MAP m_layerIndices; ///< map layer name to it's index
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

View File

@ -993,6 +993,9 @@ void RN_DATA::ProcessBoard()
void RN_DATA::Recalculate( int aNet )
{
if( m_board->GetNetCount() > m_nets.size() )
m_nets.resize( m_board->GetNetCount() );
if( aNet < 0 ) // Recompute everything
{
unsigned int i, netCount;