27#include <unordered_map> 
  108    if( old_conn && new_conn )
 
  110        new_conn->
Clone( *old_conn );
 
 
  140    std::vector<SCH_ITEM*> candidates;
 
  141    std::set<SCH_ITEM*>    strong_drivers;
 
  165            strong_drivers.insert( item );
 
  167        if( item_priority > highest_priority )
 
  170            candidates.push_back( item );
 
  171            highest_priority = item_priority;
 
  173        else if( !candidates.empty() && ( item_priority == highest_priority ) )
 
  175            candidates.push_back( item );
 
  185    if( !candidates.empty() )
 
  219                if( aGlobal != bGlobal )
 
  225                if( aLocal != bLocal )
 
  246            bool a_lowQualityName = a_name.Contains( 
"-Pad" );
 
  247            bool b_lowQualityName = b_name.Contains( 
"-Pad" );
 
  249            if( a_lowQualityName != b_lowQualityName )
 
  250                return !a_lowQualityName;
 
  252            return a_name < b_name;
 
  255        std::sort( candidates.begin(), candidates.end(), candidate_cmp );
 
  260    if( strong_drivers.size() > 1 )
 
  267        m_drivers.insert( strong_drivers.begin(), strong_drivers.end() );
 
 
  289                                                std::set<CONNECTION_SUBGRAPH*>& aSubgraphs )
 
  301    if( aSubgraphs.insert( sg ).second == 
false )
 
  307        aItems.emplace( 
m_sheet, item );
 
 
  321#ifdef CONNECTIVITY_DEBUG 
  322        wxASSERT_MSG( 
false, wxS( 
"Tried to get the net name of an item with no connection" ) );
 
 
  334    std::vector<SCH_ITEM*> labels;
 
  338        switch( item->Type() )
 
  347                labels.push_back( item );
 
 
  363    std::vector<SCH_ITEM*> labels;
 
  367        switch( item->Type() )
 
  376                labels.push_back( item );
 
 
  392    switch( aItem->
Type() )
 
  399        return pin->GetDefaultNetName( 
m_sheet, forceNoConnect );
 
  426        wxFAIL_MSG( wxS( 
"Unhandled item type in GetNameForDriver" ) );
 
  427        return wxEmptyString;
 
 
  447const std::vector<std::pair<wxString, SCH_ITEM*>>
 
  450    std::vector<std::pair<wxString, SCH_ITEM*>> foundNetclasses;
 
  452    const std::unordered_set<SCH_RULE_AREA*>& ruleAreaCache = aItem->
GetRuleAreaCache();
 
  457        const std::vector<std::pair<wxString, SCH_ITEM*>> ruleNetclasses =
 
  458                ruleArea->GetResolvedNetclasses();
 
  460        if( ruleNetclasses.size() > 0 )
 
  462            foundNetclasses.insert( foundNetclasses.end(), ruleNetclasses.begin(),
 
  463                                    ruleNetclasses.end() );
 
  479                        if( netclass != wxEmptyString )
 
  480                            foundNetclasses.push_back( { netclass, aItem } );
 
  487            foundNetclasses.begin(), foundNetclasses.end(),
 
  488            []( 
const std::pair<wxString, SCH_ITEM*>& i1, 
const std::pair<wxString, SCH_ITEM*>& i2 )
 
  490                return i1.first < i2.first;
 
  493    return foundNetclasses;
 
 
  519        child->m_absorbed_by = 
this;
 
  522            set_absorbed_by( subchild );
 
  530    set_absorbed_by( aOther );
 
 
  583                if( 
const std::unique_ptr<LIB_SYMBOL>& part = symbol->GetLibSymbolRef() )
 
  584                    return part->GetReferenceField().GetText();
 
  586                return wxEmptyString;
 
  589    switch( aDriver->
Type() )
 
 
  620               std::back_inserter( 
m_items ) );
 
 
  675    wxCHECK2( aOldItem->
Type() == aNewItem->
Type(), 
return );
 
  710        wxCHECK2( oldPins.size() == newPins.size(), 
return );
 
  712        for( 
size_t ii = 0; ii < oldPins.size(); ii++ )
 
  714            exchange( oldPins[ii], newPins[ii] );
 
 
  725        if( subgraph->m_graph == 
this )
 
 
  749                                    std::function<
void( 
SCH_ITEM* )>* aChangedItemHandler,
 
  753    PROF_TIMER recalc_time( 
"CONNECTION_GRAPH::Recalculate" );
 
  754    monitorTrans.
Start();
 
  759    monitorTrans.
StartSpan( 
"updateItemConnectivity", 
"" );
 
  760    PROF_TIMER update_items( 
"updateItemConnectivity" );
 
  763    std::set<SCH_ITEM*> dirty_items;
 
  765    int count = aSheetList.size() * 2;
 
  770        if( aProgressReporter )
 
  776        std::vector<SCH_ITEM*> items;
 
  779        std::vector<std::pair<SCH_SYMBOL*, int>> symbolsChanged;
 
  781        for( 
SCH_ITEM* item : sheet.LastScreen()->Items() )
 
  783            if( item->IsConnectable() && ( aUnconditional || item->IsConnectivityDirty() ) )
 
  785                wxLogTrace( 
ConnTrace, wxT( 
"Adding item %s to connectivity graph update" ),
 
  786                            item->GetTypeDesc() );
 
  787                items.push_back( item );
 
  788                dirty_items.insert( item );
 
  797                        if( 
pin->IsConnectivityDirty() )
 
  799                            dirty_items.insert( 
pin );
 
  812                    if( 
pin->IsConnectivityDirty() )
 
  814                        items.push_back( 
pin );
 
  815                        dirty_items.insert( 
pin );
 
  825                    if( 
pin->IsConnectivityDirty() )
 
  827                        items.push_back( 
pin );
 
  828                        dirty_items.insert( 
pin );
 
  841                if( symbol->
GetUnit() != new_unit )
 
  842                    symbolsChanged.push_back( { symbol, symbol->
GetUnit() } );
 
  852        if( aProgressReporter )
 
  859        sheet.LastScreen()->TestDanglingEnds( &sheet, aChangedItemHandler );
 
  862        for( 
const auto& [ symbol, originalUnit ] : symbolsChanged )
 
  863            symbol->SetUnit( originalUnit );
 
  874        item->SetConnectivityDirty( 
false );
 
  881    PROF_TIMER build_graph( 
"buildConnectionGraph" );
 
  882    monitorTrans.
StartSpan( 
"BuildConnectionGraph", 
"" );
 
 
  901        const std::set<SCH_ITEM*> &aItems )
 
  903    std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> retvals;
 
  904    std::set<CONNECTION_SUBGRAPH*> subgraphs;
 
  909        while( aSubgraph->m_absorbed_by )
 
  912            wxASSERT( aSubgraph->m_graph == aSubgraph->m_absorbed_by->m_graph );
 
  913            aSubgraph = aSubgraph->m_absorbed_by;
 
  917        while( aSubgraph->m_hier_parent )
 
  920            wxASSERT( aSubgraph->m_graph == aSubgraph->m_hier_parent->m_graph );
 
  921            aSubgraph = aSubgraph->m_hier_parent;
 
  925        aSubgraph->getAllConnectedItems( retvals, subgraphs );
 
  928    auto extract_element = [&]( 
SCH_ITEM* aItem )
 
  934            wxLogTrace( 
ConnTrace, wxT( 
"Item %s not found in connection graph" ),
 
  935                        aItem->GetTypeDesc() );
 
  941            wxLogTrace( 
ConnTrace, wxT( 
"Item %s in subgraph %ld (%p) has no driver" ),
 
  942                        aItem->GetTypeDesc(), item_sg->
m_code, item_sg );
 
  947        if( sg_to_scan.empty() )
 
  949            wxLogTrace( 
ConnTrace, wxT( 
"Item %s in subgraph %ld with net %s has no neighbors" ),
 
  951            sg_to_scan.push_back( item_sg );
 
  955                    wxT( 
"Removing all item %s connections from subgraph %ld with net %s: Found " 
  962            traverse_subgraph( sg );
 
  964            for( 
auto& bus_it : sg->m_bus_neighbors )
 
  967                    traverse_subgraph( bus_sg );
 
  970            for( 
auto& bus_it : sg->m_bus_parents )
 
  973                    traverse_subgraph( bus_sg );
 
  987                extract_element( 
pin );
 
  994                extract_element( 
pin );
 
  998            extract_element( item );
 
 1004    for( 
const auto& [
path, item] : retvals )
 
 
 1031    wxLogTrace( 
ConnTrace, wxT( 
"Removing %zu subgraphs" ), aSubgraphs.size() );
 
 1034    std::set<int> codes_to_remove;
 
 1038        std::sort( el.second.begin(), el.second.end() );
 
 1043        for( 
auto& it : sg->m_bus_neighbors )
 
 1049                for( 
auto test = parents.begin(); 
test != parents.end(); )
 
 1057                if( parents.empty() )
 
 1062        for( 
auto& it : sg->m_bus_parents )
 
 1068                for( 
auto test = neighbors.begin(); 
test != neighbors.end(); )
 
 1076                if( neighbors.empty() )
 
 1097            auto it = std::lower_bound( el.second.begin(), el.second.end(), sg );
 
 1099            while( it != el.second.end() && *it == sg )
 
 1100                it = el.second.erase( it );
 
 1103        auto remove_sg = [sg]( 
auto it ) -> 
bool 
 1116            if( remove_sg( it ) )
 
 1124            if( remove_sg( it ) )
 
 1133            if( remove_sg( it ) )
 
 1135                codes_to_remove.insert( it->first.Netcode );
 
 1147            if( remove_sg( it ) )
 
 1155            if( it->second == sg )
 
 1166        if( codes_to_remove.contains( it->second ) )
 
 1174        if( codes_to_remove.contains( it->second ) )
 
 1183        sg->m_graph = 
nullptr;
 
 
 1190                                                 std::map<
VECTOR2I, std::vector<SCH_ITEM*>>& aConnectionMap )
 
 1201                    aConn->SetName( 
name );
 
 1206    std::map<wxString, std::vector<SCH_PIN*>> pinNumberMap;
 
 1212        updatePin( 
pin, conn );
 
 1213        aConnectionMap[ 
pin->GetPosition() ].push_back( 
pin );
 
 1214        pinNumberMap[
pin->GetNumber()].emplace_back( 
pin );
 
 1217    auto linkPinsInVec =
 
 1218            [&]( 
const std::vector<SCH_PIN*>& aVec )
 
 1220                for( 
size_t i = 0; i < aVec.size(); ++i )
 
 1222                    for( 
size_t j = i + 1; j < aVec.size(); ++j )
 
 1224                        aVec[i]->AddConnectionTo( aSheet, aVec[j] );
 
 1225                        aVec[j]->AddConnectionTo( aSheet, aVec[i] );
 
 1234            for( 
const auto& [number, 
group] : pinNumberMap )
 
 1235                linkPinsInVec( 
group );
 
 1240            std::vector<SCH_PIN*> pins;
 
 1242            for( 
const wxString& pinNumber : 
group )
 
 1243                pins.emplace_back( aSymbol->
GetPin( pinNumber ) );
 
 1245            linkPinsInVec( pins );
 
 
 1268                                                      std::map<
VECTOR2I, std::vector<SCH_ITEM*>>& aConnectionMap )
 
 1273    m_items.emplace_back( aItem );
 
 1276    switch( aItem->
Type() )
 
 1289        if( points.empty() )
 
 1290            points = { 
static_cast<SCH_PIN*
>( aItem )->GetPosition() };
 
 1303    for( 
const VECTOR2I& point : points )
 
 1304        aConnectionMap[point].push_back( aItem );
 
 
 1309                                               const std::vector<SCH_ITEM*>& aItemList )
 
 1311    wxLogTrace( wxT( 
"Updating connectivity for sheet %s with %zu items" ),
 
 1313    std::map<VECTOR2I, std::vector<SCH_ITEM*>> connection_map;
 
 1317        std::vector<VECTOR2I> points = item->GetConnectionPoints();
 
 1318        item->ClearConnectedItems( aSheet );
 
 1324                pin->InitializeConnection( aSheet, 
this );
 
 1326                pin->ClearConnectedItems( aSheet );
 
 1328                connection_map[ 
pin->GetTextPos() ].push_back( 
pin );
 
 1345                VECTOR2I point = item->GetPosition();
 
 1348                std::vector<SCH_ITEM*> overlapping_items;
 
 1350                std::copy_if( items.begin(), items.end(), std::back_inserter( overlapping_items ),
 
 1353                                  return test_item->Type() == SCH_LINE_T
 
 1354                                         && test_item->HitTest( point, -1 );
 
 1359                if( overlapping_items.size() < 2 ) 
continue;
 
 1361                for( 
SCH_ITEM* test_item : overlapping_items )
 
 1362                    connection_map[point].push_back( test_item );
 
 1367    for( 
auto& [point, connection_vec] : connection_map )
 
 1369        std::sort( connection_vec.begin(), connection_vec.end() );
 
 1375        for( 
SCH_ITEM* connected_item : connection_vec )
 
 1389                if( connection_vec.size() == 1 )
 
 1405                    if( point == bus_entry->GetPosition() )
 
 1408                        bus_entry->m_connected_bus_items[1] = busLine;
 
 1421            for( 
SCH_ITEM* test_item : connection_vec )
 
 1423                bool      bus_connection_ok = 
true;
 
 1425                if( test_item == connected_item )
 
 1431                    if( test_item->GetLayer() == 
LAYER_BUS )
 
 1450                if( connected_item->ConnectionPropagatesTo( test_item )
 
 1451                        && test_item->ConnectionPropagatesTo( connected_item )
 
 1452                        && bus_connection_ok )
 
 1454                    connected_item->AddConnectionTo( aSheet, test_item );
 
 1465                if( !bus_entry->m_connected_bus_item )
 
 1471                        bus_entry->m_connected_bus_item = bus;
 
 
 1482    wxCHECK_RET( 
m_schematic, wxS( 
"Connection graph cannot be built without schematic pointer" ) );
 
 1486    for( 
const std::shared_ptr<BUS_ALIAS>& alias : 
m_schematic->GetAllBusAliases() )
 
 1495        for( 
const auto& [sheet, connection] : item->m_connection_map )
 
 1497            if( connection->SubgraphCode() == 0 )
 
 1506                connection->SetSubgraphCode( subgraph->
m_code );
 
 1509                std::list<SCH_ITEM*> memberlist;
 
 1514                            SCH_CONNECTION* conn = aItem->GetOrInitConnection( sheet, 
this );
 
 1520                            return ( unique && conn && ( conn->
SubgraphCode() == 0 ) );
 
 1523                std::copy_if( item->ConnectedItems( sheet ).begin(),
 
 1524                              item->ConnectedItems( sheet ).end(),
 
 1525                              std::back_inserter( memberlist ), get_items );
 
 1527                for( 
SCH_ITEM* connected_item : memberlist )
 
 1532                    SCH_CONNECTION* connected_conn = connected_item->Connection( &sheet );
 
 1534                    wxCHECK2( connected_conn, 
continue );
 
 1540                        subgraph->
AddItem( connected_item );
 
 1541                        const SCH_ITEM_VEC& citemset = connected_item->ConnectedItems( sheet );
 
 1548                            if( get_items( citem ) )
 
 1549                                memberlist.push_back( citem );
 
 1554                for( 
SCH_ITEM* connected_item : memberlist )
 
 
 1568    std::vector<CONNECTION_SUBGRAPH*> dirty_graphs;
 
 1573                      return candidate->m_dirty;
 
 1576    wxLogTrace( 
ConnTrace, wxT( 
"Resolving drivers for %zu subgraphs" ), dirty_graphs.size() );
 
 1578    std::vector<std::future<size_t>> returns( dirty_graphs.size() );
 
 1580    auto update_lambda =
 
 1583                if( !subgraph->m_dirty )
 
 1587                for( 
SCH_ITEM* item : subgraph->m_items )
 
 1589                    switch( item->
Type() )
 
 1592                        subgraph->m_no_connect = item;
 
 1596                        subgraph->m_bus_entry = item;
 
 1604                            subgraph->m_no_connect = item;
 
 1614                subgraph->ResolveDrivers( 
true );
 
 1615                subgraph->m_dirty = 
false;
 
 1622    auto results = 
tp.submit_loop( 0, dirty_graphs.size(),
 
 1625                                       update_lambda( dirty_graphs[ii] );
 
 1634                      return candidate->m_driver;
 
 
 1647        wxString full_name = subgraph->m_driver_connection->Name();
 
 1648        wxString 
name = subgraph->m_driver_connection->Name( 
true );
 
 1657            wxString prefixOnly = full_name.BeforeFirst( 
'[' ) + wxT( 
"[]" );
 
 1661        subgraph->m_dirty = 
true;
 
 1663        if( subgraph->m_strong_driver )
 
 1665            SCH_ITEM* driver = subgraph->m_driver;
 
 1668            switch( driver->
Type() )
 
 1684                if( 
pin->IsGlobalPower() )
 
 1688                else if( 
pin->IsLocalPower() )
 
 1695                    wxLogTrace( 
ConnTrace, wxS( 
"Unexpected normal pin %s" ),
 
 1705                wxLogTrace( 
ConnTrace, wxS( 
"Unexpected strong driver %s" ),
 
 
 1717    std::vector<CONNECTION_SUBGRAPH*> new_subgraphs;
 
 1728            dummy.SetGraph( 
this );
 
 1731            wxLogTrace( 
ConnTrace, wxS( 
"new bus label (%s)" ),
 
 1734            for( 
const auto& conn : 
dummy.Members() )
 
 1736                wxString 
name = conn->FullLocalName();
 
 1747                subgraph->StoreImplicitConnection( new_conn );
 
 1750                wxLogTrace( 
ConnTrace, wxS( 
"SG(%ld), Adding full local name (%s) with sg (%d) on subsheet %s" ),
 
 1751                            subgraph->m_code, 
name, code, subgraph->m_sheet.PathHumanReadable() );
 
 1764                new_subgraphs.push_back( new_sg );
 
 1769    std::copy( new_subgraphs.begin(), new_subgraphs.end(),
 
 
 1781    std::unordered_map<int, CONNECTION_SUBGRAPH*> global_power_pin_subgraphs;
 
 1785        if( !
pin->ConnectedItems( sheet ).empty()
 
 1786                && !
pin->GetLibPin()->GetParentSymbol()->IsGlobalPower() )
 
 1801        if( 
pin->GetLibPin()->GetParentSymbol()->IsGlobalPower() )
 
 1802            connection->
SetName( 
pin->GetParentSymbol()->GetValue( 
true, &sheet, 
false ) );
 
 1811        auto                 jj = global_power_pin_subgraphs.find( code );
 
 1813        if( jj != global_power_pin_subgraphs.end() )
 
 1815            subgraph = jj->second;
 
 1833            global_power_pin_subgraphs[code] = subgraph;
 
 
 1850    std::unordered_set<CONNECTION_SUBGRAPH*> invalidated_subgraphs;
 
 1854        if( subgraph->m_absorbed )
 
 1859        wxString 
name = connection->
Name();
 
 1862        unsigned suffix = 1;
 
 1864        auto create_new_name =
 
 1868                    wxString suffixStr = std::to_wstring( suffix );
 
 1875                        wxString prefix = aConn->BusPrefix();
 
 1877                        if( prefix.empty() )
 
 1878                            prefix = wxT( 
"BUS" ); 
 
 1880                        wxString oldName = aConn->Name().AfterFirst( 
'{' );
 
 1882                        newName << prefix << wxT( 
"_" ) << suffixStr << wxT( 
"{" ) << oldName;
 
 1884                        aConn->ConfigureFromLabel( newName );
 
 1888                        newName << aConn->Name() << wxT( 
"_" ) << suffixStr;
 
 1889                        aConn->SetSuffix( wxString( wxT( 
"_" ) ) << suffixStr );
 
 1896        if( !subgraph->m_strong_driver )
 
 1898            std::vector<CONNECTION_SUBGRAPH*> vec_empty;
 
 1899            std::vector<CONNECTION_SUBGRAPH*>* vec = &vec_empty;
 
 1908                wxString prefixOnly = 
name.BeforeFirst( 
'[' ) + wxT( 
"[]" );
 
 1914            if( vec->size() > 1 )
 
 1916                wxString new_name = create_new_name( connection );
 
 1919                    new_name = create_new_name( connection );
 
 1921                wxLogTrace( 
ConnTrace, wxS( 
"%ld (%s) is weakly driven and not unique. Changing to %s." ),
 
 1922                            subgraph->m_code, 
name, new_name );
 
 1924                std::erase( *vec, subgraph );
 
 1930            else if( subgraph->m_driver )
 
 1942                    bool     conflict    = 
false;
 
 1943                    wxString global_name = connection->
Name( 
true );
 
 1950                        std::vector<CONNECTION_SUBGRAPH*>& candidates = kk->second;
 
 1954                            if( candidate->m_sheet == sheet )
 
 1961                        wxLogTrace( 
ConnTrace, wxS( 
"%ld (%s) skipped for promotion due to potential conflict" ),
 
 1962                                    subgraph->m_code, 
name );
 
 1968                        wxLogTrace( 
ConnTrace, wxS( 
"%ld (%s) weakly driven by unique sheet pin %s, promoting" ),
 
 1969                                    subgraph->m_code, 
name,
 
 1970                                    subgraph->m_driver->GetItemDescription( &unitsProvider, 
true ) );
 
 1972                        subgraph->m_strong_driver = 
true;
 
 1979        if( connection->
IsBus() )
 
 2003        subgraph->m_dirty = 
true;
 
 2011        if( !subgraph->m_strong_driver )
 
 2018        std::vector<CONNECTION_SUBGRAPH*> candidate_subgraphs;
 
 2021                      std::back_inserter( candidate_subgraphs ),
 
 2024                          return ( !candidate->m_absorbed &&
 
 2025                                   candidate->m_strong_driver &&
 
 2026                                   candidate != subgraph );
 
 2032        std::vector< std::shared_ptr<SCH_CONNECTION> > connections_to_check;
 
 2035        connections_to_check.push_back( std::make_shared<SCH_CONNECTION>( *connection ) );
 
 2037        auto add_connections_to_check =
 
 2040                    for( 
SCH_ITEM* possible_driver : aSubgraph->m_items )
 
 2042                        if( possible_driver == aSubgraph->m_driver )
 
 2049                            if( c->Type() != aSubgraph->m_driver_connection->Type() )
 
 2052                            if( c->Name( 
true ) == aSubgraph->m_driver_connection->Name( 
true ) )
 
 2055                            connections_to_check.push_back( c );
 
 2056                            wxLogTrace( 
ConnTrace, wxS( 
"%lu (%s): Adding secondary driver %s" ),
 
 2058                                        aSubgraph->m_driver_connection->Name( 
true ),
 
 2067        add_connections_to_check( subgraph );
 
 2069        std::set<SCH_CONNECTION*> checked_connections;
 
 2071        for( 
unsigned i = 0; i < connections_to_check.size(); i++ )
 
 2073            auto member = connections_to_check[i];
 
 2076            if( !checked_connections.insert( member.get() ).second )
 
 2079            if( member->IsBus() )
 
 2081                connections_to_check.insert( connections_to_check.end(),
 
 2082                                             member->Members().begin(),
 
 2083                                             member->Members().end() );
 
 2086            wxString test_name = member->Name( 
true );
 
 2090                if( candidate->
m_absorbed || candidate == subgraph )
 
 2106                        if( driver == candidate->
m_driver )
 
 2118                                && 
pin->GetDefaultNetName( sheet ) == test_name )
 
 2131                            if( subgraph->GetNameForDriver( driver )  == test_name )
 
 2144                         wxLogTrace( 
ConnTrace, wxS( 
"%lu (%s) has bus child %lu (%s)" ),
 
 2145                                     subgraph->m_code, connection->
Name(),
 
 2146                                     candidate->
m_code, member->Name() );
 
 2148                        subgraph->m_bus_neighbors[member].insert( candidate );
 
 2151                    else if( !connection->
IsBus()
 
 2154                        wxLogTrace( 
ConnTrace, wxS( 
"%lu (%s) absorbs neighbor %lu (%s)" ),
 
 2155                                    subgraph->m_code, connection->
Name(),
 
 2159                        add_connections_to_check( candidate );
 
 2161                        subgraph->Absorb( candidate );
 
 2162                        invalidated_subgraphs.insert( subgraph );
 
 2172        if( subgraph->m_absorbed )
 
 2175        if( !subgraph->ResolveDrivers() )
 
 2178        if( subgraph->m_driver_connection->IsBus() )
 
 2183        wxLogTrace( 
ConnTrace, wxS( 
"Re-resolving drivers for %lu (%s)" ),
 
 2184                    subgraph->m_code, subgraph->m_driver_connection->Name() );
 
 
 2203                                             bool                              aUnconditional )
 
 2206    wxCHECK_RET( 
m_schematic, wxT( 
"Connection graph cannot be built without schematic pointer" ) );
 
 2210    for( 
const std::shared_ptr<BUS_ALIAS>& alias : 
m_schematic->GetAllBusAliases() )
 
 2216    PROF_TIMER sub_graph( 
"buildItemSubGraphs" );
 
 2235    PROF_TIMER proc_sub_graph( 
"ProcessSubGraphs" );
 
 2239        proc_sub_graph.
Show();
 
 2248    std::vector<CONNECTION_SUBGRAPH*> global_subgraphs;
 
 2250                  std::back_inserter( global_subgraphs ),
 
 2253                      return !candidate->m_local_driver;
 
 2267                                m_driver_subgraphs[ii]->UpdateItemConnections();
 
 2277        if( !subgraph->m_dirty )
 
 2280        wxLogTrace( 
ConnTrace, wxS( 
"Processing %lu (%s) for propagation" ),
 
 2281                    subgraph->m_code, subgraph->m_driver_connection->Name() );
 
 2287        if( !subgraph->m_local_driver && subgraph->m_multiple_drivers )
 
 2289            for( 
SCH_ITEM* driver : subgraph->m_drivers )
 
 2291                if( driver == subgraph->m_driver )
 
 2294                const wxString& secondary_name = subgraph->GetNameForDriver( driver );
 
 2296                if( secondary_name == subgraph->m_driver_connection->Name() )
 
 2304                    if( candidate == subgraph )
 
 2307                    if( !secondary_is_global && candidate->
m_sheet != subgraph->m_sheet )
 
 2314                            wxLogTrace( 
ConnTrace, wxS( 
"Global %lu (%s) promoted to %s" ),
 
 2316                                        subgraph->m_driver_connection->Name() );
 
 2338        if( subgraph->m_dirty )
 
 2355        wxASSERT_MSG( !subgraph->m_dirty,
 
 2356                      wxS( 
"Subgraph not processed by propagateToNeighbors!" ) );
 
 2358        if( subgraph->m_bus_parents.size() < 2 )
 
 2363        wxLogTrace( 
ConnTrace, wxS( 
"%lu (%s) has multiple bus parents" ),
 
 2364                    subgraph->m_code, conn->
Name() );
 
 2367        wxCHECK2( conn->
IsNet(), 
continue );
 
 2369        for( 
const auto& ii : subgraph->m_bus_parents )
 
 2382                    wxLogTrace( 
ConnTrace, wxS( 
"Warning: could not match %s inside %lu (%s)" ),
 
 2387                if( conn->
Name() != match->
Name() )
 
 2389                    wxString old_name = match->
Name();
 
 2391                    wxLogTrace( 
ConnTrace, wxS( 
"Updating %lu (%s) member %s to %s" ),
 
 2394                    match->
Clone( *conn );
 
 2413    auto updateItemConnectionsTask =
 
 2417                if( !subgraph->m_strong_driver
 
 2418                        && subgraph->m_drivers.size() == 1
 
 2419                        && subgraph->m_driver->Type() == 
SCH_PIN_T )
 
 2422                    wxString 
name = 
pin->GetDefaultNetName( subgraph->m_sheet, 
true );
 
 2424                    subgraph->m_driver_connection->ConfigureFromLabel( 
name );
 
 2427                subgraph->m_dirty = 
false;
 
 2428                subgraph->UpdateItemConnections();
 
 2431                if( subgraph->m_driver_connection->IsBus() )
 
 2436                if( subgraph->m_driver && subgraph->m_driver->Type() == 
SCH_SHEET_PIN_T )
 
 2442                        wxString    pinText = 
pin->GetShownText( 
false );
 
 2449                            if( label->
GetShownText( &subgraph->m_sheet, 
false ) == pinText )
 
 2452                                path.push_back( sheet );
 
 2456                                if( parent_conn && parent_conn->
IsBus() )
 
 2463                        if( subgraph->m_driver_connection->IsBus() )
 
 2474                                updateItemConnectionsTask( m_driver_subgraphs[ii] );
 
 2484                                        subgraph->m_driver_connection->NetCode() };
 
 2490    std::shared_ptr<NET_SETTINGS>& netSettings = 
m_schematic->Project().GetProjectFile().m_NetSettings;
 
 2491    std::map<wxString, std::set<wxString>> oldAssignments = netSettings->GetNetclassLabelAssignments();
 
 2492    std::set<wxString> affectedNetclassNetAssignments;
 
 2494    netSettings->ClearNetclassLabelAssignments();
 
 2496    auto dirtySubgraphs =
 
 2497            [&]( 
const std::vector<CONNECTION_SUBGRAPH*>& subgraphs )
 
 2499                if( aChangedItemHandler )
 
 2503                        for( 
SCH_ITEM* item : subgraph->m_items )
 
 2504                            (*aChangedItemHandler)( item );
 
 2509    auto checkNetclassDrivers =
 
 2510            [&]( 
const wxString& netName, 
const std::vector<CONNECTION_SUBGRAPH*>& subgraphs )
 
 2512        wxCHECK_RET( !subgraphs.empty(), wxS( 
"Invalid empty subgraph" ) );
 
 2514        std::set<wxString> netclasses;
 
 2519            for( 
SCH_ITEM* item : subgraph->m_items )
 
 2521                for( 
const auto& [
name, provider] : subgraph->GetNetclassesForDriver( item ) )
 
 2522                    netclasses.insert( 
name );
 
 2529            if( subgraph->m_driver_connection->IsBus() )
 
 2531                auto processBusMember = [&, 
this]( 
const SCH_CONNECTION* member )
 
 2533                    if( !netclasses.empty() )
 
 2535                        netSettings->AppendNetclassLabelAssignment( member->Name(), netclasses );
 
 2540                    if( oldAssignments.count( member->Name() ) )
 
 2542                        if( oldAssignments[member->Name()] != netclasses )
 
 2544                            affectedNetclassNetAssignments.insert( member->Name() );
 
 2547                                dirtySubgraphs( ii->second );
 
 2550                    else if( !netclasses.empty() )
 
 2552                        affectedNetclassNetAssignments.insert( member->Name() );
 
 2555                            dirtySubgraphs( ii->second );
 
 2559                for( 
const std::shared_ptr<SCH_CONNECTION>& member : subgraph->m_driver_connection->Members() )
 
 2563                    if( member->IsBus() )
 
 2565                        for( 
const std::shared_ptr<SCH_CONNECTION>& nestedMember : member->Members() )
 
 2566                            processBusMember( nestedMember.get() );
 
 2570                        processBusMember( member.get() );
 
 2577        if( !netclasses.empty() )
 
 2579            netSettings->AppendNetclassLabelAssignment( netName, netclasses );
 
 2582        if( oldAssignments.count( netName ) )
 
 2584            if( oldAssignments[netName] != netclasses )
 
 2586                affectedNetclassNetAssignments.insert( netName );
 
 2587                dirtySubgraphs( subgraphs );
 
 2590        else if( !netclasses.empty() )
 
 2592            affectedNetclassNetAssignments.insert( netName );
 
 2593            dirtySubgraphs( subgraphs );
 
 2599        checkNetclassDrivers( netname, subgraphs );
 
 2601    if( !aUnconditional )
 
 2603        for( 
auto& [netname, netclasses] : oldAssignments )
 
 2605            if( netSettings->GetNetclassLabelAssignments().count( netname )
 
 2606                || affectedNetclassNetAssignments.count( netname ) )
 
 2611            netSettings->SetNetclassLabelAssignment( netname, netclasses );
 
 
 2649    std::vector<std::shared_ptr<SCH_CONNECTION>> connections_to_check( aConnection->
Members() );
 
 2651    for( 
unsigned i = 0; i < connections_to_check.size(); i++ )
 
 2653        const std::shared_ptr<SCH_CONNECTION>& member = connections_to_check[i];
 
 2655        if( member->IsBus() )
 
 2657            connections_to_check.insert( connections_to_check.end(),
 
 2658                                         member->Members().begin(),
 
 2659                                         member->Members().end() );
 
 
 2671    std::vector<CONNECTION_SUBGRAPH*> search_list;
 
 2672    std::unordered_set<CONNECTION_SUBGRAPH*> visited;
 
 2673    std::unordered_set<SCH_CONNECTION*> stale_bus_members;
 
 2680            path.push_back( 
pin->GetParent() );
 
 2691                    || visited.contains( candidate ) )
 
 2700                        wxLogTrace( 
ConnTrace, wxS( 
"%lu: found child %lu (%s)" ), aParent->m_code,
 
 2708                        wxASSERT( candidate->
m_graph == aParent->m_graph );
 
 2710                        search_list.push_back( candidate );
 
 2730                    || visited.contains( candidate )
 
 2736                const KIID& last_parent_uuid = aParent->m_sheet.Last()->m_Uuid;
 
 2741                    if( 
pin->GetParent()->m_Uuid != last_parent_uuid )
 
 2747                    if( pin_path != aParent->m_sheet )
 
 2752                        wxLogTrace( 
ConnTrace, wxS( 
"%lu: found additional parent %lu (%s)" ),
 
 2755                        aParent->m_hier_children.insert( candidate );
 
 2756                        search_list.push_back( candidate );
 
 2766        for( 
const auto& 
kv : aParentGraph->m_bus_neighbors )
 
 2808                    wxLogTrace( 
ConnTrace, wxS( 
"Could not match bus member %s in %s" ),
 
 2809                                kv.first->Name(), parent->
Name() );
 
 2815                wxCHECK2( neighbor_conn, 
continue );
 
 2817                wxString neighbor_name = neighbor_conn->
Name();
 
 2820                if( neighbor_name == member->
Name() )
 
 2828                wxCHECK2_MSG( neighbor_conn->
IsNet(), 
continue,
 
 2829                              wxS( 
"\"" ) + neighbor_name + wxS( 
"\" is not a net." ) );
 
 2831                wxLogTrace( 
ConnTrace, wxS( 
"%lu (%s) connected to bus member %s (local %s)" ),
 
 2838                    member->
Clone( *neighbor_conn );
 
 2839                    stale_bus_members.insert( member );
 
 2843                    neighbor_conn->
Clone( *member );
 
 2857        propagate_bus_neighbors( aSubgraph );
 
 2864        wxLogTrace( 
ConnTrace, wxS( 
"%lu (%s) has both hier ports and pins; deferring processing" ),
 
 2870        wxLogTrace( 
ConnTrace, wxS( 
"%lu (%s) has no hier pins or ports on sheet %s; marking clean" ),
 
 2876    visited.insert( aSubgraph );
 
 2878    wxLogTrace( 
ConnTrace, wxS( 
"Propagating %lu (%s) to subsheets" ),
 
 2883    for( 
unsigned i = 0; i < search_list.size(); i++ )
 
 2885        auto child = search_list[i];
 
 2887        if( visited.insert( child ).second )
 
 2890        child->m_dirty = 
false;
 
 2904            if( subgraph == aSubgraph )
 
 2911            wxString candidateName   = subgraph->m_driver_connection->Name();
 
 2912            bool     shorterPath     = subgraph->m_sheet.size() < bestDriver->
m_sheet.
size();
 
 2913            bool     asGoodPath      = subgraph->m_sheet.size() <= bestDriver->
m_sheet.
size();
 
 2923                ( !bestIsStrong && candidateStrong ) ||
 
 2924                ( priority > highest && candidateStrong ) ||
 
 2925                ( priority == highest && candidateStrong && shorterPath ) ||
 
 2926                ( ( bestIsStrong == candidateStrong ) && asGoodPath && ( priority == highest ) &&
 
 2927                  ( candidateName < bestName ) ) )
 
 2929                bestDriver   = subgraph;
 
 2931                bestIsStrong = candidateStrong;
 
 2932                bestName     = candidateName;
 
 2937    if( bestDriver != aSubgraph )
 
 2939        wxLogTrace( 
ConnTrace, wxS( 
"%lu (%s) overridden by new driver %lu (%s)" ),
 
 2948        wxString old_name = subgraph->m_driver_connection->Name();
 
 2950        subgraph->m_driver_connection->Clone( *conn );
 
 2952        if( old_name != conn->
Name() )
 
 2956            propagate_bus_neighbors( subgraph );
 
 2962    if( conn->
IsBus() && !stale_bus_members.empty() )
 
 2964        std::unordered_set<SCH_CONNECTION*> cached_members = stale_bus_members;
 
 2974                    wxLogTrace( 
ConnTrace, wxS( 
"WARNING: failed to match stale member %s in %s." ),
 
 2975                                stale_member->Name(), subgraph->m_driver_connection->Name() );
 
 2979                wxLogTrace( 
ConnTrace, wxS( 
"Updating %lu (%s) member %s to %s" ), subgraph->m_code,
 
 2980                            subgraph->m_driver_connection->Name(), member->
LocalName(), stale_member->Name() );
 
 2982                member->
Clone( *stale_member );
 
 2984                propagate_bus_neighbors( subgraph );
 
 
 2996    std::shared_ptr<SCH_CONNECTION> c = std::shared_ptr<SCH_CONNECTION>( 
nullptr );
 
 2998    switch( aItem->
Type() )
 
 3001        if( 
static_cast<SCH_PIN*
>( aItem )->IsPower() )
 
 3002            c = std::make_shared<SCH_CONNECTION>( aItem, aSubgraph->
m_sheet );
 
 3009        c = std::make_shared<SCH_CONNECTION>( aItem, aSubgraph->
m_sheet );
 
 3018        c->SetGraph( 
this );
 
 
 3030    wxASSERT( aBusConnection->
IsBus() );
 
 3039        for( 
const std::shared_ptr<SCH_CONNECTION>& bus_member : aBusConnection->
Members() )
 
 3041            if( bus_member->VectorIndex() == aSearch->
VectorIndex() )
 
 3043                match = bus_member.get();
 
 3051        for( 
const std::shared_ptr<SCH_CONNECTION>& c : aBusConnection->
Members() )
 
 3058                for( 
const std::shared_ptr<SCH_CONNECTION>& bus_member : c->Members() )
 
 3060                    if( bus_member->LocalName() == aSearch->
LocalName() )
 
 3062                        match = bus_member.get();
 
 3067            else if( c->LocalName() == aSearch->
LocalName() )
 
 
 3085        std::vector<CONNECTION_SUBGRAPH*>& vec = it->second;
 
 3086        std::erase( vec, aSubgraph );
 
 3089    wxLogTrace( 
ConnTrace, wxS( 
"recacheSubgraphName: %s => %s" ), aOldName,
 
 
 3106    std::vector<const CONNECTION_SUBGRAPH*> ret;
 
 3112        wxASSERT( !subgraph->m_dirty );
 
 3114        if( !subgraph->m_driver )
 
 3120        if( !connection->
IsBus() )
 
 3123        auto labels = subgraph->GetVectorBusLabels();
 
 3125        if( labels.size() > 1 )
 
 3127            bool different = 
false;
 
 3130            for( 
unsigned i = 1; i < labels.size(); ++i )
 
 3142            wxLogTrace( 
ConnTrace, wxS( 
"SG %ld (%s) has multiple bus labels" ), subgraph->m_code,
 
 3143                        connection->
Name() );
 
 3145            ret.push_back( subgraph );
 
 
 3166            if( graph == aSubGraph )
 
 
 3209    wxASSERT( !it->second.empty() );
 
 3211    return it->second[0];
 
 
 3227const std::vector<CONNECTION_SUBGRAPH*>&
 
 3230    static const std::vector<CONNECTION_SUBGRAPH*> subgraphs;
 
 
 3243    int error_count = 0;
 
 3245    wxCHECK_MSG( 
m_schematic, 
true, wxS( 
"Null m_schematic in CONNECTION_GRAPH::RunERC" ) );
 
 3251    std::set<SCH_ITEM*> seenDriverInstances;
 
 3256        wxCHECK2( subgraph, 
continue );
 
 3260        wxASSERT( !subgraph->m_dirty );
 
 3262        if( subgraph->m_absorbed )
 
 3265        if( seenDriverInstances.count( subgraph->m_driver ) )
 
 3268        if( subgraph->m_driver )
 
 3269            seenDriverInstances.insert( subgraph->m_driver );
 
 3287        subgraph->ResolveDrivers( 
false );
 
 
 3358    wxCHECK( aSubgraph, 
false );
 
 3364            if( driver == aSubgraph->
m_driver )
 
 3375                if( primaryName == secondaryName )
 
 3378                wxString msg = wxString::Format( 
_( 
"Both %s and %s are attached to the same " 
 3379                                                    "items; %s will be used in the netlist" ),
 
 3380                                                 primaryName, secondaryName, primaryName );
 
 3383                ercItem->SetItems( aSubgraph->
m_driver, driver );
 
 3384                ercItem->SetSheetSpecificPath( aSubgraph->
GetSheet() );
 
 3385                ercItem->SetItemsSheetPaths( aSubgraph->
GetSheet(), aSubgraph->
m_sheet );
 
 3386                ercItem->SetErrorMessage( msg );
 
 
 3411        switch( item->
Type() )
 
 3416                bus_item = ( !bus_item ) ? item : bus_item;
 
 3418                net_item = ( !net_item ) ? item : net_item;
 
 3432                bus_item = ( !bus_item ) ? item : bus_item;
 
 3434                net_item = ( !net_item ) ? item : net_item;
 
 3444    if( net_item && bus_item )
 
 3447        ercItem->SetSheetSpecificPath( sheet );
 
 3448        ercItem->SetItems( net_item, bus_item );
 
 3451        screen->
Append( marker );
 
 
 3470        switch( item->
Type() )
 
 3497                if( 
test != member && member->Name() == 
test->Name() )
 
 3511            ercItem->SetSheetSpecificPath( sheet );
 
 3512            ercItem->SetItems( label, port );
 
 3515            screen->
Append( marker );
 
 
 3527    bool conflict = 
false;
 
 3543        switch( item->
Type() )
 
 3573            std::set<wxString> test_names;
 
 3585                    for( 
const auto& sub_member : member->Members() )
 
 3587                        if( test_names.count( sub_member->FullLocalName() ) )
 
 3591                else if( test_names.count( member->FullLocalName() ) )
 
 3610        wxString msg = wxString::Format( 
_( 
"Net %s is graphically connected to bus %s but is not a" 
 3611                                            " member of that bus" ),
 
 3615        ercItem->SetSheetSpecificPath( sheet );
 
 3616        ercItem->SetItems( bus_entry, bus_wire );
 
 3617        ercItem->SetErrorMessage( msg );
 
 3620        screen->
Append( marker );
 
 
 3637    std::set<SCH_PIN*>        unique_pins;
 
 3638    std::set<SCH_LABEL_BASE*> unique_labels;
 
 3646        for( 
SCH_ITEM* item : aProcessGraph->m_items )
 
 3648            switch( item->
Type() )
 
 3655                if( aProcessGraph == aSubgraph )
 
 3658                if( std::none_of( unique_pins.begin(), unique_pins.end(),
 
 3661                            return test_pin->IsStacked( aPin );
 
 3665                    unique_pins.insert( test_pin );
 
 3688            process_subgraph( subgraph );
 
 3693        process_subgraph( aSubgraph );
 
 3728            ercItem->SetSheetSpecificPath( sheet );
 
 3729            ercItem->SetItemsSheetPaths( sheet );
 
 3736                pos = 
pin->GetPosition();
 
 3745            screen->
Append( marker );
 
 3750        if( unique_pins.empty() && unique_labels.empty() &&
 
 3755            ercItem->SetSheetSpecificPath( sheet );
 
 3756            ercItem->SetItemsSheetPaths( sheet );
 
 3759            screen->
Append( marker );
 
 3766        bool has_other_connections = 
false;
 
 3767        std::vector<SCH_PIN*> pins;
 
 3774            switch( item->
Type() )
 
 3781                if( !has_other_connections && !pins.empty()
 
 3784                    for( 
SCH_PIN* other_pin  : pins )
 
 3788                            has_other_connections = 
true;
 
 3794                pins.emplace_back( 
static_cast<SCH_PIN*
>( item ) );
 
 3801                    has_other_connections = 
true;
 
 3808        pin = pins.empty() ? nullptr : pins[0];
 
 3811        for( 
SCH_PIN* test_pin : pins )
 
 3827        if( 
pin && !has_other_connections
 
 3829                && !
pin->GetLibPin()->GetParentSymbol()->IsPower() )
 
 3831            wxString 
name = 
pin->Connection( &sheet )->Name();
 
 3832            wxString local_name = 
pin->Connection( &sheet )->Name( 
true );
 
 3837                has_other_connections = 
true;
 
 3842        if( 
pin && !has_other_connections
 
 3848            ercItem->SetSheetSpecificPath( sheet );
 
 3849            ercItem->SetItemsSheetPaths( sheet );
 
 3850            ercItem->SetItems( 
pin );
 
 3853            screen->
Append( marker );
 
 3861        if( pins.size() > 1 )
 
 3863            for( 
SCH_PIN* testPin : pins )
 
 3868                if( testPin->GetLibPin()->GetParentSymbol()->IsPower()
 
 3869                    && testPin->ConnectedItems( sheet ).empty()
 
 3873                    ercItem->SetSheetSpecificPath( sheet );
 
 3874                    ercItem->SetItemsSheetPaths( sheet );
 
 3875                    ercItem->SetItems( testPin );
 
 3878                    screen->
Append( marker );
 
 
 3911                ercItem->SetItems( line );
 
 3912                ercItem->SetSheetSpecificPath( sheet );
 
 3913                ercItem->SetErrorMessage( 
_( 
"Unconnected wire endpoint" ) );
 
 3935                ercItem->SetItems( entry );
 
 3936                ercItem->SetSheetSpecificPath( sheet );
 
 3937                ercItem->SetErrorMessage( 
_( 
"Unconnected wire to bus entry" ) );
 
 3954    return err_count > 0;
 
 
 3964    std::vector<SCH_ITEM*> wires;
 
 3971            wires.emplace_back( item );
 
 3973            wires.emplace_back( item );
 
 3976    if( !wires.empty() )
 
 3981        ercItem->SetSheetSpecificPath( sheet );
 
 3982        ercItem->SetItems( wires[0],
 
 3983                           wires.size() > 1 ? wires[1] : 
nullptr,
 
 3984                           wires.size() > 2 ? wires[2] : 
nullptr,
 
 3985                           wires.size() > 3 ? wires[3] : 
nullptr );
 
 3988        screen->
Append( marker );
 
 
 4016    size_t                pinCount = 0;
 
 4019    std::map<KICAD_T, std::vector<SCH_TEXT*>> label_map;
 
 4025                return std::count_if( aLocSubgraph->m_items.begin(), aLocSubgraph->m_items.end(),
 
 4028                                          return item->Type() == SCH_PIN_T;
 
 4033            [&]( 
SCH_TEXT* aText, 
int errCode )
 
 4038                    ercItem->SetSheetSpecificPath( sheet );
 
 4039                    ercItem->SetItems( aText );
 
 4046    pinCount = 
hasPins( aSubgraph );
 
 4050        switch( item->
Type() )
 
 4058            label_map[item->
Type()].push_back( 
text );
 
 4063            if( 
text->IsDangling() )
 
 4077    if( label_map.empty() )
 
 4082    for( 
auto& [ connection, subgraphs ] : aSubgraph->
m_bus_parents )
 
 4086            if( busParent->m_no_connect )
 
 4109    wxCHECK_MSG( 
m_schematic, 
true, wxS( 
"Null m_schematic in CONNECTION_GRAPH::ercCheckLabels" ) );
 
 4116    for( 
auto& [type, label_vec] : label_map )
 
 4120            size_t allPins = pinCount;
 
 4128                    if( neighbor == aSubgraph )
 
 4134                    allPins += 
hasPins( neighbor );
 
 4138            if( allPins == 1 && !has_nc )
 
 
 4160    std::map<wxString, std::tuple<int, const SCH_ITEM*, SCH_SHEET_PATH>> labelData;
 
 4167            wxString  resolvedLabelText =
 
 4170            if( labelData.find( resolvedLabelText ) == labelData.end() )
 
 4172                labelData[resolvedLabelText] = { 1, item, sheet };
 
 4176                std::get<0>( labelData[resolvedLabelText] ) += 1;
 
 4177                std::get<1>( labelData[resolvedLabelText] ) = 
nullptr;
 
 4178                std::get<2>( labelData[resolvedLabelText] ) = sheet;
 
 4183    for( 
const auto& label : labelData )
 
 4185        if( std::get<0>( label.second ) == 1 )
 
 4188            const SCH_ITEM*       item = std::get<1>( label.second );
 
 4191            ercItem->SetItems( std::get<1>( label.second ) );
 
 4192            ercItem->SetSheetSpecificPath( sheet );
 
 4193            ercItem->SetItemsSheetPaths( sheet );
 
 
 4208    int error_count = 0;
 
 4220                ercItem->SetSheetSpecificPath( sheet );
 
 4221                ercItem->SetItems( 
text );
 
 4224                sheet.LastScreen()->Append( marker );
 
 
 4244        if( sheet.Last()->IsTopLevelSheet() )
 
 4250                wxCHECK2( label, 
continue );
 
 4252                msg.Printf( 
_( 
"Hierarchical label '%s' in root sheet cannot be connected to non-existent " 
 4256                ercItem->SetItems( item );
 
 4257                ercItem->SetErrorMessage( msg );
 
 4260                sheet.LastScreen()->Append( marker );
 
 4271            parentSheetPath.
push_back( parentSheet );
 
 4273            std::map<wxString, SCH_SHEET_PIN*> pins;
 
 4274            std::map<wxString, SCH_HIERLABEL*> labels;
 
 4279                    pins[ 
pin->GetShownText( &parentSheetPath, 
false ) ] = 
pin;
 
 4284                    ercItem->SetItems( 
pin );
 
 4285                    ercItem->SetSheetSpecificPath( sheet );
 
 4286                    ercItem->SetItemsSheetPaths( sheet );
 
 4289                    sheet.LastScreen()->Append( marker );
 
 4297                std::set<wxString> matchedPins;
 
 4304                        wxString       labelText = label->
GetShownText( &parentSheetPath, 
false );
 
 4306                        if( !pins.contains( labelText ) )
 
 4307                            labels[ labelText ] = label;
 
 4309                            matchedPins.insert( labelText );
 
 4313                for( 
const wxString& matched : matchedPins )
 
 4314                    pins.erase( matched );
 
 4316                for( 
const auto& [
name, 
pin] : pins )
 
 4318                    msg.Printf( 
_( 
"Sheet pin %s has no matching hierarchical label inside the sheet" ),
 
 4322                    ercItem->SetItems( 
pin );
 
 4323                    ercItem->SetErrorMessage( msg );
 
 4324                    ercItem->SetSheetSpecificPath( sheet );
 
 4325                    ercItem->SetItemsSheetPaths( sheet );
 
 4328                    sheet.LastScreen()->Append( marker );
 
 4333                for( 
const auto& [
name, label] : labels )
 
 4335                    msg.Printf( 
_( 
"Hierarchical label %s has no matching sheet pin in the parent sheet" ),
 
 4339                    ercItem->SetItems( label );
 
 4340                    ercItem->SetErrorMessage( msg );
 
 4341                    ercItem->SetSheetSpecificPath( parentSheetPath );
 
 4342                    ercItem->SetItemsSheetPaths( parentSheetPath );
 
 
constexpr EDA_IU_SCALE schIUScale
 
This represents a sentry transaction which is used for time-performance metrics You start a transacti...
 
void StartSpan(const std::string &aOperation, const std::string &aDescription)
 
int RunERC()
Run electrical rule checks on the connectivity graph.
 
bool ercCheckBusToBusConflicts(const CONNECTION_SUBGRAPH *aSubgraph)
Check one subgraph for conflicting connections between two bus items.
 
void processSubGraphs()
Process all subgraphs to assign netcodes and merge subgraphs based on labels.
 
bool ercCheckLabels(const CONNECTION_SUBGRAPH *aSubgraph)
Check one subgraph for proper connection of labels.
 
void RemoveItem(SCH_ITEM *aItem)
 
void collectAllDriverValues()
Map the driver values for each subgraph.
 
CONNECTION_SUBGRAPH * FindSubgraphByName(const wxString &aNetName, const SCH_SHEET_PATH &aPath)
Return the subgraph for a given net name on a given sheet.
 
int ercCheckDirectiveLabels()
Check directive labels should be connected to something.
 
void recacheSubgraphName(CONNECTION_SUBGRAPH *aSubgraph, const wxString &aOldName)
 
static SCH_CONNECTION * matchBusMember(SCH_CONNECTION *aBusConnection, SCH_CONNECTION *aSearch)
Search for a matching bus member inside a bus connection.
 
std::unordered_map< wxString, std::shared_ptr< BUS_ALIAS > > m_bus_alias_cache
 
SCHEMATIC * m_schematic
The schematic this graph represents.
 
void updateGenericItemConnectivity(const SCH_SHEET_PATH &aSheet, SCH_ITEM *aItem, std::map< VECTOR2I, std::vector< SCH_ITEM * > > &aConnectionMap)
Update the connectivity of items that are not pins or symbols.
 
std::unordered_map< SCH_SHEET_PATH, std::vector< CONNECTION_SUBGRAPH * > > m_sheet_to_subgraphs_map
Cache to lookup subgraphs in m_driver_subgraphs by sheet path.
 
void updateSymbolConnectivity(const SCH_SHEET_PATH &aSheet, SCH_SYMBOL *aSymbol, std::map< VECTOR2I, std::vector< SCH_ITEM * > > &aConnectionMap)
Update the connectivity of a symbol and its pins.
 
CONNECTION_SUBGRAPH * FindFirstSubgraphByName(const wxString &aNetName)
Retrieve a subgraph for the given net name, if one exists.
 
void propagateToNeighbors(CONNECTION_SUBGRAPH *aSubgraph, bool aForce)
Update all neighbors of a subgraph with this one's connectivity info.
 
void buildItemSubGraphs()
Generate individual item subgraphs on a per-sheet basis.
 
const std::vector< CONNECTION_SUBGRAPH * > & GetAllSubgraphs(const wxString &aNetName) const
 
bool ercCheckMultipleDrivers(const CONNECTION_SUBGRAPH *aSubgraph)
If the subgraph has multiple drivers of equal priority that are graphically connected,...
 
SCH_SHEET_LIST m_sheetList
All the sheets in the schematic (as long as we don't have partial updates).
 
void generateGlobalPowerPinSubGraphs()
Iterate through the global power pins to collect the global labels as drivers.
 
std::unordered_map< wxString, int > m_net_name_to_code_map
 
int ercCheckSingleGlobalLabel()
Check that a global label is instantiated more that once across the schematic hierarchy.
 
int ercCheckHierSheets()
Check that a hierarchical sheet has at least one matching label inside the sheet for each port on the...
 
bool ercCheckBusToNetConflicts(const CONNECTION_SUBGRAPH *aSubgraph)
Check one subgraph for conflicting connections between net and bus labels.
 
std::shared_ptr< SCH_CONNECTION > getDefaultConnection(SCH_ITEM *aItem, CONNECTION_SUBGRAPH *aSubgraph)
Build a new default connection for the given item based on its properties.
 
std::vector< const CONNECTION_SUBGRAPH * > GetBusesNeedingMigration()
Determine which subgraphs have more than one conflicting bus label.
 
void Recalculate(const SCH_SHEET_LIST &aSheetList, bool aUnconditional=false, std::function< void(SCH_ITEM *)> *aChangedItemHandler=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr)
Update the connection graph for the given list of sheets.
 
int assignNewNetCode(SCH_CONNECTION &aConnection)
Helper to assign a new net code to a connection.
 
std::map< std::pair< SCH_SHEET_PATH, wxString >, std::vector< const CONNECTION_SUBGRAPH * > > m_local_label_cache
 
int getOrCreateNetCode(const wxString &aNetName)
 
bool ercCheckDanglingWireEndpoints(const CONNECTION_SUBGRAPH *aSubgraph)
Check one subgraph for dangling wire endpoints.
 
void assignNetCodesToBus(SCH_CONNECTION *aConnection)
Ensure all members of the bus connection have a valid net code assigned.
 
std::unordered_map< wxString, int > m_bus_name_to_code_map
 
std::unordered_map< wxString, std::vector< const CONNECTION_SUBGRAPH * > > m_global_label_cache
 
std::vector< CONNECTION_SUBGRAPH * > m_subgraphs
The owner of all CONNECTION_SUBGRAPH objects.
 
std::vector< std::pair< SCH_SHEET_PATH, SCH_PIN * > > m_global_power_pins
 
CONNECTION_GRAPH(SCHEMATIC *aSchematic=nullptr)
 
bool ercCheckNoConnects(const CONNECTION_SUBGRAPH *aSubgraph)
Check one subgraph for proper presence or absence of no-connect symbols.
 
size_t hasPins(const CONNECTION_SUBGRAPH *aLocSubgraph)
Get the number of pins in a given subgraph.
 
std::vector< SCH_ITEM * > m_items
All connectable items in the schematic.
 
std::unordered_map< wxString, std::vector< CONNECTION_SUBGRAPH * > > m_net_name_to_subgraphs_map
 
std::shared_ptr< BUS_ALIAS > GetBusAlias(const wxString &aName)
Return a bus alias pointer for the given name if it exists (from cache)
 
void removeSubgraphs(std::set< CONNECTION_SUBGRAPH * > &aSubgraphs)
Remove references to the given subgraphs from all structures in the connection graph.
 
std::unordered_map< SCH_ITEM *, CONNECTION_SUBGRAPH * > m_item_to_subgraph_map
 
std::set< std::pair< SCH_SHEET_PATH, SCH_ITEM * > > ExtractAffectedItems(const std::set< SCH_ITEM * > &aItems)
For a set of items, this will remove the connected items and their associated data including subgraph...
 
wxString GetResolvedSubgraphName(const CONNECTION_SUBGRAPH *aSubGraph) const
Return the fully-resolved netname for a given subgraph.
 
bool ercCheckBusToBusEntryConflicts(const CONNECTION_SUBGRAPH *aSubgraph)
Check one subgraph for conflicting bus entry to bus connections.
 
std::vector< CONNECTION_SUBGRAPH * > m_driver_subgraphs
Cache of a subset of m_subgraphs.
 
void ExchangeItem(SCH_ITEM *aOldItem, SCH_ITEM *aNewItem)
Replace all references to #aOldItem with #aNewItem in the graph.
 
NET_MAP m_net_code_to_subgraphs_map
 
bool ercCheckFloatingWires(const CONNECTION_SUBGRAPH *aSubgraph)
Check one subgraph for floating wires.
 
void buildConnectionGraph(std::function< void(SCH_ITEM *)> *aChangedItemHandler, bool aUnconditional)
Generate the connection graph (after all item connectivity has been updated).
 
void Merge(CONNECTION_GRAPH &aGraph)
Combine the input graph contents into the current graph.
 
void updatePinConnectivity(const SCH_SHEET_PATH &aSheet, SCH_PIN *aPin, SCH_CONNECTION *aConnection)
Update the connectivity of a pin and its connections.
 
void resolveAllDrivers()
Find all subgraphs in the connection graph and calls ResolveDrivers() in parallel.
 
void updateItemConnectivity(const SCH_SHEET_PATH &aSheet, const std::vector< SCH_ITEM * > &aItemList)
Update the graphical connectivity between items (i.e.
 
CONNECTION_SUBGRAPH * GetSubgraphForItem(SCH_ITEM *aItem) const
 
void generateBusAliasMembers()
Iterate through labels to create placeholders for bus elements.
 
A subgraph is a set of items that are electrically connected on a single sheet.
 
wxString driverName(SCH_ITEM *aItem) const
 
PRIORITY GetDriverPriority()
 
bool m_strong_driver
True if the driver is "strong": a label or power object.
 
SCH_ITEM * m_no_connect
No-connect item in graph, if any.
 
std::set< CONNECTION_SUBGRAPH * > m_absorbed_subgraphs
Set of subgraphs that have been absorbed by this subgraph.
 
static PRIORITY GetDriverPriority(SCH_ITEM *aDriver)
Return the priority (higher is more important) of a candidate driver.
 
std::mutex m_driver_name_cache_mutex
A cache of escaped netnames from schematic items.
 
SCH_SHEET_PATH m_sheet
On which logical sheet is the subgraph contained.
 
void UpdateItemConnections()
Update all items to match the driver connection.
 
std::set< SCH_SHEET_PIN * > m_hier_pins
Cache for lookup of any hierarchical (sheet) pins on this subgraph (for referring down).
 
std::unordered_map< std::shared_ptr< SCH_CONNECTION >, std::unordered_set< CONNECTION_SUBGRAPH * > > m_bus_neighbors
If a subgraph is a bus, this map contains links between the bus members and any local sheet neighbors...
 
CONNECTION_GRAPH * m_graph
 
std::vector< SCH_ITEM * > GetAllBusLabels() const
Return all the all bus labels attached to this subgraph (if any).
 
std::unordered_map< SCH_ITEM *, wxString > m_driver_name_cache
 
const wxString & GetNameForDriver(SCH_ITEM *aItem) const
Return the candidate net name for a driver.
 
wxString GetNetName() const
Return the fully-qualified net name for this subgraph (if one exists)
 
std::vector< SCH_ITEM * > GetVectorBusLabels() const
Return all the vector-based bus labels attached to this subgraph (if any).
 
const SCH_SHEET_PATH & GetSheet() const
 
bool m_multiple_drivers
True if this subgraph contains more than one driver that should be shorted together in the netlist.
 
bool ResolveDrivers(bool aCheckMultipleDrivers=false)
Determine which potential driver should drive the subgraph.
 
std::set< SCH_ITEM * > m_drivers
 
bool m_absorbed
True if this subgraph has been absorbed into another. No pointers here are safe if so!
 
SCH_CONNECTION * m_driver_connection
Cache for driver connection.
 
CONNECTION_SUBGRAPH * m_absorbed_by
If this subgraph is absorbed, points to the absorbing (and valid) subgraph.
 
std::unordered_set< CONNECTION_SUBGRAPH * > m_hier_children
If not null, this indicates the subgraph(s) on a lower level sheet that are linked to this one.
 
void AddItem(SCH_ITEM *aItem)
Add a new item to the subgraph.
 
const std::vector< std::pair< wxString, SCH_ITEM * > > GetNetclassesForDriver(SCH_ITEM *aItem) const
Return the resolved netclasses for the item, and the source item providing the netclass.
 
void Absorb(CONNECTION_SUBGRAPH *aOther)
Combine another subgraph on the same sheet into this one.
 
std::set< SCH_ITEM * > m_items
Contents of the subgraph.
 
std::unordered_map< std::shared_ptr< SCH_CONNECTION >, std::unordered_set< CONNECTION_SUBGRAPH * > > m_bus_parents
If this is a net, this vector contains links to any same-sheet buses that contain it.
 
SCH_ITEM * m_driver
Fully-resolved driver for the subgraph (might not exist in this subgraph).
 
CONNECTION_SUBGRAPH(CONNECTION_GRAPH *aGraph)
 
std::mutex m_driver_mutex
 
bool m_is_bus_member
True if the subgraph is not actually part of a net.
 
void ExchangeItem(SCH_ITEM *aOldItem, SCH_ITEM *aNewItem)
Replaces all references to #aOldItem with #aNewItem in the subgraph.
 
CONNECTION_SUBGRAPH * m_hier_parent
If not null, this indicates the subgraph on a higher level sheet that is linked to this one.
 
void RemoveItem(SCH_ITEM *aItem)
 
bool m_local_driver
True if the driver is a local (i.e. non-global) type.
 
std::set< SCH_HIERLABEL * > m_hier_ports
Cache for lookup of any hierarchical ports on this subgraph (for referring up).
 
void getAllConnectedItems(std::set< std::pair< SCH_SHEET_PATH, SCH_ITEM * > > &aItems, std::set< CONNECTION_SUBGRAPH * > &aSubgraphs)
Find all items in the subgraph as well as child subgraphs recursively.
 
virtual VECTOR2I GetPosition() const
 
virtual wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const
Return a user-visible description string of this item.
 
KICAD_T Type() const
Returns the type of object.
 
EE_TYPE Overlapping(const BOX2I &aRect) const
 
EE_TYPE OfType(KICAD_T aType) const
 
static std::shared_ptr< ERC_ITEM > Create(int aErrorCode)
Constructs an ERC_ITEM for the given error code.
 
Container for ERC settings.
 
bool IsTestEnabled(int aErrorCode) const
 
bool GetDuplicatePinNumbersAreJumpers() const
 
std::vector< std::set< wxString > > & JumperPinGroups()
Each jumper pin group is a set of pin numbers that should be treated as internally connected.
 
A small class to help profiling.
 
void Show(std::ostream &aStream=std::cerr)
Print the elapsed time (in a suitable unit) to a stream.
 
void Stop()
Save the time when this function was called, and set the counter stane to stop.
 
A progress reporter interface for use in multi-threaded environments.
 
virtual bool KeepRefreshing(bool aWait=false)=0
Update the UI (if any).
 
virtual void SetCurrentProgress(double aProgress)=0
Set the progress value to aProgress (0..1).
 
Class for a bus to bus entry.
 
SCH_ITEM * m_connected_bus_items[2]
Pointer to the bus items (usually bus wires) connected to this bus-bus entry (either or both may be n...
 
bool IsStartDangling() const
 
VECTOR2I GetPosition() const override
 
bool IsEndDangling() const
 
std::vector< VECTOR2I > GetConnectionPoints() const override
Add all the connection points for this item to aPoints.
 
Class for a wire to bus entry.
 
SCH_ITEM * m_connected_bus_item
Pointer to the bus item (usually a bus wire) connected to this bus-wire entry, if it is connected to ...
 
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
 
wxString FullLocalName() const
 
void ConfigureFromLabel(const wxString &aLabel)
Configures the connection given a label.
 
void SetSubgraphCode(int aCode)
 
void SetBusCode(int aCode)
 
void SetName(const wxString &aName)
 
SCH_SHEET_PATH Sheet() const
 
CONNECTION_TYPE Type() const
 
void SetNetCode(int aCode)
 
SCH_ITEM * m_driver
The SCH_ITEM that drives this connection's net.
 
bool IsDriver() const
Checks if the SCH_ITEM this connection is attached to can drive connections Drivers can be labels,...
 
void SetType(CONNECTION_TYPE aType)
 
wxString LocalName() const
 
wxString Name(bool aIgnoreSheet=false) const
 
bool IsSubsetOf(SCH_CONNECTION *aOther) const
Returns true if this connection is contained within aOther (but not the same as aOther)
 
void SetDriver(SCH_ITEM *aItem)
 
void Clone(const SCH_CONNECTION &aOther)
Copies connectivity information (but not parent) from another connection.
 
void SetGraph(CONNECTION_GRAPH *aGraph)
 
const std::vector< std::shared_ptr< SCH_CONNECTION > > & Members() const
 
wxString GetCanonicalName() const
Get a non-language-specific name for a field which can be used for storage, variable look-up,...
 
wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0) const
 
Base class for any item which can be embedded within the SCHEMATIC container class,...
 
void ClearConnectedItems(const SCH_SHEET_PATH &aPath)
Clear all connections to this item.
 
virtual void RunOnChildren(const std::function< void(SCH_ITEM *)> &aFunction, RECURSE_MODE aMode)
 
const SYMBOL * GetParentSymbol() const
 
virtual const wxString & GetCachedDriverName() const
 
const std::unordered_set< SCH_RULE_AREA * > & GetRuleAreaCache() const
Get the cache of rule areas enclosing this item.
 
SCH_CONNECTION * InitializeConnection(const SCH_SHEET_PATH &aPath, CONNECTION_GRAPH *aGraph)
Create a new connection object associated with this object.
 
void AddConnectionTo(const SCH_SHEET_PATH &aPath, SCH_ITEM *aItem)
Add a connection link between this item and another.
 
SCH_LAYER_ID GetLayer() const
Return the layer this item is on.
 
void SetConnectionGraph(CONNECTION_GRAPH *aGraph)
Update the connection graph for all connections in this item.
 
virtual void SetUnit(int aUnit)
 
virtual bool HasCachedDriverName() const
 
SCH_CONNECTION * GetOrInitConnection(const SCH_SHEET_PATH &aPath, CONNECTION_GRAPH *aGraph)
 
SCH_CONNECTION * Connection(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieve the connection associated with this object in the given sheet.
 
virtual std::vector< VECTOR2I > GetConnectionPoints() const
Add all the connection points for this item to aPoints.
 
wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0) const override
 
bool IsDangling() const override
 
LABEL_FLAG_SHAPE GetShape() const
 
Segment description base class to describe items which have 2 end points (track, wire,...
 
std::vector< VECTOR2I > GetConnectionPoints() const override
Add all the connection points for this item to aPoints.
 
bool IsStartDangling() const
 
bool IsEndDangling() const
 
bool IsGraphicLine() const
Return if the line is a graphic (non electrical line)
 
bool IsGlobalPower() const
Return whether this pin forms a global power connection: i.e., is part of a power symbol and of type ...
 
bool IsLocalPower() const
Local power pin is the same except that it is sheet-local and it does not support the legacy hidden p...
 
SCH_PIN * GetLibPin() const
 
bool IsStacked(const SCH_PIN *aPin) const
 
wxString GetDefaultNetName(const SCH_SHEET_PATH &aPath, bool aForceNoConnect=false)
 
bool IsPower() const
Check if the pin is either a global or local power pin.
 
ELECTRICAL_PINTYPE GetType() const
 
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
 
void TestDanglingEnds(const SCH_SHEET_PATH *aPath=nullptr, std::function< void(SCH_ITEM *)> *aChangedHandler=nullptr) const
Test all of the connectable objects in the schematic for unused connection points.
 
EE_RTREE & Items()
Get the full RTree, usually for iterating.
 
SCH_LINE * GetBus(const VECTOR2I &aPosition, int aAccuracy=0, SCH_LINE_TEST_T aSearchType=ENTIRE_LENGTH_T) const
 
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
 
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
 
const SCH_SHEET * GetSheet(unsigned aIndex) const
 
wxString PathHumanReadable(bool aUseShortRootName=true, bool aStripTrailingSeparator=false) const
Return the sheet path in a human readable form made from the sheet names.
 
SCH_SCREEN * LastScreen()
 
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
 
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
 
size_t size() const
Forwarded method from std::vector.
 
Define a sheet pin (label) used in sheets to create hierarchical schematics.
 
SCH_SHEET * GetParent() const
Get the parent sheet object of this sheet pin.
 
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
 
wxString GetFileName() const
Return the filename corresponding to this sheet.
 
SCH_SCREEN * GetScreen() const
 
std::vector< SCH_SHEET_PIN * > & GetPins()
 
std::vector< SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet) const
Retrieve a list of the SCH_PINs for the given sheet path.
 
int GetUnitSelection(const SCH_SHEET_PATH *aSheet) const
Return the instance-specific unit selection for the given sheet path.
 
SCH_PIN * GetPin(const wxString &number) const
Find a symbol pin by number.
 
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
 
VECTOR2I GetPosition() const override
 
virtual wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0) const
 
virtual bool IsGlobalPower() const =0
 
virtual bool IsLocalPower() const =0
 
virtual bool IsPower() const =0
 
bool GetExcludedFromBoard() const override
 
#define CONNECTIVITY_CANDIDATE
flag indicating that the structure is connected for connectivity
 
@ ERCE_DRIVER_CONFLICT
Conflicting drivers (labels, etc) on a subgraph.
 
@ ERCE_UNCONNECTED_WIRE_ENDPOINT
A label is connected to more than one wire.
 
@ ERCE_LABEL_NOT_CONNECTED
Label not connected to any pins.
 
@ ERCE_BUS_TO_BUS_CONFLICT
A connection between bus objects doesn't share at least one net.
 
@ ERCE_LABEL_SINGLE_PIN
A label is connected only to a single pin.
 
@ ERCE_BUS_ENTRY_CONFLICT
A wire connected to a bus doesn't match the bus.
 
@ ERCE_BUS_TO_NET_CONFLICT
A bus wire is graphically connected to a net port/pin (or vice versa).
 
@ ERCE_NOCONNECT_NOT_CONNECTED
A no connect symbol is not connected to anything.
 
@ ERCE_PIN_NOT_CONNECTED
Pin not connected and not no connect symbol.
 
@ ERCE_NOCONNECT_CONNECTED
A no connect symbol is connected to more than 1 pin.
 
@ ERCE_HIERACHICAL_LABEL
Mismatch between hierarchical labels and pins sheets.
 
@ ERCE_WIRE_DANGLING
Some wires are not connected to anything else.
 
@ ERCE_SINGLE_GLOBAL_LABEL
A label only exists once in the schematic.
 
static const wxChar DanglingProfileMask[]
Flag to enable connectivity profiling.
 
static const wxChar ConnTrace[]
Flag to enable connectivity tracing.
 
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
 
void remove_duplicates(_Container &__c)
Deletes all duplicate values from __c.
 
@ PT_NC
not connected (must be left open)
 
@ PT_NIC
not internally connected (may be connected to anything)
 
@ PT_POWER_IN
power input (GND, VCC for ICs). Must be connected to a power output.
 
@ BUS
This item represents a bus vector.
 
@ NET
This item represents a net.
 
@ BUS_GROUP
This item represents a bus group.
 
std::vector< SCH_ITEM * > SCH_ITEM_VEC
 
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
 
std::vector< FAB_LAYER_COLOR > dummy
 
wxString UnescapeString(const wxString &aSource)
 
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
 
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.
 
BS::thread_pool< 0 > thread_pool
 
Functions to provide common constants and other functions to assist in making a consistent UI.
 
VECTOR2< int32_t > VECTOR2I