Read/write "no net" (0) for pins with a no-connection marker.
Fixes https://gitlab.com/kicad/code/kicad/issues/2273 Fixes https://gitlab.com/kicad/code/kicad/issues/5587
This commit is contained in:
parent
c94001839b
commit
5f8a8c6850
|
@ -566,7 +566,7 @@ XNODE* NETLIST_EXPORTER_XML::makeListOfNets( unsigned aCtl )
|
|||
wxString netName;
|
||||
wxString ref;
|
||||
|
||||
XNODE* xnet = 0;
|
||||
XNODE* xnet = nullptr;
|
||||
|
||||
/* output:
|
||||
<net code="123" name="/cfcard.sch/WAIT#">
|
||||
|
@ -575,19 +575,31 @@ XNODE* NETLIST_EXPORTER_XML::makeListOfNets( unsigned aCtl )
|
|||
</net>
|
||||
*/
|
||||
|
||||
int code = 0;
|
||||
typedef std::pair<SCH_PIN*, SCH_SHEET_PATH> MEMBER_RECORD;
|
||||
typedef std::pair<wxString, std::vector<MEMBER_RECORD>> NET_RECORD;
|
||||
std::vector<NET_RECORD*> nets;
|
||||
|
||||
// Pre-allocate the no-net node
|
||||
nets.emplace_back( new NET_RECORD() );
|
||||
|
||||
for( const auto& it : m_schematic->ConnectionGraph()->GetNetMap() )
|
||||
{
|
||||
bool added = false;
|
||||
wxString net_name = it.first.first;
|
||||
auto subgraphs = it.second;
|
||||
wxString net_name = it.first.first;
|
||||
auto subgraphs = it.second;
|
||||
NET_RECORD* net_record;
|
||||
|
||||
// Code starts at 1
|
||||
code++;
|
||||
if( subgraphs.empty() )
|
||||
continue;
|
||||
|
||||
XNODE* xnode;
|
||||
std::vector<std::pair<SCH_PIN*, SCH_SHEET_PATH>> sorted_items;
|
||||
if( !subgraphs[0]->m_strong_driver && subgraphs[0]->m_no_connect )
|
||||
{
|
||||
net_record = nets[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
nets.emplace_back( new NET_RECORD( net_name, std::vector<MEMBER_RECORD>() ) );
|
||||
net_record = nets.back();
|
||||
}
|
||||
|
||||
for( CONNECTION_SUBGRAPH* subgraph : subgraphs )
|
||||
{
|
||||
|
@ -607,40 +619,52 @@ XNODE* NETLIST_EXPORTER_XML::makeListOfNets( unsigned aCtl )
|
|||
continue;
|
||||
}
|
||||
|
||||
sorted_items.emplace_back( pin, sheet );
|
||||
net_record->second.emplace_back( pin, sheet );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( int i = 0; i < (int) nets.size(); ++i )
|
||||
{
|
||||
NET_RECORD* net_record = nets[i];
|
||||
bool added = false;
|
||||
XNODE* xnode;
|
||||
|
||||
// Netlist ordering: Net name, then ref des, then pin name
|
||||
std::sort( sorted_items.begin(), sorted_items.end(),
|
||||
std::sort( net_record->second.begin(), net_record->second.end(),
|
||||
[]( const std::pair<SCH_PIN*, SCH_SHEET_PATH>& a,
|
||||
const std::pair<SCH_PIN*, SCH_SHEET_PATH>& b )
|
||||
{
|
||||
wxString ref_a = a.first->GetParentSymbol()->GetRef( &a.second );
|
||||
wxString ref_b = b.first->GetParentSymbol()->GetRef( &b.second );
|
||||
SCH_PIN* pinA = a.first;
|
||||
SCH_PIN* pinB = b.first;
|
||||
wxString refA = pinA->GetParentSymbol()->GetRef( &a.second );
|
||||
wxString refB = pinB->GetParentSymbol()->GetRef( &b.second );
|
||||
|
||||
if( ref_a == ref_b )
|
||||
return a.first->GetNumber() < b.first->GetNumber();
|
||||
if( refA == refB )
|
||||
return pinA->GetNumber() < pinB->GetNumber();
|
||||
|
||||
return ref_a < ref_b;
|
||||
return refA < refB;
|
||||
} );
|
||||
|
||||
// Some duplicates can exist, for example on multi-unit parts with duplicated
|
||||
// pins across units. If the user connects the pins on each unit, they will
|
||||
// appear on separate subgraphs. Remove those here:
|
||||
sorted_items.erase( std::unique( sorted_items.begin(), sorted_items.end(),
|
||||
[]( const std::pair<SCH_PIN*, SCH_SHEET_PATH>& a,
|
||||
const std::pair<SCH_PIN*, SCH_SHEET_PATH>& b )
|
||||
{
|
||||
wxString ref_a = a.first->GetParentSymbol()->GetRef( &a.second );
|
||||
wxString ref_b = b.first->GetParentSymbol()->GetRef( &b.second );
|
||||
net_record->second.erase(
|
||||
std::unique( net_record->second.begin(), net_record->second.end(),
|
||||
[]( const std::pair<SCH_PIN*, SCH_SHEET_PATH>& a,
|
||||
const std::pair<SCH_PIN*, SCH_SHEET_PATH>& b )
|
||||
{
|
||||
SCH_PIN* pinA = a.first;
|
||||
SCH_PIN* pinB = b.first;
|
||||
wxString refA = pinA->GetParentSymbol()->GetRef( &a.second );
|
||||
wxString refB = pinB->GetParentSymbol()->GetRef( &b.second );
|
||||
|
||||
return ref_a == ref_b && a.first->GetNumber() == b.first->GetNumber();
|
||||
} ),
|
||||
sorted_items.end() );
|
||||
return refA == refB && pinA->GetNumber() == pinB->GetNumber();
|
||||
} ),
|
||||
net_record->second.end() );
|
||||
|
||||
for( const std::pair<SCH_PIN*, SCH_SHEET_PATH>& pair : sorted_items )
|
||||
for( const std::pair<SCH_PIN*, SCH_SHEET_PATH>& pair : net_record->second )
|
||||
{
|
||||
SCH_PIN* pin = pair.first;
|
||||
SCH_SHEET_PATH sheet = pair.second;
|
||||
|
@ -655,9 +679,9 @@ XNODE* NETLIST_EXPORTER_XML::makeListOfNets( unsigned aCtl )
|
|||
if( !added )
|
||||
{
|
||||
xnets->AddChild( xnet = node( "net" ) );
|
||||
netCodeTxt.Printf( "%d", code );
|
||||
netCodeTxt.Printf( "%d", i );
|
||||
xnet->AddAttribute( "code", netCodeTxt );
|
||||
xnet->AddAttribute( "name", net_name );
|
||||
xnet->AddAttribute( "name", net_record->first );
|
||||
|
||||
added = true;
|
||||
}
|
||||
|
|
|
@ -189,7 +189,6 @@ void KICAD_NETLIST_PARSER::parseNet()
|
|||
wxString reference;
|
||||
wxString pin_number;
|
||||
wxString pin_function;
|
||||
int nodecount = 0;
|
||||
|
||||
// The token net was read, so the next data is (code <number>)
|
||||
while( (token = NextTok()) != T_EOF )
|
||||
|
@ -211,10 +210,6 @@ void KICAD_NETLIST_PARSER::parseNet()
|
|||
NeedSYMBOLorNUMBER();
|
||||
name = FROM_UTF8( CurText() );
|
||||
NeedRIGHT();
|
||||
|
||||
if( name.IsEmpty() ) // Give a dummy net name like N-000109
|
||||
name = wxT("N-00000") + code;
|
||||
|
||||
break;
|
||||
|
||||
case T_node:
|
||||
|
@ -253,21 +248,25 @@ void KICAD_NETLIST_PARSER::parseNet()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
component = m_netlist->GetComponentByReference( reference );
|
||||
|
||||
// Cannot happen if the netlist is valid.
|
||||
if( component == NULL )
|
||||
if( strtol( code, NULL, 10 ) >= 1 )
|
||||
{
|
||||
wxString msg;
|
||||
msg.Printf( _( "Cannot find component with reference designator \"%s\" in netlist." ),
|
||||
reference );
|
||||
THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), m_lineReader->Line(),
|
||||
m_lineReader->LineNumber(), m_lineReader->Length() );
|
||||
}
|
||||
if( name.IsEmpty() ) // Give a dummy net name like N-000009
|
||||
name = wxT("N-00000") + code;
|
||||
|
||||
component->AddNet( pin_number, name, pin_function );
|
||||
nodecount++;
|
||||
component = m_netlist->GetComponentByReference( reference );
|
||||
|
||||
// Cannot happen if the netlist is valid.
|
||||
if( component == NULL )
|
||||
{
|
||||
wxString msg;
|
||||
msg.Printf( _( "Cannot find component with ref '%s' in netlist." ),
|
||||
reference );
|
||||
THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), m_lineReader->Line(),
|
||||
m_lineReader->LineNumber(), m_lineReader->Length() );
|
||||
}
|
||||
|
||||
component->AddNet( pin_number, name, pin_function );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
Loading…
Reference in New Issue