Generate duplicate footprint errors when reading netlist.

Fixes: lp:1682970
* https://bugs.launchpad.net/kicad/+bug/1682970
This commit is contained in:
Jeff Young 2018-09-17 10:54:49 +01:00
parent a53b163456
commit cd7ebaf9ee
5 changed files with 285 additions and 311 deletions

View File

@ -1024,8 +1024,8 @@ void BOARD::Remove( BOARD_ITEM* aBoardItem )
void BOARD::DeleteMARKERs() void BOARD::DeleteMARKERs()
{ {
// the vector does not know how to delete the MARKER_PCB, it holds pointers // the vector does not know how to delete the MARKER_PCB, it holds pointers
for( unsigned i = 0; i<m_markers.size(); ++i ) for( MARKER_PCB* marker : m_markers )
delete m_markers[i]; delete marker;
m_markers.clear(); m_markers.clear();
} }
@ -1033,10 +1033,9 @@ void BOARD::DeleteMARKERs()
void BOARD::DeleteZONEOutlines() void BOARD::DeleteZONEOutlines()
{ {
// the vector does not know how to delete the ZONE Outlines, it holds // the vector does not know how to delete the ZONE Outlines, it holds pointers
// pointers for( ZONE_CONTAINER* zone : m_ZoneDescriptorList )
for( unsigned i = 0; i<m_ZoneDescriptorList.size(); ++i ) delete zone;
delete m_ZoneDescriptorList[i];
m_ZoneDescriptorList.clear(); m_ZoneDescriptorList.clear();
} }
@ -1170,10 +1169,8 @@ EDA_RECT BOARD::ComputeBoundingBox( bool aBoardEdgesOnly ) const
} }
// Check polygonal zones // Check polygonal zones
for( unsigned int i = 0; i < m_ZoneDescriptorList.size(); i++ ) for( auto aZone : m_ZoneDescriptorList )
{ {
ZONE_CONTAINER* aZone = m_ZoneDescriptorList[i];
if( !hasItems ) if( !hasItems )
area = aZone->GetBoundingBox(); area = aZone->GetBoundingBox();
else else
@ -1507,11 +1504,10 @@ int BOARD::SortedNetnamesList( wxArrayString& aNames, bool aSortbyPadsCount )
netBuffer.reserve( m_NetInfo.GetNetCount() ); netBuffer.reserve( m_NetInfo.GetNetCount() );
for( NETINFO_LIST::iterator net( m_NetInfo.begin() ), netEnd( m_NetInfo.end() ); for( NETINFO_ITEM* net : m_NetInfo )
net != netEnd; ++net )
{ {
if( net->GetNet() > 0 ) if( net->GetNet() > 0 )
netBuffer.push_back( *net ); netBuffer.push_back( net );
} }
// sort the list // sort the list
@ -1538,8 +1534,8 @@ int BOARD::SortedNetnamesList( wxArrayString& aNames, bool aSortbyPadsCount )
else else
sort( netBuffer.begin(), netBuffer.end(), sortNetsByNames ); sort( netBuffer.begin(), netBuffer.end(), sortNetsByNames );
for( unsigned ii = 0; ii < netBuffer.size(); ii++ ) for( NETINFO_ITEM* net : netBuffer )
aNames.Add( netBuffer[ii]->GetNetname() ); aNames.Add( net->GetNetname() );
return netBuffer.size(); return netBuffer.size();
} }
@ -1584,12 +1580,9 @@ ZONE_CONTAINER* BOARD::HitTestForAnyFilledArea( const wxPoint& aRefPos,
if( aEndLayer < aStartLayer ) if( aEndLayer < aStartLayer )
std::swap( aEndLayer, aStartLayer ); std::swap( aEndLayer, aStartLayer );
for( unsigned ia = 0; ia < m_ZoneDescriptorList.size(); ia++ ) for( ZONE_CONTAINER* area : m_ZoneDescriptorList )
{ {
ZONE_CONTAINER* area = m_ZoneDescriptorList[ia]; if( area->GetLayer() < aStartLayer || area->GetLayer() > aEndLayer )
LAYER_NUM layer = area->GetLayer();
if( layer < aStartLayer || layer > aEndLayer )
continue; continue;
// In locate functions we must skip tagged items with BUSY flag set. // In locate functions we must skip tagged items with BUSY flag set.
@ -2420,8 +2413,8 @@ ZONE_CONTAINER* BOARD::InsertArea( int aNetcode, int aAreaIdx, PCB_LAYER_ID aLay
bool BOARD::NormalizeAreaPolygon( PICKED_ITEMS_LIST * aNewZonesList, ZONE_CONTAINER* aCurrArea ) bool BOARD::NormalizeAreaPolygon( PICKED_ITEMS_LIST * aNewZonesList, ZONE_CONTAINER* aCurrArea )
{ {
// mark all areas as unmodified except this one, if modified // mark all areas as unmodified except this one, if modified
for( unsigned ia = 0; ia < m_ZoneDescriptorList.size(); ia++ ) for( ZONE_CONTAINER* zone : m_ZoneDescriptorList )
m_ZoneDescriptorList[ia]->SetLocalFlags( 0 ); zone->SetLocalFlags( 0 );
aCurrArea->SetLocalFlags( 1 ); aCurrArea->SetLocalFlags( 1 );
@ -2465,14 +2458,72 @@ bool BOARD::NormalizeAreaPolygon( PICKED_ITEMS_LIST * aNewZonesList, ZONE_CONTAI
} }
void BOARD::updateComponentPadConnections( NETLIST& aNetlist, MODULE* footprint,
COMPONENT* component, REPORTER& aReporter )
{
wxString msg;
for( auto pad : footprint->Pads() )
{
COMPONENT_NET net = component->GetNet( pad->GetName() );
if( !net.IsValid() ) // Footprint pad had no net.
{
if( !pad->GetNetname().IsEmpty() )
{
msg.Printf( _( "Clearing component %s pin %s net." ),
footprint->GetReference(),
pad->GetName() );
aReporter.Report( msg, REPORTER::RPT_ACTION );
}
if( !aNetlist.IsDryRun() )
{
m_connectivity->Remove( pad );
pad->SetNetCode( NETINFO_LIST::UNCONNECTED );
}
}
else // Footprint pad has a net.
{
if( net.GetNetName() != pad->GetNetname() )
{
msg.Printf( _( "Changing footprint %s pad %s net from %s to %s." ),
footprint->GetReference(),
pad->GetName(),
pad->GetNetname(),
net.GetNetName() );
aReporter.Report( msg, REPORTER::RPT_ACTION );
if( !aNetlist.IsDryRun() )
{
NETINFO_ITEM* netinfo = FindNet( net.GetNetName() );
if( netinfo == NULL )
{
// It is a new net, we have to add it
netinfo = new NETINFO_ITEM( this, net.GetNetName() );
Add( netinfo );
}
m_connectivity->Remove( pad );
pad->SetNetCode( netinfo->GetNet() );
m_connectivity->Add( pad );
}
}
}
}
}
void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
std::vector<MODULE*>* aNewFootprints, REPORTER* aReporter ) std::vector<MODULE*>* aNewFootprints, REPORTER& aReporter )
{ {
unsigned i; unsigned i;
wxPoint bestPosition; wxPoint bestPosition;
wxString msg; wxString msg;
std::vector<MODULE*> newFootprints; std::vector<MODULE*> newFootprints;
std::map< ZONE_CONTAINER*, std::vector<D_PAD*> > zoneConnectionsCache; std::map< ZONE_CONTAINER*, std::vector<D_PAD*> > zoneConnectionsCache;
MODULE* lastPreexistingFootprint = m_Modules.GetLast();
for( int ii = 0; ii < GetAreaCount(); ii++ ) for( int ii = 0; ii < GetAreaCount(); ii++ )
{ {
@ -2509,80 +2560,45 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
for( i = 0; i < aNetlist.GetCount(); i++ ) for( i = 0; i < aNetlist.GetCount(); i++ )
{ {
COMPONENT* component = aNetlist.GetComponent( i ); COMPONENT* component = aNetlist.GetComponent( i );
MODULE* footprint; int matchCount = 0;
if( aReporter )
{
msg.Printf( _( "Checking netlist symbol footprint \"%s:%s:%s\"." ), msg.Printf( _( "Checking netlist symbol footprint \"%s:%s:%s\"." ),
GetChars( component->GetReference() ), component->GetReference(),
GetChars( component->GetTimeStamp() ), component->GetTimeStamp(),
GetChars( component->GetFPID().Format() ) ); GetChars( component->GetFPID().Format() ) );
aReporter->Report( msg, REPORTER::RPT_INFO ); aReporter.Report( msg, REPORTER::RPT_INFO );
}
for( MODULE* footprint = m_Modules; footprint; footprint = footprint->Next() )
{
bool match;
MODULE* tmp;
if( aNetlist.IsFindByTimeStamp() ) if( aNetlist.IsFindByTimeStamp() )
footprint = FindModule( aNetlist.GetComponent( i )->GetTimeStamp(), true ); match = footprint->GetPath() == component->GetTimeStamp();
else else
footprint = FindModule( aNetlist.GetComponent( i )->GetReference() ); match = footprint->GetReference().CmpNoCase( component->GetReference() );
if( footprint == NULL ) // A new footprint. if( match )
{
if( aReporter )
{
if( component->GetModule() != NULL )
{
msg.Printf( _( "Adding new symbol %s footprint %s." ),
GetChars( component->GetReference() ),
GetChars( component->GetFPID().Format() ) );
aReporter->Report( msg, REPORTER::RPT_ACTION );
}
else
{
msg.Printf( _( "Cannot add new symbol %s due to missing footprint %s." ),
GetChars( component->GetReference() ),
GetChars( component->GetFPID().Format() ) );
aReporter->Report( msg, REPORTER::RPT_ERROR );
}
}
if( !aNetlist.IsDryRun() && (component->GetModule() != NULL) )
{
// Owned by NETLIST, can only copy it.
footprint = new MODULE( *component->GetModule() );
footprint->SetParent( this );
footprint->SetPosition( bestPosition );
footprint->SetTimeStamp( GetNewTimeStamp() );
newFootprints.push_back( footprint );
Add( footprint, ADD_APPEND );
m_connectivity->Add( footprint );
}
}
else // An existing footprint.
{ {
// Test for footprint change. // Test for footprint change.
if( !component->GetFPID().empty() && footprint->GetFPID() != component->GetFPID() ) if( !component->GetFPID().empty() && footprint->GetFPID() != component->GetFPID() )
{ {
if( aNetlist.GetReplaceFootprints() ) if( aNetlist.GetReplaceFootprints() )
{
if( aReporter )
{ {
if( component->GetModule() != NULL ) if( component->GetModule() != NULL )
{ {
msg.Printf( _( "Changing symbol %s footprint from %s to %s." ), msg.Printf( _( "Changing symbol %s footprint from %s to %s." ),
GetChars( footprint->GetReference() ), footprint->GetReference(),
GetChars( footprint->GetFPID().Format() ), GetChars( footprint->GetFPID().Format() ),
GetChars( component->GetFPID().Format() ) ); GetChars( component->GetFPID().Format() ) );
aReporter->Report( msg, REPORTER::RPT_ACTION ); aReporter.Report( msg, REPORTER::RPT_ACTION );
} }
else else
{ {
msg.Printf( _( "Cannot change symbol %s footprint due to missing " msg.Printf( _( "Cannot change symbol %s footprint due to missing footprint %s." ),
"footprint %s." ), footprint->GetReference(),
GetChars( footprint->GetReference() ),
GetChars( component->GetFPID().Format() ) ); GetChars( component->GetFPID().Format() ) );
aReporter->Report( msg, REPORTER::RPT_ERROR ); aReporter.Report( msg, REPORTER::RPT_ERROR );
}
} }
if( !aNetlist.IsDryRun() && (component->GetModule() != NULL) ) if( !aNetlist.IsDryRun() && (component->GetModule() != NULL) )
@ -2625,14 +2641,11 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
// Test for reference designator field change. // Test for reference designator field change.
if( footprint->GetReference() != component->GetReference() ) if( footprint->GetReference() != component->GetReference() )
{
if( aReporter )
{ {
msg.Printf( _( "Changing footprint %s reference to %s." ), msg.Printf( _( "Changing footprint %s reference to %s." ),
GetChars( footprint->GetReference() ), footprint->GetReference(),
GetChars( component->GetReference() ) ); component->GetReference() );
aReporter->Report( msg, REPORTER::RPT_ACTION ); aReporter.Report( msg, REPORTER::RPT_ACTION );
}
if( !aNetlist.IsDryRun() ) if( !aNetlist.IsDryRun() )
footprint->SetReference( component->GetReference() ); footprint->SetReference( component->GetReference() );
@ -2640,15 +2653,12 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
// Test for value field change. // Test for value field change.
if( footprint->GetValue() != component->GetValue() ) if( footprint->GetValue() != component->GetValue() )
{
if( aReporter )
{ {
msg.Printf( _( "Changing footprint %s value from %s to %s." ), msg.Printf( _( "Changing footprint %s value from %s to %s." ),
GetChars( footprint->GetReference() ), footprint->GetReference(),
GetChars( footprint->GetValue() ), footprint->GetValue(),
GetChars( component->GetValue() ) ); component->GetValue() );
aReporter->Report( msg, REPORTER::RPT_ACTION ); aReporter.Report( msg, REPORTER::RPT_ACTION );
}
if( !aNetlist.IsDryRun() ) if( !aNetlist.IsDryRun() )
footprint->SetValue( component->GetValue() ); footprint->SetValue( component->GetValue() );
@ -2656,76 +2666,67 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
// Test for time stamp change. // Test for time stamp change.
if( footprint->GetPath() != component->GetTimeStamp() ) if( footprint->GetPath() != component->GetTimeStamp() )
{
if( aReporter )
{ {
msg.Printf( _( "Changing component path \"%s:%s\" to \"%s\"." ), msg.Printf( _( "Changing component path \"%s:%s\" to \"%s\"." ),
GetChars( footprint->GetReference() ), footprint->GetReference(),
GetChars( footprint->GetPath() ), footprint->GetPath(),
GetChars( component->GetTimeStamp() ) ); component->GetTimeStamp() );
aReporter->Report( msg, REPORTER::RPT_INFO ); aReporter.Report( msg, REPORTER::RPT_INFO );
}
if( !aNetlist.IsDryRun() ) if( !aNetlist.IsDryRun() )
footprint->SetPath( component->GetTimeStamp() ); footprint->SetPath( component->GetTimeStamp() );
} }
updateComponentPadConnections( aNetlist, footprint, component, aReporter );
matchCount++;
} }
if( footprint == NULL ) if( footprint == lastPreexistingFootprint )
continue;
// At this point, the component footprint is updated. Now update the nets.
for( auto pad : footprint->Pads() )
{ {
COMPONENT_NET net = component->GetNet( pad->GetName() ); if( matchCount == 0 )
if( !net.IsValid() ) // Footprint pad had no net.
{ {
if( aReporter && !pad->GetNetname().IsEmpty() ) if( component->GetModule() != NULL )
{ {
msg.Printf( _( "Clearing component %s pin %s net." ), msg.Printf( _( "Adding new symbol %s footprint %s." ),
GetChars( footprint->GetReference() ), component->GetReference(),
GetChars( pad->GetName() ) ); GetChars( component->GetFPID().Format() ) );
aReporter->Report( msg, REPORTER::RPT_ACTION ); aReporter.Report( msg, REPORTER::RPT_ACTION );
}
else
{
msg.Printf( _( "Cannot add new symbol %s due to missing footprint %s." ),
component->GetReference(),
GetChars( component->GetFPID().Format() ) );
aReporter.Report( msg, REPORTER::RPT_ERROR );
} }
if( !aNetlist.IsDryRun() ) if( !aNetlist.IsDryRun() && (component->GetModule() != NULL) )
{ {
m_connectivity->Remove( pad ); // Owned by NETLIST, can only copy it.
pad->SetNetCode( NETINFO_LIST::UNCONNECTED ); tmp = new MODULE( *component->GetModule() );
} tmp->SetParent( this );
} tmp->SetPosition( bestPosition );
else // Footprint pad has a net. tmp->SetTimeStamp( GetNewTimeStamp() );
{ newFootprints.push_back( tmp );
if( net.GetNetName() != pad->GetNetname() ) Add( tmp, ADD_APPEND );
{ m_connectivity->Add( tmp );
if( aReporter )
{ updateComponentPadConnections( aNetlist, tmp, component, aReporter );
msg.Printf( _( "Changing footprint %s pad %s net from %s to %s." ),
GetChars( footprint->GetReference() ),
GetChars( pad->GetName() ),
GetChars( pad->GetNetname() ),
GetChars( net.GetNetName() ) );
aReporter->Report( msg, REPORTER::RPT_ACTION );
} }
if( !aNetlist.IsDryRun() ) matchCount++;
{
NETINFO_ITEM* netinfo = FindNet( net.GetNetName() );
if( netinfo == NULL )
{
// It is a new net, we have to add it
netinfo = new NETINFO_ITEM( this, net.GetNetName() );
Add( netinfo );
} }
m_connectivity->Remove( pad ); // No sense going through the newly-created footprints
pad->SetNetCode( netinfo->GetNet() ); break;
m_connectivity->Add( pad );
}
} }
} }
if( matchCount > 1 )
{
msg.Printf( _( "Multiple footprints found for \"%s\"." ), component->GetReference() );
aReporter.Report( msg, REPORTER::RPT_ERROR );
} }
} }
@ -2749,12 +2750,8 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
if( component == NULL ) if( component == NULL )
{ {
if( aReporter ) msg.Printf( _( "Removing unused footprint %s." ), module->GetReference() );
{ aReporter.Report( msg, REPORTER::RPT_ACTION );
msg.Printf( _( "Removing unused footprint %s." ),
GetChars( module->GetReference() ) );
aReporter->Report( msg, REPORTER::RPT_ACTION );
}
if( !aNetlist.IsDryRun() ) if( !aNetlist.IsDryRun() )
{ {
@ -2772,7 +2769,7 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
// If needed, remove the single pad nets: // If needed, remove the single pad nets:
if( aDeleteSinglePadNets && !aNetlist.IsDryRun() ) if( aDeleteSinglePadNets && !aNetlist.IsDryRun() )
{ {
std::vector<unsigned int> padCount( connAlgo->NetCount() ); std::vector<unsigned int> padCount( (unsigned) connAlgo->NetCount() );
for( const auto cnItem : connAlgo->ItemList() ) for( const auto cnItem : connAlgo->ItemList() )
{ {
@ -2814,12 +2811,8 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
if( pad && zoneCount == 0 ) if( pad && zoneCount == 0 )
{ {
if( aReporter ) msg.Printf( _( "Remove single pad net %s." ), GetChars( pad->GetNetname() ) );
{ aReporter.Report( msg, REPORTER::RPT_ACTION );
msg.Printf( _( "Remove single pad net %s." ),
GetChars( pad->GetNetname() ) );
aReporter->Report( msg, REPORTER::RPT_ACTION );
}
m_connectivity->Remove( pad ); m_connectivity->Remove( pad );
pad->SetNetCode( NETINFO_LIST::UNCONNECTED ); pad->SetNetCode( NETINFO_LIST::UNCONNECTED );
@ -2832,8 +2825,6 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
// wrong or missing. // wrong or missing.
// Note that we use references to find the footprints as they're already updated by this // Note that we use references to find the footprints as they're already updated by this
// point (whether by-reference or by-timestamp). // point (whether by-reference or by-timestamp).
if( aReporter )
{
wxString padname; wxString padname;
for( i = 0; i < aNetlist.GetCount(); i++ ) for( i = 0; i < aNetlist.GetCount(); i++ )
{ {
@ -2854,11 +2845,10 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
// not found: bad footprint, report error // not found: bad footprint, report error
msg.Printf( _( "Symbol %s pad %s not found in footprint %s.\n" ), msg.Printf( _( "Symbol %s pad %s not found in footprint %s.\n" ),
GetChars( component->GetReference() ), component->GetReference(),
GetChars( padname ), padname,
GetChars( footprint->GetFPID().Format() ) ); GetChars( footprint->GetFPID().Format() ) );
aReporter->Report( msg, REPORTER::RPT_ERROR ); aReporter.Report( msg, REPORTER::RPT_ERROR );
}
} }
} }
@ -2886,20 +2876,18 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
} }
} }
if( aReporter )
{
if( updatedNet ) if( updatedNet )
{ {
msg.Printf( _( "Updating copper zone from net %s to %s." ), msg.Printf( _( "Updating copper zone from net %s to %s." ),
zone->GetNetname(), updatedNet->GetNetname() ); zone->GetNetname(),
aReporter->Report( msg, REPORTER::RPT_ACTION ); updatedNet->GetNetname() );
aReporter.Report( msg, REPORTER::RPT_ACTION );
} }
else else
{ {
msg.Printf( _( "Copper zone (net %s) has no pads connected." ), msg.Printf( _( "Copper zone (net %s) has no pads connected." ),
zone->GetNetname() ); zone->GetNetname() );
aReporter->Report( msg, REPORTER::RPT_WARNING ); aReporter.Report( msg, REPORTER::RPT_WARNING );
}
} }
if( updatedNet && !aNetlist.IsDryRun() ) if( updatedNet && !aNetlist.IsDryRun() )
@ -2972,25 +2960,24 @@ bool BOARD::GetBoardPolygonOutlines( SHAPE_POLY_SET& aOutlines, wxString* aError
const std::vector<D_PAD*> BOARD::GetPads() const std::vector<D_PAD*> BOARD::GetPads()
{ {
std::vector<D_PAD*> rv; std::vector<D_PAD*> allPads;
for ( auto mod: Modules() )
{
for ( auto pad: mod->Pads() )
rv.push_back ( pad );
for( MODULE* mod : Modules() )
{
for( D_PAD* pad : mod->Pads() )
allPads.push_back( pad );
} }
return rv; return allPads;
} }
unsigned BOARD::GetPadCount() unsigned BOARD::GetPadCount()
{ {
unsigned retval = 0; unsigned retval = 0;
for( auto mod : Modules() ) for( auto mod : Modules() )
{
retval += mod->Pads().Size(); retval += mod->Pads().Size();
}
return retval; return retval;
} }
@ -3020,14 +3007,12 @@ D_PAD* BOARD::GetPad( unsigned aIndex ) const
void BOARD::ClearAllNetCodes() void BOARD::ClearAllNetCodes()
{ {
for ( auto zone : Zones() ) for( auto zone : Zones() )
zone->SetNetCode( 0 ); zone->SetNetCode( 0 );
for ( auto mod : Modules() ) for( auto pad : GetPads() )
for ( auto pad : mod->Pads() )
pad->SetNetCode( 0 ); pad->SetNetCode( 0 );
for ( auto track : Tracks() ) for( auto track : Tracks() )
track->SetNetCode( 0 ); track->SetNetCode( 0 );
} }

View File

@ -63,6 +63,7 @@ class NETLIST;
class REPORTER; class REPORTER;
class SHAPE_POLY_SET; class SHAPE_POLY_SET;
class CONNECTIVITY_DATA; class CONNECTIVITY_DATA;
class COMPONENT;
/** /**
* Enum LAYER_T * Enum LAYER_T
@ -896,11 +897,13 @@ public:
* @param aNewFootprints is a pointer the to a list of new footprints used when updating * @param aNewFootprints is a pointer the to a list of new footprints used when updating
* the netlist. * the netlist.
* @param aReporter is a #REPORTER object to report the changes \a aNetlist makes to * @param aReporter is a #REPORTER object to report the changes \a aNetlist makes to
* the #BOARD. If NULL, no change reporting occurs. * the #BOARD.
*/ */
void ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, void ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
std::vector<MODULE*>* aNewFootprints, REPORTER* aReporter = NULL ); std::vector<MODULE*>* aNewFootprints, REPORTER& aReporter );
void updateComponentPadConnections( NETLIST& aNetlist, MODULE* footprint,
COMPONENT* component, REPORTER& aReporter );
/** /**
* Function SortedNetnamesList * Function SortedNetnamesList
* @param aNames An array string to fill with net names. * @param aNames An array string to fill with net names.

View File

@ -449,7 +449,7 @@ void DIALOG_NETLIST::loadNetlist( bool aDryRun )
m_MessageWindow->SetLazyUpdate( true ); // Use lazy update to speed the creation of the report m_MessageWindow->SetLazyUpdate( true ); // Use lazy update to speed the creation of the report
// (the window is not updated for each message) // (the window is not updated for each message)
m_parent->ReadPcbNetlist( netlistFileName, wxEmptyString, &reporter, m_parent->ReadPcbNetlist( netlistFileName, wxEmptyString, reporter,
m_cbUpdateFootprints->GetValue(), m_cbUpdateFootprints->GetValue(),
m_cbDeleteShortingTracks->GetValue(), m_cbDeleteShortingTracks->GetValue(),
m_cbDeleteExtraFootprints->GetValue(), m_cbDeleteExtraFootprints->GetValue(),

View File

@ -57,7 +57,7 @@ using namespace std::placeholders;
void PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFileName, void PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFileName,
const wxString& aCmpFileName, const wxString& aCmpFileName,
REPORTER* aReporter, REPORTER& aReporter,
bool aChangeFootprints, bool aChangeFootprints,
bool aDeleteUnconnectedTracks, bool aDeleteUnconnectedTracks,
bool aDeleteExtraFootprints, bool aDeleteExtraFootprints,
@ -224,7 +224,7 @@ MODULE* PCB_EDIT_FRAME::ListAndSelectModuleName()
#define ALLOW_PARTIAL_FPID 1 #define ALLOW_PARTIAL_FPID 1
void PCB_EDIT_FRAME::LoadFootprints( NETLIST& aNetlist, REPORTER* aReporter ) void PCB_EDIT_FRAME::LoadFootprints( NETLIST& aNetlist, REPORTER& aReporter )
{ {
wxString msg; wxString msg;
LIB_ID lastFPID; LIB_ID lastFPID;
@ -248,13 +248,10 @@ void PCB_EDIT_FRAME::LoadFootprints( NETLIST& aNetlist, REPORTER* aReporter )
#else #else
if( component->GetFPID().empty() ) if( component->GetFPID().empty() )
#endif #endif
{
if( aReporter )
{ {
msg.Printf( _( "No footprint defined for symbol \"%s\".\n" ), msg.Printf( _( "No footprint defined for symbol \"%s\".\n" ),
GetChars( component->GetReference() ) ); component->GetReference() );
aReporter->Report( msg, REPORTER::RPT_ERROR ); aReporter.Report( msg, REPORTER::RPT_ERROR );
}
continue; continue;
} }
@ -266,19 +263,15 @@ void PCB_EDIT_FRAME::LoadFootprints( NETLIST& aNetlist, REPORTER* aReporter )
else else
fpOnBoard = m_Pcb->FindModule( aNetlist.GetComponent( ii )->GetReference() ); fpOnBoard = m_Pcb->FindModule( aNetlist.GetComponent( ii )->GetReference() );
bool footprintMisMatch = fpOnBoard && bool footprintMisMatch = fpOnBoard && fpOnBoard->GetFPID() != component->GetFPID();
fpOnBoard->GetFPID() != component->GetFPID();
if( footprintMisMatch && !aNetlist.GetReplaceFootprints() ) if( footprintMisMatch && !aNetlist.GetReplaceFootprints() )
{
if( aReporter )
{ {
msg.Printf( _( "Footprint of %s changed: board footprint \"%s\", netlist footprint \"%s\"." ), msg.Printf( _( "Footprint of %s changed: board footprint \"%s\", netlist footprint \"%s\"." ),
GetChars( component->GetReference() ), component->GetReference(),
GetChars( fpOnBoard->GetFPID().Format() ), GetChars( fpOnBoard->GetFPID().Format() ),
GetChars( component->GetFPID().Format() ) ); GetChars( component->GetFPID().Format() ) );
aReporter->Report( msg, REPORTER::RPT_WARNING ); aReporter.Report( msg, REPORTER::RPT_WARNING );
}
continue; continue;
} }
@ -300,14 +293,11 @@ void PCB_EDIT_FRAME::LoadFootprints( NETLIST& aNetlist, REPORTER* aReporter )
#else #else
if( !component->GetFPID().IsValid() ) if( !component->GetFPID().IsValid() )
#endif #endif
{
if( aReporter )
{ {
msg.Printf( _( "%s footprint ID \"%s\" is not valid." ), msg.Printf( _( "%s footprint ID \"%s\" is not valid." ),
GetChars( component->GetReference() ), component->GetReference(),
GetChars( component->GetFPID().Format() ) ); GetChars( component->GetFPID().Format() ) );
aReporter->Report( msg, REPORTER::RPT_ERROR ); aReporter.Report( msg, REPORTER::RPT_ERROR );
}
continue; continue;
} }
@ -320,14 +310,11 @@ void PCB_EDIT_FRAME::LoadFootprints( NETLIST& aNetlist, REPORTER* aReporter )
lastFPID = component->GetFPID(); lastFPID = component->GetFPID();
} }
else else
{
if( aReporter )
{ {
msg.Printf( _( "%s footprint \"%s\" not found in any libraries in the footprint library table.\n" ), msg.Printf( _( "%s footprint \"%s\" not found in any libraries in the footprint library table.\n" ),
GetChars( component->GetReference() ), component->GetReference(),
GetChars( component->GetFPID().GetLibItemName() ) ); GetChars( component->GetFPID().GetLibItemName() ) );
aReporter->Report( msg, REPORTER::RPT_ERROR ); aReporter.Report( msg, REPORTER::RPT_ERROR );
}
continue; continue;
} }

View File

@ -283,7 +283,7 @@ public:
* @throw IO_ERROR if an I/O error occurs or a #PARSE_ERROR if a file parsing error * @throw IO_ERROR if an I/O error occurs or a #PARSE_ERROR if a file parsing error
* occurs while reading footprint library files. * occurs while reading footprint library files.
*/ */
void LoadFootprints( NETLIST& aNetlist, REPORTER* aReporter ); void LoadFootprints( NETLIST& aNetlist, REPORTER& aReporter );
void OnQuit( wxCommandEvent& event ); void OnQuit( wxCommandEvent& event );
@ -1557,8 +1557,7 @@ public:
* @param aNetlistFileName = netlist file name (*.net) * @param aNetlistFileName = netlist file name (*.net)
* @param aCmpFileName = cmp/footprint link file name (*.cmp). * @param aCmpFileName = cmp/footprint link file name (*.cmp).
* if not found or empty, only the netlist will be used * if not found or empty, only the netlist will be used
* @param aReporter is a pointer to a #REPORTER object to write display messages. * @param aReporter a #REPORTER object to write display messages.
* can be NULL.
* @param aChangeFootprint if true, footprints that have changed in netlist will be changed * @param aChangeFootprint if true, footprints that have changed in netlist will be changed
* @param aDeleteBadTracks if true, erroneous tracks will be deleted * @param aDeleteBadTracks if true, erroneous tracks will be deleted
* @param aDeleteExtraFootprints if true, remove unlocked footprints that are not in netlist * @param aDeleteExtraFootprints if true, remove unlocked footprints that are not in netlist
@ -1571,7 +1570,7 @@ public:
*/ */
void ReadPcbNetlist( const wxString& aNetlistFileName, void ReadPcbNetlist( const wxString& aNetlistFileName,
const wxString& aCmpFileName, const wxString& aCmpFileName,
REPORTER* aReporter, REPORTER& aReporter,
bool aChangeFootprint, bool aChangeFootprint,
bool aDeleteBadTracks, bool aDeleteBadTracks,
bool aDeleteExtraFootprints, bool aDeleteExtraFootprints,