85 _(
"Bidirectional Pin" ),
89 _(
"Unspecified Pin" ),
90 _(
"Power Input Pin" ),
91 _(
"Power Output Pin" ),
92 _(
"Open Collector" ),
102 _(
"Bidirectional Pin" ),
103 _(
"Tri-State Pin" ),
106 _(
"Unspecified Pin" ),
107 _(
"Power Input Pin" ),
108 _(
"Power Output Pin" ),
109 _(
"Open Collector" ),
152 std::vector<SCH_SHEET*> list;
155 list.push_back(
static_cast<SCH_SHEET*
>( item ) );
157 for(
size_t i = 0; i < list.size(); i++ )
161 for(
size_t j = i + 1; j < list.size(); j++ )
168 const wxString variant =
m_schematic->GetCurrentVariant();
169 const wxString
name =
171 const wxString other =
174 if(
name.IsSameAs( other,
false ) )
179 ercItem->SetItems( sheet, test_item );
180 ercItem->SetSheetSpecificPath(
path );
181 ercItem->SetItemsSheetPaths(
path,
path );
204 typedef void ( *PAD_NUMBERS_FN_PTR )(
const wxString&,
PROJECT*, std::set<wxString>& );
206 PAD_NUMBERS_FN_PTR padFetcher =
209 std::map<wxString, std::set<wxString>> padCache;
211 auto getPads = [&](
const wxString& aFootprintId ) ->
const std::set<wxString>&
213 auto it = padCache.find( aFootprintId );
215 if( it != padCache.end() )
218 std::set<wxString>& pads = padCache[aFootprintId];
220 if( padFetcher && !aFootprintId.IsEmpty() )
221 padFetcher( aFootprintId, aProject, pads );
243 std::set<wxString> pinNumbers;
246 pinNumbers.insert(
pin->GetNumber() );
248 const std::vector<std::set<wxString>>& jumperGroups = lib->
JumperPinGroups();
250 auto sharesJumperGroup = [&](
const wxString& aPinA,
const wxString& aPinB )
252 for(
const std::set<wxString>&
group : jumperGroups )
254 if(
group.count( aPinA ) &&
group.count( aPinB ) )
267 if( pinNumbers.count( entry.m_PinNumber ) )
271 ercItem->SetItems( symbol );
272 ercItem->SetErrorMessage(
273 wxString::Format(
_(
"Pin map '%s' references unknown symbol pin '%s'" ), map.GetName(),
274 entry.m_PinNumber ) );
283 std::map<wxString, wxString> padToPin;
289 auto it = padToPin.find(
pad );
291 if( it == padToPin.end() )
293 padToPin[
pad] = entry.m_PinNumber;
295 else if( it->second != entry.m_PinNumber
296 && !sharesJumperGroup( it->second, entry.m_PinNumber ) )
299 ercItem->SetItems( symbol );
300 ercItem->SetErrorMessage(
301 wxString::Format(
_(
"Symbol pins '%s' and '%s' both map to pad '%s'" ),
302 it->second, entry.m_PinNumber,
pad ) );
311 if( checkBadPad && padFetcher )
320 const std::set<wxString>& pads = getPads( assoc.m_FootprintLibId.GetUniStringLibId() );
329 if( pads.count(
pad ) )
333 ercItem->SetItems( symbol );
334 ercItem->SetErrorMessage( wxString::Format(
335 _(
"Pin map '%s' references pad '%s' not present on footprint '%s'" ),
336 boundMap->
GetName(),
pad, assoc.m_FootprintLibId.GetUniStringLibId() ) );
363 if( fpText.IsEmpty() || fpId.
Parse( fpText,
true ) >= 0 )
373 if(
pin->IsDangling() )
377 pin->GetEffectivePadNumber( sheet, variant, fpId, &pads, &state );
379 if( state != SCH_PIN::PAD_RESOLUTION::UNMAPPED )
383 ercItem->SetItems(
pin );
384 ercItem->SetErrorMessage( wxString::Format(
_(
"Pin '%s' is connected but maps to no pad "
385 "on footprint '%s'" ),
388 sheet.LastScreen()->Append(
new SCH_MARKER( std::move( ercItem ),
pin->GetPosition() ) );
405 static wxRegEx varRefRegEx( wxT(
"(^|[^\\\\])\\$\\{.*\\}.*" ) );
408 [&](
const wxString& str )
423 static wxRegEx warningExpr( wxS(
"(^|[^\\\\])\\$\\{ERC_WARNING\\s*([^}]*)\\}" ) );
424 static wxRegEx errorExpr( wxS(
"(^|[^\\\\])\\$\\{ERC_ERROR\\s*([^}]*)\\}" ) );
427 [&]( wxRegEx& aExpr,
int aErrorCode )
434 wxString remaining =
text;
436 while( aExpr.Matches( remaining ) )
440 wxString ercText = aExpr.GetMatch( remaining, 2 );
445 ercItem->SetItems( item );
447 ercText +=
_(
" (in drawing sheet)" );
449 ercItem->SetSheetSpecificPath( sheet );
450 ercItem->SetErrorMessage( ercText );
453 screen->Append( marker );
458 if( !aExpr.GetMatch( &start, &len, 0 ) || len == 0 )
461 remaining = remaining.Mid( start + len );
470 return foundWarning || foundError;
496 if( testAssertion( &field, sheet, screen, field.GetText(), field.
GetPosition() ) )
500 else if( unresolved( field.GetShownText( &sheet,
FOR_ERC_DRC ) ) )
503 ercItem->SetItems( symbol );
504 ercItem->SetSheetSpecificPath( sheet );
524 if( testAssertion( symbol, sheet, screen, textItem->
GetText(),
532 ercItem->SetItems( symbol );
533 ercItem->SetSheetSpecificPath( sheet );
547 if( testAssertion( symbol, sheet, screen, textboxItem->
GetText(),
555 ercItem->SetItems( symbol );
556 ercItem->SetSheetSpecificPath( sheet );
572 for(
SCH_FIELD& field : label->GetFields() )
574 if( testAssertion( &field, sheet, screen, field.GetText(), field.
GetPosition() ) )
578 else if( unresolved( field.GetShownText( &sheet,
FOR_ERC_DRC ) ) )
581 ercItem->SetItems( label );
582 ercItem->SetSheetSpecificPath( sheet );
595 if( testAssertion( &field, sheet, screen, field.GetText(), field.
GetPosition() ) )
599 else if( unresolved( field.GetShownText( &sheet,
FOR_ERC_DRC ) ) )
602 ercItem->SetItems( subSheet );
603 ercItem->SetSheetSpecificPath( sheet );
615 if( varRefRegEx.Matches(
pin->GetShownText( &subSheetPath,
FOR_ERC_DRC ) ) )
618 ercItem->SetItems(
pin );
619 ercItem->SetSheetSpecificPath( sheet );
628 if( testAssertion(
text, sheet, screen,
text->GetText(),
text->GetPosition() ) )
632 else if( varRefRegEx.Matches(
text->GetShownText( &sheet,
FOR_ERC_DRC ) ) )
635 ercItem->SetItems(
text );
636 ercItem->SetSheetSpecificPath( sheet );
644 if( testAssertion( textBox, sheet, screen, textBox->GetText(), textBox->
GetPosition() ) )
648 else if( varRefRegEx.Matches( textBox->GetShownText(
nullptr, &sheet,
FOR_ERC_DRC ) ) )
651 ercItem->SetItems( textBox );
652 ercItem->SetSheetSpecificPath( sheet );
664 if( testAssertion(
nullptr, sheet, screen,
text->GetText(),
text->GetPosition() ) )
671 ercItem->SetErrorMessage(
_(
"Unresolved text variable in drawing sheet" ) );
672 ercItem->SetSheetSpecificPath( sheet );
701 text.Trim(
false ).Trim(
true );
706 ercItem->SetItems( label );
707 ercItem->SetItemsSheetPaths( sheet );
708 ercItem->SetSheetSpecificPath( sheet );
736 wxString trimmedFieldName = field.GetName();
737 trimmedFieldName.Trim();
738 trimmedFieldName.Trim(
false );
740 if( field.GetName() != trimmedFieldName )
743 ercItem->SetItems( symbol, &field );
744 ercItem->SetItemsSheetPaths( sheet, sheet );
745 ercItem->SetSheetSpecificPath( sheet );
746 ercItem->SetErrorMessage(
748 _(
"Field name has leading or trailing whitespace: '%s'" ),
764 wxString trimmedFieldName = field.GetName();
765 trimmedFieldName.Trim();
766 trimmedFieldName.Trim(
false );
768 if( field.GetName() != trimmedFieldName )
771 ercItem->SetItems( subSheet, &field );
772 ercItem->SetItemsSheetPaths( sheet, sheet );
773 ercItem->SetSheetSpecificPath( sheet );
774 ercItem->SetErrorMessage(
776 _(
"Field name has leading or trailing whitespace: '%s'" ),
795 for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol :
m_refMap )
810 for(
size_t ii = 0; ii < refList.
GetCount(); ++ii )
815 if( !unitFP.IsEmpty() )
818 unitName = unit->
GetRef( &sheetPath,
true );
823 for(
size_t ii = 0; ii < refList.
GetCount(); ++ii )
831 if( unit && !secondFp.IsEmpty() && unitFP != secondFp )
833 msg.Printf(
_(
"Different footprints assigned to %s and %s" ),
834 unitName, secondName );
837 ercItem->SetErrorMessage( msg );
838 ercItem->SetItems( unit, secondUnit );
856 for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol :
m_refMap )
860 wxCHECK2( refList.
GetCount(),
continue );
870 std::set<int> lib_units;
871 std::set<int> instance_units;
872 std::set<int> missing_units;
875 [&]( std::set<int>& aMissingUnits,
const wxString& aErrorMsg,
int aErrorCode )
878 wxString missing_pin_units = wxS(
"[ " );
881 for(
int missing_unit : aMissingUnits )
885 missing_pin_units += wxS(
"..." );
892 missing_pin_units.Truncate( missing_pin_units.length() - 2 );
893 missing_pin_units += wxS(
" ]" );
895 msg.Printf( aErrorMsg, symbol.first, missing_pin_units );
898 ercItem->SetErrorMessage( msg );
899 ercItem->SetItems( unit );
900 ercItem->SetSheetSpecificPath( base_ref.
GetSheetPath() );
909 for(
int ii = 1; ii <= libSymbol->
GetUnitCount(); ++ii )
910 lib_units.insert( lib_units.end(), ii );
912 for(
size_t ii = 0; ii < refList.
GetCount(); ++ii )
913 instance_units.insert( instance_units.end(), refList.
GetItem( ii ).
GetUnit() );
915 std::set_difference( lib_units.begin(), lib_units.end(),
916 instance_units.begin(), instance_units.end(),
917 std::inserter( missing_units, missing_units.begin() ) );
924 std::set<int> missing_power;
925 std::set<int> missing_input;
926 std::set<int> missing_bidi;
928 for(
int missing_unit : missing_units )
932 for(
size_t ii = 0; ii < refList.
GetCount(); ++ii )
943 switch(
pin->GetType() )
946 missing_power.insert( missing_unit );
950 missing_bidi.insert( missing_unit );
954 missing_input.insert( missing_unit );
965 report( missing_power,
_(
"Symbol %s has input power pins in units %s that are not placed" ),
971 report( missing_input,
_(
"Symbol %s has input pins in units %s that are not placed" ),
977 report( missing_bidi,
_(
"Symbol %s has bidirectional pins in units %s that are not placed" ),
989 std::shared_ptr<NET_SETTINGS>& settings =
m_schematic->Project().GetProjectFile().NetSettings();
990 wxString defaultNetclass = settings->GetDefaultNetclass()->GetName();
999 ercItem->SetItems( item );
1000 ercItem->SetErrorMessage( wxString::Format(
_(
"Netclass %s is not defined" ), netclass ) );
1010 item->RunOnChildren(
1022 if( !netclass.empty() && !netclass.IsSameAs( defaultNetclass )
1023 && !settings->HasNetclass( netclass ) )
1025 logError( sheet, item, netclass );
1046 std::map<VECTOR2I, std::vector<SCH_ITEM*>> connMap;
1053 connMap[pt].emplace_back( label );
1056 for(
const std::pair<
const VECTOR2I, std::vector<SCH_ITEM*>>& pair : connMap )
1058 std::vector<SCH_ITEM*> lines;
1060 for(
SCH_ITEM* item : sheet.LastScreen()->Items().Overlapping(
SCH_LINE_T, pair.first ) )
1069 lines.emplace_back( line );
1072 if( lines.size() > 1 )
1078 wxString msg = wxString::Format(
_(
"Label connects more than one wire at %d, %d" ),
1079 pair.first.x, pair.first.y );
1081 ercItem->SetItems( pair.second.front(), lines[0], lines[1], lines[2] );
1082 ercItem->SetErrorMessage( msg );
1083 ercItem->SetSheetSpecificPath( sheet );
1086 sheet.LastScreen()->Append( marker );
1099 auto pinStackAlreadyRepresented =
1100 [](
SCH_PIN*
pin, std::vector<SCH_ITEM*>& collection ) ->
bool
1102 for(
SCH_ITEM*& item : collection )
1104 if( item->Type() ==
SCH_PIN_T && item->GetParentSymbol() ==
pin->GetParentSymbol() )
1118 std::map<VECTOR2I, std::vector<SCH_ITEM*>> connMap;
1127 std::vector<SCH_ITEM*>& entry = connMap[
pin->GetPosition()];
1130 if( pinStackAlreadyRepresented(
pin, entry ) )
1133 entry.emplace_back(
pin );
1145 connMap[pt].emplace_back( line );
1148 for(
const std::pair<
const VECTOR2I, std::vector<SCH_ITEM*>>& pair : connMap )
1150 if( pair.second.size() >= 4 )
1156 ercItem->SetItems( pair.second[0], pair.second[1], pair.second[2], pair.second[3] );
1158 wxString msg = wxString::Format(
_(
"Four items connected at %d, %d" ),
1159 pair.first.x, pair.first.y );
1160 ercItem->SetErrorMessage( msg );
1162 ercItem->SetSheetSpecificPath( sheet );
1165 sheet.LastScreen()->Append( marker );
1180 std::map<VECTOR2I, std::vector<SCH_ITEM*>> pinMap;
1185 if( pinMap.count( pt ) )
1186 pinMap[pt].emplace_back( aOther );
1196 pinMap[
pin->GetPosition()].emplace_back(
pin );
1200 for(
SCH_ITEM* item : sheet.LastScreen()->Items() )
1209 addOther(
pin->GetPosition(),
pin );
1214 for(
const VECTOR2I& pt : item->GetConnectionPoints() )
1215 addOther( pt, item );
1219 for(
const std::pair<
const VECTOR2I, std::vector<SCH_ITEM*>>& pair : pinMap )
1221 if( pair.second.size() > 1 )
1225 for(
SCH_ITEM* item : pair.second )
1249 ercItem->SetItems( pair.second[0], pair.second[1],
1250 pair.second.size() > 2 ? pair.second[2] :
nullptr,
1251 pair.second.size() > 3 ? pair.second[3] :
nullptr );
1252 ercItem->SetErrorMessage(
_(
"Pin with 'no connection' type is connected" ) );
1253 ercItem->SetSheetSpecificPath( sheet );
1256 sheet.LastScreen()->Append( marker );
1268 std::set<wxString> powerDrivenNets;
1270 if( !
m_schematic->ConnectionGraph()->GetCommittedNetChains().empty() )
1272 for(
const auto& [key, subgraphs] :
m_nets )
1276 for(
SCH_ITEM* item : subgraph->GetItems() )
1284 powerDrivenNets.insert( key.Name );
1293 std::unordered_map<wxString, std::vector<ERC_SCH_PIN_CONTEXT>> netToPins;
1297 using iterator_t = std::vector<ERC_SCH_PIN_CONTEXT>::iterator;
1298 std::vector<ERC_SCH_PIN_CONTEXT> pins;
1299 std::unordered_map<EDA_ITEM*, SCH_SCREEN*> pinToScreenMap;
1300 bool has_noconnect =
false;
1305 has_noconnect =
true;
1311 pins.emplace_back(
static_cast<SCH_PIN*
>( item ), subgraph->
GetSheet() );
1312 netToPins[ net.first.Name ].emplace_back(
static_cast<SCH_PIN*
>( item ), subgraph->
GetSheet() );
1318 std::sort( pins.begin(), pins.end(),
1321 int ret = StrNumCmp( lhs.Pin()->GetParentSymbol()->GetRef( &lhs.Sheet() ),
1322 rhs.Pin()->GetParentSymbol()->GetRef( &rhs.Sheet() ) );
1325 ret = StrNumCmp( lhs.Pin()->GetNumber(), rhs.Pin()->GetNumber() );
1327 return ret != 0 ? ret < 0 : lhs < rhs;
1332 bool hasDriver =
false;
1333 std::vector<ERC_SCH_PIN_CONTEXT*> pinsNeedingDrivers;
1334 std::vector<ERC_SCH_PIN_CONTEXT*> nonPowerPinsNeedingDrivers;
1335 std::vector<ERC_SCH_PIN_CONTEXT*> powerInPinsNeedingDrivers;
1340 bool ispowerNet =
false;
1351 std::vector<std::tuple<iterator_t, iterator_t, PIN_ERROR>> pin_mismatches;
1352 std::map<iterator_t, int> pin_mismatch_counts;
1354 for(
auto refIt = pins.begin(); refIt != pins.end(); ++refIt )
1364 pinsNeedingDrivers.push_back( &refPin );
1367 nonPowerPinsNeedingDrivers.push_back( &refPin );
1370 powerInPinsNeedingDrivers.push_back( &refPin );
1372 if( !needsDriver.
Pin()
1377 needsDriver = refPin;
1378 needsDriverType = needsDriver.
Pin()->
GetType();
1387 for(
auto testIt = refIt + 1; testIt != pins.end(); ++testIt )
1411 pin_mismatches.emplace_back( std::tuple<iterator_t, iterator_t, PIN_ERROR>{ refIt, testIt,
erc } );
1415 pin_mismatch_counts[refIt] =
m_settings.GetPinTypeWeight( ( *refIt ).Pin()->GetType() );
1416 pin_mismatch_counts[testIt] =
m_settings.GetPinTypeWeight( ( *testIt ).Pin()->GetType() );
1420 if( !pin_mismatch_counts.contains( testIt ) )
1421 pin_mismatch_counts.emplace( testIt, 1 );
1423 pin_mismatch_counts[testIt]++;
1425 if( !pin_mismatch_counts.contains( refIt ) )
1426 pin_mismatch_counts.emplace( refIt, 1 );
1428 pin_mismatch_counts[refIt]++;
1434 std::multimap<size_t, iterator_t, std::greater<size_t>> pins_dsc;
1436 std::transform( pin_mismatch_counts.begin(), pin_mismatch_counts.end(),
1437 std::inserter( pins_dsc, pins_dsc.begin() ),
1440 return std::pair<size_t, iterator_t>( p.second, p.first );
1443 for(
const auto& [amount, pinItBind] : pins_dsc )
1445 auto& pinIt = pinItBind;
1447 if( pin_mismatches.empty() )
1453 iterator_t nearest_pin = pins.end();
1454 double smallest_distance = std::numeric_limits<double>::infinity();
1459 [&](
const auto& tuple )
1463 if( pinIt == std::get<0>( tuple ) )
1464 other = std::get<1>( tuple );
1465 else if( pinIt == std::get<1>( tuple ) )
1466 other = std::get<0>( tuple );
1470 if( ( *pinIt ).Sheet().Cmp( ( *other ).Sheet() ) != 0 )
1472 if( std::isinf( smallest_distance ) )
1474 nearest_pin = other;
1475 erc = std::get<2>( tuple );
1482 if( std::isinf( smallest_distance ) ||
distance < smallest_distance )
1485 nearest_pin = other;
1486 erc = std::get<2>( tuple );
1493 if( nearest_pin != pins.end() )
1495 SCH_PIN* other_pin = ( *nearest_pin ).Pin();
1499 ercItem->SetItems(
pin, other_pin );
1500 ercItem->SetSheetSpecificPath( ( *pinIt ).Sheet() );
1501 ercItem->SetItemsSheetPaths( ( *pinIt ).Sheet(), ( *nearest_pin ).Sheet() );
1503 ercItem->SetErrorMessage( wxString::Format(
_(
"Pins of type %s and %s are connected" ),
1508 pinToScreenMap[
pin]->Append( marker );
1513 if( needsDriver.
Pin() && !hasDriver && !has_noconnect )
1521 bool suppressForNetChainDriver =
false;
1525 const wxString& thisNetName = net.first.Name;
1526 const auto& netChains =
m_schematic->ConnectionGraph()->GetCommittedNetChains();
1528 for(
const auto& sig : netChains )
1533 const auto& sigNets = sig->GetNets();
1534 bool containsThisNet = std::find( sigNets.begin(), sigNets.end(), thisNetName ) != sigNets.end();
1536 if( !containsThisNet )
1540 for(
const wxString& otherNet : sigNets )
1542 if( otherNet == thisNetName )
1545 if( powerDrivenNets.contains( otherNet ) )
1547 suppressForNetChainDriver =
true;
1556 if( !suppressForNetChainDriver &&
m_settings.IsTestEnabled( err_code ) )
1558 std::vector<ERC_SCH_PIN_CONTEXT*> pinsToMark;
1567 if( ispowerNet && !powerInPinsNeedingDrivers.empty() )
1568 pinsToMark = powerInPinsNeedingDrivers;
1569 else if( !nonPowerPinsNeedingDrivers.empty() )
1570 pinsToMark = nonPowerPinsNeedingDrivers;
1572 pinsToMark = pinsNeedingDrivers;
1576 if( ispowerNet && !powerInPinsNeedingDrivers.empty() )
1577 pinsToMark.push_back( powerInPinsNeedingDrivers.front() );
1579 pinsToMark.push_back( &needsDriver );
1586 ercItem->SetItems( pinCtx->Pin() );
1587 ercItem->SetSheetSpecificPath( pinCtx->Sheet() );
1588 ercItem->SetItemsSheetPaths( pinCtx->Sheet() );
1591 pinToScreenMap[pinCtx->Pin()]->Append( marker );
1606 auto& netChains =
m_schematic->ConnectionGraph()->GetCommittedNetChains();
1607 wxLogTrace(
traceSchNetChain,
"ERC TestPinToPin: cross-chain phase start chains=%zu",
1610 for(
const auto& sig : netChains )
1615 const wxString chainName = sig->GetName();
1616 const auto& sigNets = sig->GetNets();
1622 const wxString* net;
1624 std::vector<CHAIN_PIN> netChainPins;
1625 netChainPins.reserve( sigNets.size() * 4 );
1627 for(
const wxString& n : sigNets )
1629 auto it = netToPins.find( n );
1630 if( it != netToPins.end() )
1633 netChainPins.push_back( { context, &it->first } );
1637 if( netChainPins.size() < 2 )
1641 "ERC TestPinToPin: chain '%s' nets=%zu collectedPins=%zu",
1642 TO_UTF8( chainName ), sigNets.size(), netChainPins.size() );
1645 std::sort( netChainPins.begin(), netChainPins.end(),
1646 [](
const CHAIN_PIN&
left,
const CHAIN_PIN&
right )
1648 const auto& lhs = left.context;
1649 const auto& rhs = right.context;
1650 int ret = StrNumCmp( lhs.Pin()->GetParentSymbol()->GetRef( &lhs.Sheet() ),
1651 rhs.Pin()->GetParentSymbol()->GetRef( &rhs.Sheet() ) );
1653 ret = StrNumCmp( lhs.Pin()->GetNumber(), rhs.Pin()->GetNumber() );
1654 return ret != 0 ? ret < 0 : lhs < rhs;
1657 for(
size_t i = 0; i < netChainPins.size(); ++i )
1659 const auto& aContext = netChainPins[i].context;
1660 SCH_PIN* aPin = aContext.Pin();
1662 const wxString& aNet = *netChainPins[i].net;
1664 for(
size_t j = i + 1; j < netChainPins.size(); ++j )
1666 const auto& bContext = netChainPins[j].context;
1667 SCH_PIN* bPin = bContext.Pin();
1668 const wxString& bNet = *netChainPins[j].net;
1683 ercItem->SetItems( aPin, bPin );
1684 ercItem->SetSheetSpecificPath( aContext.Sheet() );
1685 ercItem->SetItemsSheetPaths( aContext.Sheet(), bContext.Sheet() );
1686 ercItem->SetErrorMessage( wxString::Format(
1687 _(
"Pins of type %s and %s are connected via net chain %s" ),
1692 aContext.Sheet().LastScreen()->Append( marker );
1715 std::unordered_map<wxString, std::vector<PIN_ON_NET>> pinToNetMap;
1719 const wxString& netName = net.first.Name;
1730 if( !
pin->GetParentSymbol()->IsMultiUnit() )
1733 wxString
name =
pin->GetParentSymbol()->GetRef( &sheet ) +
":"
1734 +
pin->GetShownNumber();
1736 pinToNetMap[
name].push_back( { netName,
pin, sheet } );
1743 std::vector<wxString> conflicted;
1745 for(
const auto& [
name, pins] : pinToNetMap )
1747 for(
const PIN_ON_NET& candidate : pins )
1749 if( candidate.m_netName != pins.front().m_netName )
1751 conflicted.push_back(
name );
1757 std::sort( conflicted.begin(), conflicted.end() );
1759 for(
const wxString&
name : conflicted )
1761 std::vector<PIN_ON_NET> pins = pinToNetMap[
name];
1763 std::sort( pins.begin(), pins.end(),
1764 [](
const PIN_ON_NET& a,
const PIN_ON_NET& b )
1766 if( a.m_netName != b.m_netName )
1767 return a.m_netName < b.m_netName;
1769 return a.m_pin->m_Uuid < b.m_pin->m_Uuid;
1772 const PIN_ON_NET& first = pins.front();
1774 for(
const PIN_ON_NET& other : pins )
1776 if( other.m_netName == first.m_netName )
1781 ercItem->SetErrorMessage( wxString::Format(
_(
"Pin %s is connected to both %s and %s" ),
1782 other.m_pin->GetShownNumber(),
1784 first.m_netName ) );
1786 ercItem->SetItems( other.m_pin, first.m_pin );
1787 ercItem->SetSheetSpecificPath( other.m_sheet );
1788 ercItem->SetItemsSheetPaths( other.m_sheet, first.m_sheet );
1791 other.m_sheet.LastScreen()->Append( marker );
1820 std::vector<SCH_PIN*> pins = symbol->
GetPins( &sheet );
1822 std::map<wxString, std::vector<std::pair<SCH_PIN*, wxString>>> pinsByNumber;
1827 wxString netName = conn ? conn->
GetNetName() : wxString();
1829 pinsByNumber[
pin->GetNumber()].emplace_back(
pin, netName );
1832 for(
const auto& [pinNumber, pinNetPairs] : pinsByNumber )
1834 if( pinNetPairs.size() < 2 )
1837 wxString firstNet = pinNetPairs[0].second;
1838 bool hasDifferentNets =
false;
1839 SCH_PIN* conflictPin =
nullptr;
1841 for(
size_t i = 1; i < pinNetPairs.size(); i++ )
1843 if( pinNetPairs[i].second != firstNet )
1845 hasDifferentNets =
true;
1846 conflictPin = pinNetPairs[i].first;
1851 if( hasDifferentNets )
1856 msg.Printf(
_(
"Pin %s on symbol '%s' is connected to different nets: %s and %s" ),
1858 symbol->
GetRef( &sheet ),
1859 firstNet.IsEmpty() ?
_(
"<no net>" ) : firstNet,
1860 pinNetPairs[1].second.IsEmpty() ?
_(
"<no net>" ) : pinNetPairs[1].second );
1862 ercItem->SetErrorMessage( msg );
1863 ercItem->SetItems( pinNetPairs[0].first, conflictPin );
1864 ercItem->SetSheetSpecificPath( sheet );
1865 ercItem->SetItemsSheetPaths( sheet, sheet );
1868 pinNetPairs[0].first->GetPosition() );
1869 screen->
Append( marker );
1885 [](
const wxString& txt )
1887 wxString upper = txt.Upper();
1889 return upper.Contains( wxT(
"GND" ) )
1890 || upper == wxT(
"EARTH" ) || upper.StartsWith( wxT(
"EARTH_" ) )
1891 || upper == wxT(
"VSS" ) || upper == wxT(
"VSSA" );
1901 bool hasGroundNet =
false;
1902 std::vector<SCH_PIN*> mismatched;
1914 const wxString net = conn ? conn->
Name(
true ) : wxString();
1915 const bool netIsGround = isGround( net );
1918 hasGroundNet =
true;
1920 if( isGround(
pin->GetShownName() ) && !netIsGround )
1921 mismatched.push_back(
pin );
1930 ercItem->SetErrorMessage( wxString::Format(
_(
"Pin %s not connected to ground net" ),
1931 pin->GetShownName() ) );
1932 ercItem->SetItems(
pin );
1933 ercItem->SetSheetSpecificPath( sheet );
1934 ercItem->SetItemsSheetPaths( sheet );
1937 screen->
Append( marker );
1963 pin->GetStackedPinNumbers( &valid );
1968 ercItem->SetItems(
pin );
1969 ercItem->SetSheetSpecificPath( sheet );
1970 ercItem->SetItemsSheetPaths( sheet );
1973 screen->
Append( marker );
1988 std::unordered_map<wxString, std::pair<SCH_ITEM*, SCH_SHEET_PATH>> globalLabels;
1989 std::unordered_map<wxString, std::pair<SCH_ITEM*, SCH_SHEET_PATH>> localLabels;
2004 auto& map = item->Type() ==
SCH_LABEL_T ? localLabels : globalLabels;
2005 auto it = map.find(
text );
2008 if( ( it == map.end() ) || ( label->
m_Uuid < it->second.first->m_Uuid ) )
2009 map[
text] = std::make_pair( label, sheet );
2015 if( !
pin->IsPower() )
2024 ?
pin->GetShownName()
2027 auto& map =
pin->IsGlobalPower() ? globalLabels : localLabels;
2028 auto it = map.find(
text );
2031 if( ( it == map.end() ) || (
pin->m_Uuid < it->second.first->m_Uuid ) )
2032 map[
text] = std::make_pair(
pin, sheet );
2038 for(
auto& [globalText, globalItem] : globalLabels )
2040 for(
auto& [localText, localItem] : localLabels )
2042 if( globalText == localText )
2052 ercItem->SetItems( globalItem.first, localItem.first );
2053 ercItem->SetSheetSpecificPath( globalItem.second );
2054 ercItem->SetItemsSheetPaths( globalItem.second, localItem.second );
2057 globalItem.second.LastScreen()->Append( marker );
2072 struct SIMILAR_ENTRY
2079 std::unordered_map<wxString, std::vector<SIMILAR_ENTRY>> generalMap;
2081 auto normalizeLabel =
2082 [](
const wxString& aLabel )
2084 wxString stripped = aLabel.Strip( wxString::leading ).Strip( wxString::trailing );
2091 if( prefix == wxT(
"+" ) )
2092 prefix = wxEmptyString;
2095 units.Replace( wxS(
"µ" ),
'u' );
2096 units.Replace( wxS(
"μ" ),
'u' );
2098 return prefix.Lower() + value.Lower() + units.Lower();
2111 switch( item->Type() )
2120 generalMap[normalizeLabel( unnormalized )].push_back( { unnormalized, label, sheet } );
2127 if( !
pin->IsPower() )
2133 generalMap[normalizeLabel( unnormalized )].push_back( { unnormalized,
pin, sheet } );
2145 [&](
const SIMILAR_ENTRY& aMain,
const SIMILAR_ENTRY& aAux )
2157 ercItem->SetItems( aMain.m_item, aAux.m_item );
2158 ercItem->SetSheetSpecificPath( aMain.m_sheet );
2159 ercItem->SetItemsSheetPaths( aMain.m_sheet, aAux.m_sheet );
2162 aMain.m_sheet.LastScreen()->Append( marker );
2167 std::vector<wxString> keys;
2168 keys.reserve( generalMap.size() );
2170 for(
const auto& [key, entries] : generalMap )
2171 keys.push_back( key );
2173 std::sort( keys.begin(), keys.end() );
2175 for(
const wxString& key : keys )
2177 std::vector<SIMILAR_ENTRY> entries = generalMap[key];
2179 std::sort( entries.begin(), entries.end(),
2180 [](
const SIMILAR_ENTRY& a,
const SIMILAR_ENTRY& b )
2182 wxString pathA = a.m_sheet.Path().AsString();
2183 wxString pathB = b.m_sheet.Path().AsString();
2185 if( pathA != pathB )
2186 return pathA < pathB;
2188 return a.m_item->m_Uuid < b.m_item->m_Uuid;
2192 for(
size_t ii = 0; ii < entries.size(); ++ii )
2194 for(
size_t jj = ii + 1; jj < entries.size(); ++jj )
2196 const SIMILAR_ENTRY& a = entries[ii];
2197 const SIMILAR_ENTRY& b = entries[jj];
2199 if( a.m_text == b.m_text )
2205 && a.m_sheet != b.m_sheet )
2231 std::vector<SCH_MARKER*> markers;
2238 if( !libSymbolInSchematic )
2245 if( !optRow || ( *optRow )->Disabled() )
2250 ercItem->SetItems( symbol );
2251 msg.Printf(
_(
"The current configuration does not include the symbol library '%s'" ),
2253 ercItem->SetErrorMessage( msg );
2266 wxCHECK2( uri.has_value(), uri = wxEmptyString );
2267 ercItem->SetItems( symbol );
2268 msg.Printf(
_(
"The symbol library '%s' was not found at '%s'" ),
2271 ercItem->SetErrorMessage( msg );
2282 if( libSymbol ==
nullptr )
2287 ercItem->SetItems( symbol );
2288 msg.Printf(
_(
"Symbol '%s' not found in symbol library '%s'" ),
2291 ercItem->SetErrorMessage( msg );
2299 std::unique_ptr<LIB_SYMBOL> flattenedSymbol = libSymbol->
Flatten();
2300 int flags =
m_schematic->Settings().SymbolCompareFlags();
2308 std::vector<wxString> messages;
2316 if( messages.empty() && flattenedSymbol->Compare( *libSymbolInSchematic, flags ) != 0 )
2319 ercItem->SetItems( symbol );
2320 msg.Printf(
_(
"Symbol '%s' doesn't match copy in library '%s'" ),
2323 ercItem->SetErrorMessage( msg );
2332 screen->Append( marker );
2345 if( std::optional<LIBRARY_MANAGER_ADAPTER*> adapter =
2348 ( *adapter )->BlockUntilLoaded();
2354 typedef int (*TESTER_FN_PTR)(
const wxString&,
PROJECT* );
2360 std::vector<SCH_MARKER*> markers;
2367 if( footprint.IsEmpty() )
2372 if( fpID.
Parse( footprint,
true ) >= 0 )
2375 msg.Printf(
_(
"'%s' is not a valid footprint identifier" ), footprint );
2376 ercItem->SetErrorMessage( msg );
2377 ercItem->SetItems( symbol );
2384 int ret = (linkTester)( footprint, aProject );
2389 msg.Printf(
_(
"The current configuration does not include the footprint library '%s'" ),
2391 ercItem->SetErrorMessage( msg );
2392 ercItem->SetItems( symbol );
2398 msg.Printf(
_(
"The footprint library '%s' is not enabled in the current configuration" ),
2400 ercItem->SetErrorMessage( msg );
2401 ercItem->SetItems( symbol );
2407 msg.Printf(
_(
"Footprint '%s' not found in library '%s'" ),
2410 ercItem->SetErrorMessage( msg );
2411 ercItem->SetItems( symbol );
2418 sheet.LastScreen()->Append( marker );
2436 std::vector<SCH_MARKER*> markers;
2441 std::unique_ptr<LIB_SYMBOL>& lib_symbol = sch_symbol->
GetLibSymbolRef();
2446 wxArrayString filters = lib_symbol->GetFPFilters();
2448 if( filters.empty() )
2454 if( footprint.
Parse( lowerId ) > 0 )
2460 for( wxString
filter : filters )
2465 if(
filter.Contains( wxS(
":" ) ) )
2466 found |= lowerId.Matches(
filter );
2468 found |= lowerItemName.Matches(
filter );
2477 msg.Printf(
_(
"Assigned footprint (%s) doesn't match footprint filters (%s)" ),
2479 wxJoin( filters,
' ' ) );
2480 ercItem->SetErrorMessage( msg );
2481 ercItem->SetItems( sch_symbol );
2488 sheet.LastScreen()->Append( marker );
2499 const int gridSize =
m_schematic->Settings().m_ConnectionGridSize;
2504 std::vector<SCH_MARKER*> markers;
2506 for(
SCH_ITEM* item : screen->Items() )
2508 if( item->Type() ==
SCH_LINE_T && item->IsConnectable() )
2516 ercItem->SetItems( line );
2524 ercItem->SetItems( line );
2535 if( ( point.x % gridSize ) != 0
2536 || ( point.y % gridSize ) != 0 )
2539 ercItem->SetItems( entry );
2541 markers.emplace_back(
new SCH_MARKER( std::move( ercItem ), point ) );
2556 if( ( pinPos.
x % gridSize ) != 0 || ( pinPos.
y % gridSize ) != 0 )
2559 ercItem->SetItems(
pin );
2561 markers.emplace_back(
new SCH_MARKER( std::move( ercItem ), pinPos ) );
2570 screen->Append( marker );
2584 wxString variant =
m_schematic->GetCurrentVariant();
2588 if( sheet.GetExcludedFromSim( variant ) )
2591 std::vector<SCH_MARKER*> markers;
2609 wxString msg =
reporter.GetMessages();
2615 ercItem->SetErrorMessage( msg );
2616 ercItem->SetItems( symbol );
2624 sheet.LastScreen()->Append( marker );
2645 std::map<wxString, std::unique_ptr<LIB_SYMBOL>> flatAltCache;
2654 std::vector<SCH_MARKER*> markers;
2661 if( !symbol->
GetInstance( instance, sheet.Path() ) )
2665 [&](
int aErrorCode,
const wxString& aMessage )
2669 ercItem->SetItems( symbol );
2670 ercItem->SetSheetSpecificPath( sheet );
2671 ercItem->SetErrorMessage( aMessage );
2673 markers.emplace_back(
2678 for(
const auto& [variantName, variant] : instance.
m_Variants )
2680 if( !variant.m_SymbolOverride )
2683 const LIB_ID& libId = *variant.m_SymbolOverride;
2684 wxString libIdStr = libId.
Format();
2690 auto cacheIt = flatAltCache.find( libIdStr );
2692 if( cacheIt == flatAltCache.end() )
2694 std::unique_ptr<LIB_SYMBOL> flatAlt;
2699 flatAlt = altSymbol->Flatten();
2705 cacheIt = flatAltCache.emplace( libIdStr, std::move( flatAlt ) ).first;
2708 const LIB_SYMBOL* flatAlt = cacheIt->second.get();
2715 wxString::Format(
_(
"Variant '%s': symbol '%s' not found in libraries" ),
2716 variantName, libIdStr ) );
2731 std::vector<VARIANT_COMPAT_RESULT> issues =
2737 wxString::Format(
_(
"Variant '%s', alternate '%s': %s" ),
2738 variantName, libIdStr, issue.detail ) );
2744 screen->
Append( marker );
2760 if( aProgressReporter )
2761 aProgressReporter->
AdvancePhase(
_(
"Checking sheet names..." ) );
2770 if( aProgressReporter )
2771 aProgressReporter->
AdvancePhase(
_(
"Checking pin maps..." ) );
2777 if( aProgressReporter )
2778 aProgressReporter->
AdvancePhase(
_(
"Checking conflicts..." ) );
2791 if( aProgressReporter )
2792 aProgressReporter->
AdvancePhase(
_(
"Checking units..." ) );
2797 if( aProgressReporter )
2798 aProgressReporter->
AdvancePhase(
_(
"Checking footprints..." ) );
2811 if( aProgressReporter )
2841 if( aProgressReporter )
2842 aProgressReporter->
AdvancePhase(
_(
"Checking similar labels..." ) );
2850 if( aProgressReporter )
2851 aProgressReporter->
AdvancePhase(
_(
"Checking local and global labels..." ) );
2858 if( aProgressReporter )
2859 aProgressReporter->
AdvancePhase(
_(
"Checking for unresolved variables..." ) );
2866 if( aProgressReporter )
2867 aProgressReporter->
AdvancePhase(
_(
"Checking field names..." ) );
2874 if( aProgressReporter )
2875 aProgressReporter->
AdvancePhase(
_(
"Checking for empty label names..." ) );
2882 if( aProgressReporter )
2883 aProgressReporter->
AdvancePhase(
_(
"Checking SPICE models..." ) );
2890 if( aProgressReporter )
2891 aProgressReporter->
AdvancePhase(
_(
"Checking no connect pins for connections..." ) );
2899 if( aProgressReporter )
2900 aProgressReporter->
AdvancePhase(
_(
"Checking for library symbol issues..." ) );
2907 if( aProgressReporter )
2908 aProgressReporter->
AdvancePhase(
_(
"Checking for footprint link issues..." ) );
2915 if( aProgressReporter )
2916 aProgressReporter->
AdvancePhase(
_(
"Checking footprint assignments against footprint filters..." ) );
2923 if( aProgressReporter )
2924 aProgressReporter->
AdvancePhase(
_(
"Checking for off grid pins and wires..." ) );
2931 if( aProgressReporter )
2932 aProgressReporter->
AdvancePhase(
_(
"Checking for four way junctions..." ) );
2939 if( aProgressReporter )
2940 aProgressReporter->
AdvancePhase(
_(
"Checking for labels on more than one wire..." ) );
2947 if( aProgressReporter )
2948 aProgressReporter->
AdvancePhase(
_(
"Checking for undefined netclasses..." ) );
2956 if( aProgressReporter )
2957 aProgressReporter->
AdvancePhase(
_(
"Checking variant symbols..." ) );
constexpr EDA_IU_SCALE schIUScale
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
constexpr Vec Centre() const
A subgraph is a set of items that are electrically connected on a single sheet.
const std::set< SCH_ITEM * > & GetItems() const
Provide a read-only reference to the items in the subgraph.
const SCH_ITEM * GetNoConnect() const
const SCH_SHEET_PATH & GetSheet() const
Base class to handle basic graphic items.
Store the list of graphic items: rect, lines, polygons and texts to draw/plot the title block and fra...
DS_DRAW_ITEM_BASE * GetFirst()
void BuildDrawItemsList(const PAGE_INFO &aPageInfo, const TITLE_BLOCK &aTitleBlock)
Drawing or plot the drawing sheet.
void SetFileName(const wxString &aFileName)
Set the filename to draw/plot.
void SetSheetName(const wxString &aSheetName)
Set the sheet name to draw/plot.
void SetSheetLayer(const wxString &aSheetLayer)
Set the sheet layer to draw/plot.
void SetSheetCount(int aSheetCount)
Set the value of the count of sheets, for basic inscriptions.
void SetPageNumber(const wxString &aPageNumber)
Set the value of the sheet number.
DS_DRAW_ITEM_BASE * GetNext()
void SetProject(const PROJECT *aProject)
const PAGE_INFO & GetPageInfo()
const TITLE_BLOCK & GetTitleBlock()
virtual VECTOR2I GetPosition() const
KICAD_T Type() const
Returns the type of object.
virtual const wxString & GetText() const
Return the string associated with the text object.
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.
A class used to associate a SCH_PIN with its owning SCH_SHEET_PATH, in order to handle ERC checks acr...
const SCH_SHEET_PATH & Sheet() const
Get the SCH_SHEET_PATH context for the paired SCH_PIN.
SCH_PIN * Pin() const
Get the SCH_PIN for this context.
int TestLibSymbolIssues()
Test symbols for changed library symbols and broken symbol library links.
int TestStackedPinNotation()
Checks for pin numbers that resemble stacked pin notation but are invalid.
void TestTextVars(DS_PROXY_VIEW_ITEM *aDrawingSheet)
Check for any unresolved text variable references.
int TestPinToPin()
Checks the full netlist against the pin-to-pin connectivity requirements.
int TestSimilarLabels()
Checks for labels that differ only in capitalization.
SCH_MULTI_UNIT_REFERENCE_MAP m_refMap
int TestEmptyLabelNames()
Check for labels with empty or whitespace-only names.
int TestFootprintLinkIssues(KIFACE *aCvPcb, PROJECT *aProject)
Test footprint links against the current footprint libraries.
int TestOffGridEndpoints()
Test pins and wire ends for being off grid.
int TestDuplicateSheetNames(bool aCreateMarker)
Inside a given sheet, one cannot have sheets with duplicate names (file names can be duplicated).
int TestSameLocalGlobalLabel()
Checks for global and local labels with the same name.
int TestMultUnitPinConflicts()
Checks if shared pins on multi-unit symbols have been connected to different nets.
int TestNoConnectPins()
In KiCad 5 and earlier, you could connect stuff up to pins with NC electrical type.
int TestFootprintFilters()
Test symbols to ensure that assigned footprint passes any given footprint filters.
int TestPinMap(KIFACE *aCvPcb, PROJECT *aProject)
Check pin-to-pad maps (issue #2282): stale pin references, duplicate pad targets, bad pads and unmapp...
int TestFieldNameWhitespace()
Check for field names with leading or trailing whitespace.
int TestDuplicatePinNets()
Checks if duplicate pin numbers within a symbol are connected to different nets.
ERC_SETTINGS & m_settings
int TestFourWayJunction()
Test to see if there are potentially confusing 4-way junctions in the schematic.
int TestMissingNetclasses()
Tests for netclasses that are referenced but not defined.
int TestSimModelIssues()
Test SPICE models for various issues.
SCH_SHEET_LIST m_sheetList
int TestGroundPins()
Checks for ground-labeled pins not on a ground net while another pin is.
void RunTests(DS_PROXY_VIEW_ITEM *aDrawingSheet, SCH_EDIT_FRAME *aEditFrame, KIFACE *aCvPcb, PROJECT *aProject, PROGRESS_REPORTER *aProgressReporter)
int TestMissingUnits()
Test for uninstantiated units of multi unit symbols.
int TestLabelMultipleWires()
Test to see if there are labels that are connected to more than one wire.
int TestVariantSymbols()
Test all variant symbol overrides for resolution and pin compatibility.
int TestMultiunitFootprints()
Test if all units of each multiunit symbol have the same footprint assigned.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
bool IsLibraryLoaded(const wxString &aNickname)
std::optional< wxString > GetFullURI(LIBRARY_TABLE_TYPE aType, const wxString &aNickname, bool aSubstituted=false)
Return the full location specifying URI for the LIB, either in original UI form or in environment var...
std::optional< LIBRARY_TABLE_ROW * > GetRow(LIBRARY_TABLE_TYPE aType, const wxString &aNickname, LIBRARY_TABLE_SCOPE aScope=LIBRARY_TABLE_SCOPE::BOTH)
A logical library item identifier and consists of various portions much like a URI.
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
wxString GetUniStringLibId() const
const wxString GetUniStringLibItemName() const
Get strings for display messages in dialogs.
const UTF8 & GetLibItemName() const
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Define a library symbol object.
std::vector< const SCH_PIN * > GetGraphicalPins(int aUnit=0, int aBodyStyle=0) const
Graphical pins: Return schematic pin objects as drawn (unexpanded), filtered by unit/body.
const std::vector< ASSOCIATED_FOOTPRINT > & GetEffectiveAssociatedFootprints() const
std::vector< SCH_PIN * > GetPins() const override
const PIN_MAP_SET & GetEffectivePinMaps() const
void RunOnChildren(const std::function< void(SCH_ITEM *)> &aFunction, RECURSE_MODE aMode) override
int GetUnitCount() const override
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
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.
wxString GetUnitDisplayName(int aUnit, bool aLabel) const override
Return the user-defined display name for aUnit for symbols with units.
virtual LIBRARY_MANAGER & GetLibraryManager() const
A symbol-owned ordered set of named pin maps.
const std::vector< PIN_MAP > & GetAll() const
const PIN_MAP * FindByName(const wxString &aName) const
const std::vector< PIN_MAP_ENTRY > & GetEntries() const
const wxString & GetName() const
A progress reporter interface for use in multi-threaded environments.
virtual void AdvancePhase()=0
Use the next available virtual zone of the dialog progress bar.
static SYMBOL_LIBRARY_ADAPTER * SymbolLibAdapter(PROJECT *aProject)
Accessor for project symbol library manager adapter.
Container for project specific data.
std::vector< VECTOR2I > GetConnectionPoints() const override
Add all the connection points for this item to aPoints.
Class for a wire to bus entry.
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
wxString GetNetName() const
wxString Name(bool aIgnoreSheet=false) const
Schematic editor (Eeschema) main window.
void RecalculateConnections(SCH_COMMIT *aCommit, SCH_CLEANUP_FLAGS aCleanupFlags, PROGRESS_REPORTER *aProgressReporter=nullptr, bool aCleanupDone=false)
Generate the connection data for the entire schematic hierarchy.
wxString GetUntranslatedName() const
Get the untranslated field name for storage, variable look-up, etc.
wxString GetShownText(const SCH_SHEET_PATH *aPath, RESOLUTION_CONTEXT aContext, const wxString &aVariantName=wxEmptyString, int aDepth=0) const
Base class for any item which can be embedded within the SCHEMATIC container class,...
bool ResolveExcludedFromSim(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const
std::vector< VECTOR2I > GetConnectionPoints() const override
Add all the connection points for this item to aPoints.
wxString GetShownText(const SCH_SHEET_PATH *aPath, RESOLUTION_CONTEXT aContext, int aDepth=0) const override
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.
VECTOR2I GetEndPoint() const
VECTOR2I GetStartPoint() const
bool IsEndPoint(const VECTOR2I &aPoint) const override
Test if aPt is an end point of this schematic object.
bool IsGraphicLine() const
Return if the line is a graphic (non electrical line)
PAD_RESOLUTION
Outcome of pin-to-pad resolution (issue #2282).
VECTOR2I GetPosition() const override
bool IsStacked(const SCH_PIN *aPin) const
bool IsPower() const
Check if the pin is either a global or local power pin.
ELECTRICAL_PINTYPE GetType() const
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
SCH_REFERENCE & GetItem(size_t aIdx)
A helper to define a symbol's reference designator in a schematic.
const SCH_SHEET_PATH & GetSheetPath() const
const wxString GetFootprint() const
SCH_SYMBOL * GetSymbol() const
LIB_SYMBOL * GetLibPart() const
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
EE_RTREE & Items()
Get the full RTree, usually for iterating.
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
VECTOR2I GetPosition() const override
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
SCH_SCREEN * LastScreen()
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
std::vector< SCH_FIELD > & GetFields()
Return a reference to the vector holding the sheet's fields.
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this sheet.
VECTOR2I GetPosition() const override
std::vector< SCH_SHEET_PIN * > & GetPins()
const wxString GetFootprintFieldText(const SCH_SHEET_PATH *aPath, RESOLUTION_CONTEXT aContext, const wxString &aVariantName=wxEmptyString) const
std::vector< const SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet) const
Retrieve a list of the SCH_PINs for the given sheet path.
bool IsGlobalPower() const override
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly) const override
Populate a std::vector with SCH_FIELDs, sorted in ordinal order.
VECTOR2I GetPosition() const override
const LIB_ID & GetLibId() const override
bool GetInstance(SCH_SYMBOL_INSTANCE &aInstance, const KIID_PATH &aSheetPath, bool aTestFromEnd=false) const
const wxString GetValue(const SCH_SHEET_PATH *aPath, RESOLUTION_CONTEXT aContext, const wxString &aVariantName=wxEmptyString) const override
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const override
virtual wxString GetShownText(const RENDER_SETTINGS *aSettings, const SCH_SHEET_PATH *aPath, RESOLUTION_CONTEXT aContext, int aDepth=0) const
VECTOR2I GetPosition() const override
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
virtual wxString GetShownText(const SCH_SHEET_PATH *aPath, RESOLUTION_CONTEXT aContext, int aDepth=0) const
SIM_MODEL & CreateModel(SIM_MODEL::TYPE aType, std::span< const wxString > aPins, REPORTER &aReporter)
An interface to the global shared library manager that is schematic-specific and linked to one projec...
LIB_SYMBOL * LoadSymbol(const wxString &aNickname, const wxString &aName)
Load a LIB_SYMBOL having aName from the library given by aNickname.
const TRANSFORM & GetTransform() const
double Distance(const VECTOR2< extended_type > &aVector) const
Compute the distance between two vectors.
A wrapper for reporting to a wxString object.
const wxString ExpandEnvVarSubstitutions(const wxString &aString, const PROJECT *aProject)
Replace any environment variable & text variable references with their values.
void CheckDuplicatePins(LIB_SYMBOL *aSymbol, std::vector< wxString > &aMessages, UNITS_PROVIDER *aUnitsProvider)
const wxString CommentERC_V[]
const wxString CommentERC_H[]
const std::set< ELECTRICAL_PINTYPE > DrivenPinTypes
const std::set< ELECTRICAL_PINTYPE > DrivingPinTypes
const std::set< ELECTRICAL_PINTYPE > DrivingPowerPinTypes
@ ERCE_POWERPIN_NOT_DRIVEN
Power input pin connected to some others pins but no power out pin to drive it.
@ ERCE_SIMILAR_POWER
2 power pins are equal for case insensitive comparisons.
@ ERCE_MISSING_POWER_INPUT_PIN
Symbol has power input pins that are not placed on the schematic.
@ ERCE_GROUND_PIN_NOT_GROUND
A ground-labeled pin is not on a ground net while another pin is.
@ ERCE_SIMILAR_LABELS
2 labels are equal for case insensitive comparisons.
@ ERCE_VARIANT_SYMBOL_INCOMPATIBLE
Variant symbol override fails pin compatibility.
@ ERCE_STACKED_PIN_SYNTAX
Pin name resembles stacked pin notation.
@ ERCE_ENDPOINT_OFF_GRID
Pin or wire-end off grid.
@ ERCE_EMPTY_LABEL_NAME
Label has an empty or whitespace-only name.
@ ERCE_SAME_LOCAL_GLOBAL_LABEL
2 labels are equal for case insensitive comparisons.
@ ERCE_SIMILAR_LABEL_AND_POWER
label and pin are equal for case insensitive comparisons.
@ ERCE_SAME_LOCAL_GLOBAL_POWER
Local power port and global power port have the same name.
@ ERCE_PIN_MAP_BAD_PAD
Pin map references a pad absent from the footprint.
@ ERCE_FOOTPRINT_LINK_ISSUES
The footprint link is invalid, or points to a missing (or inactive) footprint or library.
@ ERCE_PIN_MAP_DUPLICATE_PAD
Two symbol pins map to one pad (not stacked/jumper).
@ ERCE_DUPLICATE_PIN_ERROR
@ ERCE_DIFFERENT_UNIT_NET
Shared pin in a multi-unit symbol is connected to more than one net.
@ ERCE_FOUR_WAY_JUNCTION
A four-way junction was found.
@ ERCE_UNDEFINED_NETCLASS
A netclass was referenced but not defined.
@ ERCE_UNRESOLVED_VARIABLE
A text variable could not be resolved.
@ ERCE_SIMULATION_MODEL
An error was found in the simulation model.
@ ERCE_LIB_SYMBOL_MISMATCH
Symbol doesn't match copy in library.
@ ERCE_DIFFERENT_UNIT_FP
Different units of the same symbol have different footprints assigned.
@ ERCE_NOCONNECT_CONNECTED
A no connect symbol is connected to more than 1 pin.
@ ERCE_PIN_TO_PIN_WARNING
@ ERCE_PIN_NOT_DRIVEN
Pin connected to some others pins but no pin to drive it.
@ ERCE_MISSING_INPUT_PIN
Symbol has input pins that are not placed.
@ ERCE_MISSING_UNIT
Symbol has units that are not placed on the schematic.
@ ERCE_FIELD_NAME_WHITESPACE
Field name has leading or trailing whitespace.
@ ERCE_DUPLICATE_SHEET_NAME
Duplicate sheet names within a given sheet.
@ ERCE_PIN_MAP_STALE_PIN
Pin map references a pin number not on the symbol.
@ ERCE_MISSING_BIDI_PIN
Symbol has bi-directional pins that are not placed.
@ ERCE_LIB_SYMBOL_ISSUES
Symbol not found in active libraries.
@ ERCE_FOOTPRINT_FILTERS
The assigned footprint doesn't match the footprint filters.
@ ERCE_VARIANT_SYMBOL_INVALID
Variant symbol override LIB_ID cannot be resolved.
@ ERCE_PIN_MAP_UNMAPPED_PIN
A connected pin resolves to no footprint pad.
@ ERCE_LABEL_MULTIPLE_WIRES
A label is connected to more than one wire.
PIN_ERROR
The values a pin-to-pin entry in the pin matrix can take on.
const wxChar *const traceSchNetChain
Flag to enable tracing of schematic net chain rebuild and ERC cross-chain checks.
@ KIFACE_TEST_FOOTPRINT_LINK_LIBRARY_NOT_ENABLED
@ KIFACE_TEST_FOOTPRINT_LINK
@ KIFACE_TEST_FOOTPRINT_LINK_NO_LIBRARY
@ KIFACE_TEST_FOOTPRINT_LINK_NO_FOOTPRINT
@ KIFACE_FOOTPRINT_PAD_NUMBERS
Function pointer type: void (*)( const wxString& aFootprint, PROJECT* aProject, std::set<wxString>& a...
PGM_BASE & Pgm()
The global program "get" accessor.
ELECTRICAL_PINTYPE
The symbol library pin object electrical types used in ERC tests.
@ PT_INPUT
usual pin input: must be connected
@ PT_NC
not connected (must be left open)
@ PT_TRISTATE
tri state bus pin
@ PT_BIDI
input or output (like port for a microprocessor)
@ PT_POWER_OUT
output of a regulator: intended to be connected to power input pins
@ PT_POWER_IN
power input (GND, VCC for ICs). Must be connected to a power output.
@ PT_UNSPECIFIED
unknown electrical properties: creates always a warning when connected
@ PT_PASSIVE
pin for passive symbols: must be connected, and can be connected to any pin.
wxString ElectricalPinTypeGetText(ELECTRICAL_PINTYPE)
static float distance(const SFVEC2UI &a, const SFVEC2UI &b)
static const std::vector< KICAD_T > labelTypes
std::vector< wxString > ExpandStackedPinNotation(const wxString &aPinName, bool *aValid)
Expand stacked pin notation like [1,2,3], [1-4], [A1-A4], or [AA1-AA3,AB4,CD12-CD14] into individual ...
wxString UnescapeString(const wxString &aSource)
int SplitString(const wxString &strToSplit, wxString *strBeginning, wxString *strDigits, wxString *strEnd)
Break a string into three parts: he alphabetic preamble, the numeric part, and any alphabetic ending.
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Implement a participant in the KIWAY alchemy.
virtual void * IfaceOrAddress(int aDataId)=0
Return pointer to the requested object.
One symbol-pin to footprint-pad mapping inside a PIN_MAP.
A simple container for schematic symbol instance information.
std::map< wxString, SCH_SYMBOL_VARIANT > m_Variants
A list of symbol variants.
IbisParser parser & reporter
wxLogTrace helper definitions.
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
std::vector< VARIANT_COMPAT_RESULT > ValidateVariantSymbolCompatibility(const LIB_SYMBOL &aBase, const LIB_SYMBOL &aCandidate)
Check whether aCandidate can be used as a variant symbol override for aBase.
VECTOR2< int32_t > VECTOR2I