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" ),
151 std::vector<SCH_SHEET*> list;
154 list.push_back(
static_cast<SCH_SHEET*
>( item ) );
156 for(
size_t i = 0; i < list.size(); i++ )
160 for(
size_t j = i + 1; j < list.size(); j++ )
172 ercItem->SetItems( sheet, test_item );
175 screen->Append( marker );
195 typedef void ( *PAD_NUMBERS_FN_PTR )(
const wxString&,
PROJECT*, std::set<wxString>& );
197 PAD_NUMBERS_FN_PTR padFetcher =
200 std::map<wxString, std::set<wxString>> padCache;
202 auto getPads = [&](
const wxString& aFootprintId ) ->
const std::set<wxString>&
204 auto it = padCache.find( aFootprintId );
206 if( it != padCache.end() )
209 std::set<wxString>& pads = padCache[aFootprintId];
211 if( padFetcher && !aFootprintId.IsEmpty() )
212 padFetcher( aFootprintId, aProject, pads );
234 std::set<wxString> pinNumbers;
237 pinNumbers.insert(
pin->GetNumber() );
239 const std::vector<std::set<wxString>>& jumperGroups = lib->
JumperPinGroups();
241 auto sharesJumperGroup = [&](
const wxString& aPinA,
const wxString& aPinB )
243 for(
const std::set<wxString>&
group : jumperGroups )
245 if(
group.count( aPinA ) &&
group.count( aPinB ) )
258 if( pinNumbers.count( entry.m_PinNumber ) )
262 ercItem->SetItems( symbol );
263 ercItem->SetErrorMessage(
264 wxString::Format(
_(
"Pin map '%s' references unknown symbol pin '%s'" ), map.GetName(),
265 entry.m_PinNumber ) );
274 std::map<wxString, wxString> padToPin;
280 auto it = padToPin.find(
pad );
282 if( it == padToPin.end() )
284 padToPin[
pad] = entry.m_PinNumber;
286 else if( it->second != entry.m_PinNumber
287 && !sharesJumperGroup( it->second, entry.m_PinNumber ) )
290 ercItem->SetItems( symbol );
291 ercItem->SetErrorMessage(
292 wxString::Format(
_(
"Symbol pins '%s' and '%s' both map to pad '%s'" ),
293 it->second, entry.m_PinNumber,
pad ) );
302 if( checkBadPad && padFetcher )
311 const std::set<wxString>& pads = getPads( assoc.m_FootprintLibId.GetUniStringLibId() );
320 if( pads.count(
pad ) )
324 ercItem->SetItems( symbol );
325 ercItem->SetErrorMessage( wxString::Format(
326 _(
"Pin map '%s' references pad '%s' not present on footprint '%s'" ),
327 boundMap->
GetName(),
pad, assoc.m_FootprintLibId.GetUniStringLibId() ) );
354 if( fpText.IsEmpty() || fpId.
Parse( fpText,
true ) >= 0 )
364 if(
pin->IsDangling() )
368 pin->GetEffectivePadNumber( sheet, variant, fpId, &pads, &state );
370 if( state != SCH_PIN::PAD_RESOLUTION::UNMAPPED )
374 ercItem->SetItems(
pin );
375 ercItem->SetErrorMessage(
376 wxString::Format(
_(
"Pin '%s' is connected but maps to no pad on footprint '%s'" ),
377 pin->GetNumber(), fpText ) );
378 sheet.LastScreen()->Append(
new SCH_MARKER( std::move( ercItem ),
pin->GetPosition() ) );
394 [
this]( wxString str )
397 return str.Matches( wxS(
"*${*}*" ) );
410 static wxRegEx warningExpr( wxS(
"(^|[^\\\\])\\$\\{ERC_WARNING\\s*([^}]*)\\}" ) );
411 static wxRegEx errorExpr( wxS(
"(^|[^\\\\])\\$\\{ERC_ERROR\\s*([^}]*)\\}" ) );
414 [&]( wxRegEx& aExpr,
int aErrorCode )
421 wxString remaining =
text;
423 while( aExpr.Matches( remaining ) )
427 wxString ercText = aExpr.GetMatch( remaining, 2 );
432 ercItem->SetItems( item );
434 ercText +=
_(
" (in drawing sheet)" );
436 ercItem->SetSheetSpecificPath( sheet );
437 ercItem->SetErrorMessage( ercText );
440 screen->Append( marker );
445 if( !aExpr.GetMatch( &start, &len, 0 ) || len == 0 )
448 remaining = remaining.Mid( start + len );
457 return foundWarning || foundError;
483 if( testAssertion( &field, sheet, screen, field.GetText(), field.
GetPosition() ) )
487 else if( unresolved( field.GetShownText( &sheet,
true ) ) )
490 ercItem->SetItems( symbol );
491 ercItem->SetSheetSpecificPath( sheet );
511 if( testAssertion( symbol, sheet, screen, textItem->
GetText(),
516 else if( unresolved( textItem->
GetShownText( &sheet,
true ) ) )
519 ercItem->SetItems( symbol );
520 ercItem->SetSheetSpecificPath( sheet );
534 if( testAssertion( symbol, sheet, screen, textboxItem->
GetText(),
539 else if( unresolved( textboxItem->
GetShownText(
nullptr, &sheet,
543 ercItem->SetItems( symbol );
544 ercItem->SetSheetSpecificPath( sheet );
560 for(
SCH_FIELD& field : label->GetFields() )
562 if( testAssertion( &field, sheet, screen, field.GetText(), field.
GetPosition() ) )
566 else if( unresolved( field.GetShownText( &sheet,
true ) ) )
569 ercItem->SetItems( label );
570 ercItem->SetSheetSpecificPath( sheet );
583 if( testAssertion( &field, sheet, screen, field.GetText(), field.
GetPosition() ) )
587 else if( unresolved( field.GetShownText( &sheet,
true ) ) )
590 ercItem->SetItems( subSheet );
591 ercItem->SetSheetSpecificPath( sheet );
603 if(
pin->GetShownText( &subSheetPath,
true ).Matches( wxS(
"*${*}*" ) ) )
606 ercItem->SetItems(
pin );
607 ercItem->SetSheetSpecificPath( sheet );
616 if( testAssertion(
text, sheet, screen,
text->GetText(),
text->GetPosition() ) )
620 else if(
text->GetShownText( &sheet,
true ).Matches( wxS(
"*${*}*" ) ) )
623 ercItem->SetItems(
text );
624 ercItem->SetSheetSpecificPath( sheet );
632 if( testAssertion( textBox, sheet, screen, textBox->GetText(),
637 else if( textBox->GetShownText(
nullptr, &sheet,
true ).Matches( wxS(
"*${*}*" ) ) )
640 ercItem->SetItems( textBox );
641 ercItem->SetSheetSpecificPath( sheet );
653 if( testAssertion(
nullptr, sheet, screen,
text->GetText(),
text->GetPosition() ) )
657 else if(
text->GetShownText(
true ).Matches( wxS(
"*${*}*" ) ) )
660 ercItem->SetErrorMessage(
_(
"Unresolved text variable in drawing sheet" ) );
661 ercItem->SetSheetSpecificPath( sheet );
690 text.Trim(
false ).Trim(
true );
695 ercItem->SetItems( label );
696 ercItem->SetItemsSheetPaths( sheet );
697 ercItem->SetSheetSpecificPath( sheet );
725 wxString trimmedFieldName = field.GetName();
726 trimmedFieldName.Trim();
727 trimmedFieldName.Trim(
false );
729 if( field.GetName() != trimmedFieldName )
732 ercItem->SetItems( symbol, &field );
733 ercItem->SetItemsSheetPaths( sheet, sheet );
734 ercItem->SetSheetSpecificPath( sheet );
735 ercItem->SetErrorMessage(
737 _(
"Field name has leading or trailing whitespace: '%s'" ),
753 wxString trimmedFieldName = field.GetName();
754 trimmedFieldName.Trim();
755 trimmedFieldName.Trim(
false );
757 if( field.GetName() != trimmedFieldName )
760 ercItem->SetItems( subSheet, &field );
761 ercItem->SetItemsSheetPaths( sheet, sheet );
762 ercItem->SetSheetSpecificPath( sheet );
763 ercItem->SetErrorMessage(
765 _(
"Field name has leading or trailing whitespace: '%s'" ),
784 for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol :
m_refMap )
799 for(
size_t ii = 0; ii < refList.
GetCount(); ++ii )
804 if( !unitFP.IsEmpty() )
807 unitName = unit->
GetRef( &sheetPath,
true );
812 for(
size_t ii = 0; ii < refList.
GetCount(); ++ii )
820 if( unit && !secondFp.IsEmpty() && unitFP != secondFp )
822 msg.Printf(
_(
"Different footprints assigned to %s and %s" ),
823 unitName, secondName );
826 ercItem->SetErrorMessage( msg );
827 ercItem->SetItems( unit, secondUnit );
845 for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol :
m_refMap )
849 wxCHECK2( refList.
GetCount(),
continue );
859 std::set<int> lib_units;
860 std::set<int> instance_units;
861 std::set<int> missing_units;
864 [&]( std::set<int>& aMissingUnits,
const wxString& aErrorMsg,
int aErrorCode )
867 wxString missing_pin_units = wxS(
"[ " );
870 for(
int missing_unit : aMissingUnits )
874 missing_pin_units += wxS(
"..." );
881 missing_pin_units.Truncate( missing_pin_units.length() - 2 );
882 missing_pin_units += wxS(
" ]" );
884 msg.Printf( aErrorMsg, symbol.first, missing_pin_units );
887 ercItem->SetErrorMessage( msg );
888 ercItem->SetItems( unit );
889 ercItem->SetSheetSpecificPath( base_ref.
GetSheetPath() );
898 for(
int ii = 1; ii <= libSymbol->
GetUnitCount(); ++ii )
899 lib_units.insert( lib_units.end(), ii );
901 for(
size_t ii = 0; ii < refList.
GetCount(); ++ii )
902 instance_units.insert( instance_units.end(), refList.
GetItem( ii ).
GetUnit() );
904 std::set_difference( lib_units.begin(), lib_units.end(),
905 instance_units.begin(), instance_units.end(),
906 std::inserter( missing_units, missing_units.begin() ) );
913 std::set<int> missing_power;
914 std::set<int> missing_input;
915 std::set<int> missing_bidi;
917 for(
int missing_unit : missing_units )
921 for(
size_t ii = 0; ii < refList.
GetCount(); ++ii )
932 switch(
pin->GetType() )
935 missing_power.insert( missing_unit );
939 missing_bidi.insert( missing_unit );
943 missing_input.insert( missing_unit );
954 report( missing_power,
_(
"Symbol %s has input power pins in units %s that are not placed" ),
960 report( missing_input,
_(
"Symbol %s has input pins in units %s that are not placed" ),
966 report( missing_bidi,
_(
"Symbol %s has bidirectional pins in units %s that are not placed" ),
978 std::shared_ptr<NET_SETTINGS>& settings =
m_schematic->Project().GetProjectFile().NetSettings();
979 wxString defaultNetclass = settings->GetDefaultNetclass()->GetName();
988 ercItem->SetItems( item );
989 ercItem->SetErrorMessage( wxString::Format(
_(
"Netclass %s is not defined" ), netclass ) );
1008 wxString netclass = field->
GetShownText( &sheet,
false );
1010 if( !netclass.empty() && !netclass.IsSameAs( defaultNetclass )
1011 && !settings->HasNetclass( netclass ) )
1013 logError( sheet, item, netclass );
1034 std::map<VECTOR2I, std::vector<SCH_ITEM*>> connMap;
1041 connMap[pt].emplace_back( label );
1044 for(
const std::pair<
const VECTOR2I, std::vector<SCH_ITEM*>>& pair : connMap )
1046 std::vector<SCH_ITEM*> lines;
1048 for(
SCH_ITEM* item : sheet.LastScreen()->Items().Overlapping(
SCH_LINE_T, pair.first ) )
1057 lines.emplace_back( line );
1060 if( lines.size() > 1 )
1066 wxString msg = wxString::Format(
_(
"Label connects more than one wire at %d, %d" ),
1067 pair.first.x, pair.first.y );
1069 ercItem->SetItems( pair.second.front(), lines[0], lines[1], lines[2] );
1070 ercItem->SetErrorMessage( msg );
1071 ercItem->SetSheetSpecificPath( sheet );
1074 sheet.LastScreen()->Append( marker );
1087 auto pinStackAlreadyRepresented =
1088 [](
SCH_PIN*
pin, std::vector<SCH_ITEM*>& collection ) ->
bool
1090 for(
SCH_ITEM*& item : collection )
1092 if( item->Type() ==
SCH_PIN_T && item->GetParentSymbol() ==
pin->GetParentSymbol() )
1106 std::map<VECTOR2I, std::vector<SCH_ITEM*>> connMap;
1115 std::vector<SCH_ITEM*>& entry = connMap[
pin->GetPosition()];
1118 if( pinStackAlreadyRepresented(
pin, entry ) )
1121 entry.emplace_back(
pin );
1133 connMap[pt].emplace_back( line );
1136 for(
const std::pair<
const VECTOR2I, std::vector<SCH_ITEM*>>& pair : connMap )
1138 if( pair.second.size() >= 4 )
1144 ercItem->SetItems( pair.second[0], pair.second[1], pair.second[2], pair.second[3] );
1146 wxString msg = wxString::Format(
_(
"Four items connected at %d, %d" ),
1147 pair.first.x, pair.first.y );
1148 ercItem->SetErrorMessage( msg );
1150 ercItem->SetSheetSpecificPath( sheet );
1153 sheet.LastScreen()->Append( marker );
1168 std::map<VECTOR2I, std::vector<SCH_ITEM*>> pinMap;
1173 if( pinMap.count( pt ) )
1174 pinMap[pt].emplace_back( aOther );
1184 pinMap[
pin->GetPosition()].emplace_back(
pin );
1188 for(
SCH_ITEM* item : sheet.LastScreen()->Items() )
1197 addOther(
pin->GetPosition(),
pin );
1202 for(
const VECTOR2I& pt : item->GetConnectionPoints() )
1203 addOther( pt, item );
1207 for(
const std::pair<
const VECTOR2I, std::vector<SCH_ITEM*>>& pair : pinMap )
1209 if( pair.second.size() > 1 )
1213 for(
SCH_ITEM* item : pair.second )
1237 ercItem->SetItems( pair.second[0], pair.second[1],
1238 pair.second.size() > 2 ? pair.second[2] :
nullptr,
1239 pair.second.size() > 3 ? pair.second[3] :
nullptr );
1240 ercItem->SetErrorMessage(
_(
"Pin with 'no connection' type is connected" ) );
1241 ercItem->SetSheetSpecificPath( sheet );
1244 sheet.LastScreen()->Append( marker );
1259 std::unordered_map<wxString, std::vector<ERC_SCH_PIN_CONTEXT>> netToPins;
1263 using iterator_t = std::vector<ERC_SCH_PIN_CONTEXT>::iterator;
1264 std::vector<ERC_SCH_PIN_CONTEXT> pins;
1265 std::unordered_map<EDA_ITEM*, SCH_SCREEN*> pinToScreenMap;
1266 bool has_noconnect =
false;
1271 has_noconnect =
true;
1277 pins.emplace_back(
static_cast<SCH_PIN*
>( item ), subgraph->
GetSheet() );
1278 netToPins[ net.first.Name ].emplace_back(
static_cast<SCH_PIN*
>( item ), subgraph->
GetSheet() );
1284 std::sort( pins.begin(), pins.end(),
1287 int ret = StrNumCmp( lhs.Pin()->GetParentSymbol()->GetRef( &lhs.Sheet() ),
1288 rhs.Pin()->GetParentSymbol()->GetRef( &rhs.Sheet() ) );
1291 ret = StrNumCmp( lhs.Pin()->GetNumber(), rhs.Pin()->GetNumber() );
1301 bool hasDriver =
false;
1302 std::vector<ERC_SCH_PIN_CONTEXT*> pinsNeedingDrivers;
1303 std::vector<ERC_SCH_PIN_CONTEXT*> nonPowerPinsNeedingDrivers;
1304 std::vector<ERC_SCH_PIN_CONTEXT*> powerInPinsNeedingDrivers;
1309 bool ispowerNet =
false;
1320 std::vector<std::tuple<iterator_t, iterator_t, PIN_ERROR>> pin_mismatches;
1321 std::map<iterator_t, int> pin_mismatch_counts;
1323 for(
auto refIt = pins.begin(); refIt != pins.end(); ++refIt )
1333 pinsNeedingDrivers.push_back( &refPin );
1336 nonPowerPinsNeedingDrivers.push_back( &refPin );
1339 powerInPinsNeedingDrivers.push_back( &refPin );
1341 if( !needsDriver.
Pin()
1346 needsDriver = refPin;
1347 needsDriverType = needsDriver.
Pin()->
GetType();
1356 for(
auto testIt = refIt + 1; testIt != pins.end(); ++testIt )
1380 pin_mismatches.emplace_back( std::tuple<iterator_t, iterator_t, PIN_ERROR>{ refIt, testIt,
erc } );
1384 pin_mismatch_counts[refIt] =
m_settings.GetPinTypeWeight( ( *refIt ).Pin()->GetType() );
1385 pin_mismatch_counts[testIt] =
m_settings.GetPinTypeWeight( ( *testIt ).Pin()->GetType() );
1389 if( !pin_mismatch_counts.contains( testIt ) )
1390 pin_mismatch_counts.emplace( testIt, 1 );
1392 pin_mismatch_counts[testIt]++;
1394 if( !pin_mismatch_counts.contains( refIt ) )
1395 pin_mismatch_counts.emplace( refIt, 1 );
1397 pin_mismatch_counts[refIt]++;
1403 std::multimap<size_t, iterator_t, std::greater<size_t>> pins_dsc;
1405 std::transform( pin_mismatch_counts.begin(), pin_mismatch_counts.end(),
1406 std::inserter( pins_dsc, pins_dsc.begin() ),
1409 return std::pair<size_t, iterator_t>( p.second, p.first );
1412 for(
const auto& [amount, pinItBind] : pins_dsc )
1414 auto& pinIt = pinItBind;
1416 if( pin_mismatches.empty() )
1422 iterator_t nearest_pin = pins.end();
1423 double smallest_distance = std::numeric_limits<double>::infinity();
1428 [&](
const auto& tuple )
1432 if( pinIt == std::get<0>( tuple ) )
1433 other = std::get<1>( tuple );
1434 else if( pinIt == std::get<1>( tuple ) )
1435 other = std::get<0>( tuple );
1439 if( ( *pinIt ).Sheet().Cmp( ( *other ).Sheet() ) != 0 )
1441 if( std::isinf( smallest_distance ) )
1443 nearest_pin = other;
1444 erc = std::get<2>( tuple );
1451 if( std::isinf( smallest_distance ) ||
distance < smallest_distance )
1454 nearest_pin = other;
1455 erc = std::get<2>( tuple );
1462 if( nearest_pin != pins.end() )
1464 SCH_PIN* other_pin = ( *nearest_pin ).Pin();
1468 ercItem->SetItems(
pin, other_pin );
1469 ercItem->SetSheetSpecificPath( ( *pinIt ).Sheet() );
1470 ercItem->SetItemsSheetPaths( ( *pinIt ).Sheet(), ( *nearest_pin ).Sheet() );
1472 ercItem->SetErrorMessage( wxString::Format(
_(
"Pins of type %s and %s are connected" ),
1477 pinToScreenMap[
pin]->Append( marker );
1482 if( needsDriver.
Pin() && !hasDriver && !has_noconnect )
1490 bool suppressForNetChainDriver =
false;
1494 const wxString& thisNetName = net.first.Name;
1495 const auto& netChains =
m_schematic->ConnectionGraph()->GetCommittedNetChains();
1497 auto netHasPowerDriver = [&](
const wxString& aNetName ) ->
bool
1500 for(
const auto& n :
m_nets )
1502 if( n.first.Name != aNetName )
1524 for(
const auto& sig : netChains )
1529 const auto& sigNets = sig->GetNets();
1530 bool containsThisNet = std::find( sigNets.begin(), sigNets.end(), thisNetName ) != sigNets.end();
1532 if( !containsThisNet )
1536 for(
const wxString& otherNet : sigNets )
1538 if( otherNet == thisNetName )
1541 if( netHasPowerDriver( otherNet ) )
1543 suppressForNetChainDriver =
true;
1552 if( !suppressForNetChainDriver &&
m_settings.IsTestEnabled( err_code ) )
1554 std::vector<ERC_SCH_PIN_CONTEXT*> pinsToMark;
1563 if( ispowerNet && !powerInPinsNeedingDrivers.empty() )
1564 pinsToMark = powerInPinsNeedingDrivers;
1565 else if( !nonPowerPinsNeedingDrivers.empty() )
1566 pinsToMark = nonPowerPinsNeedingDrivers;
1568 pinsToMark = pinsNeedingDrivers;
1572 if( ispowerNet && !powerInPinsNeedingDrivers.empty() )
1573 pinsToMark.push_back( powerInPinsNeedingDrivers.front() );
1575 pinsToMark.push_back( &needsDriver );
1582 ercItem->SetItems( pinCtx->Pin() );
1583 ercItem->SetSheetSpecificPath( pinCtx->Sheet() );
1584 ercItem->SetItemsSheetPaths( pinCtx->Sheet() );
1587 pinToScreenMap[pinCtx->Pin()]->Append( marker );
1602 auto& netChains =
m_schematic->ConnectionGraph()->GetCommittedNetChains();
1603 wxLogTrace(
traceSchNetChain,
"ERC TestPinToPin: cross-chain phase start chains=%zu",
1606 for(
const auto& sig : netChains )
1611 const wxString chainName = sig->GetName();
1612 const auto& sigNets = sig->GetNets();
1615 std::vector<ERC_SCH_PIN_CONTEXT> netChainPins;
1616 netChainPins.reserve( sigNets.size() * 4 );
1618 for(
const wxString& n : sigNets )
1620 auto it = netToPins.find( n );
1621 if( it != netToPins.end() )
1623 const auto& vec = it->second;
1624 netChainPins.insert( netChainPins.end(), vec.begin(), vec.end() );
1628 if( netChainPins.size() < 2 )
1632 "ERC TestPinToPin: chain '%s' nets=%zu collectedPins=%zu",
1633 TO_UTF8( chainName ), sigNets.size(), netChainPins.size() );
1636 std::sort( netChainPins.begin(), netChainPins.end(),
1639 int ret = StrNumCmp( lhs.Pin()->GetParentSymbol()->GetRef( &lhs.Sheet() ),
1640 rhs.Pin()->GetParentSymbol()->GetRef( &rhs.Sheet() ) );
1642 ret = StrNumCmp( lhs.Pin()->GetNumber(), rhs.Pin()->GetNumber() );
1649 std::unordered_map<SCH_PIN*, wxString> pinNet;
1650 for(
const auto& netEntry : netToPins )
1651 for(
const auto& ctx : netEntry.second )
1652 pinNet[ ctx.Pin() ] = netEntry.first;
1654 for(
size_t i = 0; i < netChainPins.size(); ++i )
1656 SCH_PIN* aPin = netChainPins[i].Pin();
1658 const wxString& aNet = pinNet[aPin];
1660 for(
size_t j = i + 1; j < netChainPins.size(); ++j )
1662 SCH_PIN* bPin = netChainPins[j].Pin();
1663 const wxString& bNet = pinNet[bPin];
1678 ercItem->SetItems( aPin, bPin );
1679 ercItem->SetSheetSpecificPath( netChainPins[i].Sheet() );
1680 ercItem->SetItemsSheetPaths( netChainPins[i].Sheet(), netChainPins[j].Sheet() );
1681 ercItem->SetErrorMessage( wxString::Format(
1682 _(
"Pins of type %s and %s are connected via net chain %s" ),
1687 netChainPins[i].Sheet().LastScreen()->Append( marker );
1703 std::unordered_map<wxString, std::pair<wxString, SCH_PIN*>> pinToNetMap;
1707 const wxString& netName = net.first.Name;
1718 if( !
pin->GetParentSymbol()->IsMultiUnit() )
1721 wxString
name =
pin->GetParentSymbol()->GetRef( &sheet ) +
":" +
pin->GetShownNumber();
1723 if( !pinToNetMap.count(
name ) )
1725 pinToNetMap[
name] = std::make_pair( netName,
pin );
1727 else if( pinToNetMap[
name].first != netName )
1731 ercItem->SetErrorMessage( wxString::Format(
_(
"Pin %s is connected to both %s and %s" ),
1732 pin->GetShownNumber(),
1734 pinToNetMap[
name].first ) );
1736 ercItem->SetItems(
pin, pinToNetMap[
name].second );
1737 ercItem->SetSheetSpecificPath( sheet );
1738 ercItem->SetItemsSheetPaths( sheet, sheet );
1772 std::vector<SCH_PIN*> pins = symbol->
GetPins( &sheet );
1774 std::map<wxString, std::vector<std::pair<SCH_PIN*, wxString>>> pinsByNumber;
1779 wxString netName = conn ? conn->
GetNetName() : wxString();
1781 pinsByNumber[
pin->GetNumber()].emplace_back(
pin, netName );
1784 for(
const auto& [pinNumber, pinNetPairs] : pinsByNumber )
1786 if( pinNetPairs.size() < 2 )
1789 wxString firstNet = pinNetPairs[0].second;
1790 bool hasDifferentNets =
false;
1791 SCH_PIN* conflictPin =
nullptr;
1793 for(
size_t i = 1; i < pinNetPairs.size(); i++ )
1795 if( pinNetPairs[i].second != firstNet )
1797 hasDifferentNets =
true;
1798 conflictPin = pinNetPairs[i].first;
1803 if( hasDifferentNets )
1808 msg.Printf(
_(
"Pin %s on symbol '%s' is connected to different nets: %s and %s" ),
1810 symbol->
GetRef( &sheet ),
1811 firstNet.IsEmpty() ?
_(
"<no net>" ) : firstNet,
1812 pinNetPairs[1].second.IsEmpty() ?
_(
"<no net>" ) : pinNetPairs[1].second );
1814 ercItem->SetErrorMessage( msg );
1815 ercItem->SetItems( pinNetPairs[0].first, conflictPin );
1816 ercItem->SetSheetSpecificPath( sheet );
1817 ercItem->SetItemsSheetPaths( sheet, sheet );
1820 pinNetPairs[0].first->GetPosition() );
1821 screen->
Append( marker );
1837 [](
const wxString& txt )
1839 wxString upper = txt.Upper();
1841 return upper.Contains( wxT(
"GND" ) )
1842 || upper == wxT(
"EARTH" ) || upper.StartsWith( wxT(
"EARTH_" ) )
1843 || upper == wxT(
"VSS" ) || upper == wxT(
"VSSA" );
1853 bool hasGroundNet =
false;
1854 std::vector<SCH_PIN*> mismatched;
1859 wxString net = conn ? conn->
GetNetName() : wxString();
1860 bool netIsGround = isGround( net );
1870 hasGroundNet =
true;
1872 if( isGround(
pin->GetShownName() ) && !netIsGround )
1873 mismatched.push_back(
pin );
1882 ercItem->SetErrorMessage( wxString::Format(
_(
"Pin %s not connected to ground net" ),
1883 pin->GetShownName() ) );
1884 ercItem->SetItems(
pin );
1885 ercItem->SetSheetSpecificPath( sheet );
1886 ercItem->SetItemsSheetPaths( sheet );
1889 screen->
Append( marker );
1915 pin->GetStackedPinNumbers( &valid );
1920 ercItem->SetItems(
pin );
1921 ercItem->SetSheetSpecificPath( sheet );
1922 ercItem->SetItemsSheetPaths( sheet );
1925 screen->
Append( marker );
1940 std::unordered_map<wxString, std::pair<SCH_ITEM*, SCH_SHEET_PATH>> globalLabels;
1941 std::unordered_map<wxString, std::pair<SCH_ITEM*, SCH_SHEET_PATH>> localLabels;
1956 auto& map = item->Type() ==
SCH_LABEL_T ? localLabels : globalLabels;
1958 if( !map.count(
text ) )
1960 map[
text] = std::make_pair( label, sheet );
1967 if( !
pin->IsPower() )
1976 ?
pin->GetShownName()
1977 : symbol->
GetValue(
true, &sheet,
false );
1979 auto& map =
pin->IsGlobalPower() ? globalLabels : localLabels;
1981 if( !map.count(
text ) )
1983 map[
text] = std::make_pair(
pin, sheet );
1990 for(
auto& [globalText, globalItem] : globalLabels )
1992 for(
auto& [localText, localItem] : localLabels )
1994 if( globalText == localText )
2004 ercItem->SetItems( globalItem.first, localItem.first );
2005 ercItem->SetSheetSpecificPath( globalItem.second );
2006 ercItem->SetItemsSheetPaths( globalItem.second, localItem.second );
2009 globalItem.second.LastScreen()->Append( marker );
2023 std::unordered_map<wxString, std::vector<std::tuple<wxString, SCH_ITEM*, SCH_SHEET_PATH>>> generalMap;
2027 const std::tuple<wxString, SCH_ITEM*, SCH_SHEET_PATH>& other )
2029 auto& [otherText, otherItem, otherSheet] = other;
2049 ercItem->SetItems( item, otherItem );
2050 ercItem->SetSheetSpecificPath( sheet );
2051 ercItem->SetItemsSheetPaths( sheet, otherSheet );
2054 sheet.LastScreen()->Append( marker );
2065 switch( item->Type() )
2072 wxString unnormalized = label->
GetShownText( &sheet,
false );
2073 wxString normalized = unnormalized.Lower();
2075 generalMap[normalized].emplace_back( std::make_tuple( unnormalized, label, sheet ) );
2077 for(
const auto& otherTuple : generalMap.at( normalized ) )
2079 const auto& [otherText, otherItem, otherSheet] = otherTuple;
2081 if( unnormalized != otherText )
2085 && sheet != otherSheet )
2090 logError( normalized, label, sheet, otherTuple );
2101 if( !
pin->IsPower() )
2105 wxString unnormalized = symbol->
GetValue(
true, &sheet,
false );
2106 wxString normalized = unnormalized.Lower();
2108 generalMap[normalized].emplace_back( std::make_tuple( unnormalized,
pin, sheet ) );
2110 for(
const auto& otherTuple : generalMap.at( normalized ) )
2112 const auto& [otherText, otherItem, otherSheet] = otherTuple;
2114 if( unnormalized != otherText )
2116 logError( normalized,
pin, sheet, otherTuple );
2146 std::vector<SCH_MARKER*> markers;
2153 if( !libSymbolInSchematic )
2158 std::optional<const LIBRARY_TABLE_ROW*> optRow =
2161 if( !optRow || ( *optRow )->Disabled() )
2166 ercItem->SetItems( symbol );
2167 msg.Printf(
_(
"The current configuration does not include the symbol library '%s'" ),
2169 ercItem->SetErrorMessage( msg );
2181 std::optional<wxString> uri =
2183 wxCHECK2( uri.has_value(), uri = wxEmptyString );
2184 ercItem->SetItems( symbol );
2185 msg.Printf(
_(
"The symbol library '%s' was not found at '%s'" ),
2187 ercItem->SetErrorMessage( msg );
2198 if( libSymbol ==
nullptr )
2203 ercItem->SetItems( symbol );
2204 msg.Printf(
_(
"Symbol '%s' not found in symbol library '%s'" ),
2207 ercItem->SetErrorMessage( msg );
2215 std::unique_ptr<LIB_SYMBOL> flattenedSymbol = libSymbol->
Flatten();
2224 std::vector<wxString> messages;
2232 if( messages.empty() && flattenedSymbol->Compare( *libSymbolInSchematic, flags ) != 0 )
2235 ercItem->SetItems( symbol );
2236 msg.Printf(
_(
"Symbol '%s' doesn't match copy in library '%s'" ),
2239 ercItem->SetErrorMessage( msg );
2248 screen->Append( marker );
2261 if( std::optional<LIBRARY_MANAGER_ADAPTER*> adapter =
2264 ( *adapter )->BlockUntilLoaded();
2270 typedef int (*TESTER_FN_PTR)(
const wxString&,
PROJECT* );
2276 std::vector<SCH_MARKER*> markers;
2283 if( footprint.IsEmpty() )
2288 if( fpID.
Parse( footprint,
true ) >= 0 )
2291 msg.Printf(
_(
"'%s' is not a valid footprint identifier" ), footprint );
2292 ercItem->SetErrorMessage( msg );
2293 ercItem->SetItems( symbol );
2300 int ret = (linkTester)( footprint, aProject );
2305 msg.Printf(
_(
"The current configuration does not include the footprint library '%s'" ),
2307 ercItem->SetErrorMessage( msg );
2308 ercItem->SetItems( symbol );
2314 msg.Printf(
_(
"The footprint library '%s' is not enabled in the current configuration" ),
2316 ercItem->SetErrorMessage( msg );
2317 ercItem->SetItems( symbol );
2323 msg.Printf(
_(
"Footprint '%s' not found in library '%s'" ),
2326 ercItem->SetErrorMessage( msg );
2327 ercItem->SetItems( symbol );
2334 sheet.LastScreen()->Append( marker );
2352 std::vector<SCH_MARKER*> markers;
2357 std::unique_ptr<LIB_SYMBOL>& lib_symbol = sch_symbol->
GetLibSymbolRef();
2362 wxArrayString filters = lib_symbol->GetFPFilters();
2364 if( filters.empty() )
2370 if( footprint.
Parse( lowerId ) > 0 )
2376 for( wxString
filter : filters )
2381 if(
filter.Contains( wxS(
":" ) ) )
2382 found |= lowerId.Matches(
filter );
2384 found |= lowerItemName.Matches(
filter );
2393 msg.Printf(
_(
"Assigned footprint (%s) doesn't match footprint filters (%s)" ),
2395 wxJoin( filters,
' ' ) );
2396 ercItem->SetErrorMessage( msg );
2397 ercItem->SetItems( sch_symbol );
2404 sheet.LastScreen()->Append( marker );
2415 const int gridSize =
m_schematic->Settings().m_ConnectionGridSize;
2420 std::vector<SCH_MARKER*> markers;
2422 for(
SCH_ITEM* item : screen->Items() )
2424 if( item->Type() ==
SCH_LINE_T && item->IsConnectable() )
2432 ercItem->SetItems( line );
2440 ercItem->SetItems( line );
2451 if( ( point.x % gridSize ) != 0
2452 || ( point.y % gridSize ) != 0 )
2455 ercItem->SetItems( entry );
2457 markers.emplace_back(
new SCH_MARKER( std::move( ercItem ), point ) );
2472 if( ( pinPos.
x % gridSize ) != 0 || ( pinPos.
y % gridSize ) != 0 )
2475 ercItem->SetItems(
pin );
2477 markers.emplace_back(
new SCH_MARKER( std::move( ercItem ), pinPos ) );
2486 screen->Append( marker );
2500 wxString variant =
m_schematic->GetCurrentVariant();
2504 if( sheet.GetExcludedFromSim( variant ) )
2507 std::vector<SCH_MARKER*> markers;
2525 wxString msg =
reporter.GetMessages();
2531 ercItem->SetErrorMessage( msg );
2532 ercItem->SetItems( symbol );
2540 sheet.LastScreen()->Append( marker );
2561 std::map<wxString, std::unique_ptr<LIB_SYMBOL>> flatAltCache;
2570 std::vector<SCH_MARKER*> markers;
2577 if( !symbol->
GetInstance( instance, sheet.Path() ) )
2581 [&](
int aErrorCode,
const wxString& aMessage )
2585 ercItem->SetItems( symbol );
2586 ercItem->SetSheetSpecificPath( sheet );
2587 ercItem->SetErrorMessage( aMessage );
2589 markers.emplace_back(
2594 for(
const auto& [variantName, variant] : instance.
m_Variants )
2596 if( !variant.m_SymbolOverride )
2599 const LIB_ID& libId = *variant.m_SymbolOverride;
2600 wxString libIdStr = libId.
Format();
2606 auto cacheIt = flatAltCache.find( libIdStr );
2608 if( cacheIt == flatAltCache.end() )
2610 std::unique_ptr<LIB_SYMBOL> flatAlt;
2615 flatAlt = altSymbol->Flatten();
2621 cacheIt = flatAltCache.emplace( libIdStr, std::move( flatAlt ) ).first;
2624 const LIB_SYMBOL* flatAlt = cacheIt->second.get();
2631 wxString::Format(
_(
"Variant '%s': symbol '%s' not found in libraries" ),
2632 variantName, libIdStr ) );
2647 std::vector<VARIANT_COMPAT_RESULT> issues =
2653 wxString::Format(
_(
"Variant '%s', alternate '%s': %s" ),
2654 variantName, libIdStr, issue.detail ) );
2660 screen->
Append( marker );
2676 if( aProgressReporter )
2677 aProgressReporter->
AdvancePhase(
_(
"Checking sheet names..." ) );
2686 if( aProgressReporter )
2687 aProgressReporter->
AdvancePhase(
_(
"Checking pin maps..." ) );
2693 if( aProgressReporter )
2694 aProgressReporter->
AdvancePhase(
_(
"Checking conflicts..." ) );
2707 if( aProgressReporter )
2708 aProgressReporter->
AdvancePhase(
_(
"Checking units..." ) );
2713 if( aProgressReporter )
2714 aProgressReporter->
AdvancePhase(
_(
"Checking footprints..." ) );
2727 if( aProgressReporter )
2757 if( aProgressReporter )
2758 aProgressReporter->
AdvancePhase(
_(
"Checking similar labels..." ) );
2766 if( aProgressReporter )
2767 aProgressReporter->
AdvancePhase(
_(
"Checking local and global labels..." ) );
2774 if( aProgressReporter )
2775 aProgressReporter->
AdvancePhase(
_(
"Checking for unresolved variables..." ) );
2782 if( aProgressReporter )
2783 aProgressReporter->
AdvancePhase(
_(
"Checking field names..." ) );
2790 if( aProgressReporter )
2791 aProgressReporter->
AdvancePhase(
_(
"Checking for empty label names..." ) );
2798 if( aProgressReporter )
2799 aProgressReporter->
AdvancePhase(
_(
"Checking SPICE models..." ) );
2806 if( aProgressReporter )
2807 aProgressReporter->
AdvancePhase(
_(
"Checking no connect pins for connections..." ) );
2815 if( aProgressReporter )
2816 aProgressReporter->
AdvancePhase(
_(
"Checking for library symbol issues..." ) );
2823 if( aProgressReporter )
2824 aProgressReporter->
AdvancePhase(
_(
"Checking for footprint link issues..." ) );
2831 if( aProgressReporter )
2832 aProgressReporter->
AdvancePhase(
_(
"Checking footprint assignments against footprint filters..." ) );
2839 if( aProgressReporter )
2840 aProgressReporter->
AdvancePhase(
_(
"Checking for off grid pins and wires..." ) );
2847 if( aProgressReporter )
2848 aProgressReporter->
AdvancePhase(
_(
"Checking for four way junctions..." ) );
2855 if( aProgressReporter )
2856 aProgressReporter->
AdvancePhase(
_(
"Checking for labels on more than one wire..." ) );
2863 if( aProgressReporter )
2864 aProgressReporter->
AdvancePhase(
_(
"Checking for undefined netclasses..." ) );
2872 if( aProgressReporter )
2873 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
Schematic editor (Eeschema) main window.
void RecalculateConnections(SCH_COMMIT *aCommit, SCH_CLEANUP_FLAGS aCleanupFlags, PROGRESS_REPORTER *aProgressReporter=nullptr)
Generate the connection data for the entire schematic hierarchy.
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 wxString &aVariantName=wxEmptyString) 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
wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0) const override
std::vector< VECTOR2I > GetConnectionPoints() const override
Add all the connection points for this item to aPoints.
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.
VECTOR2I GetPosition() const override
std::vector< SCH_SHEET_PIN * > & GetPins()
wxString GetShownName(bool aAllowExtraText) 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
const wxString GetValue(bool aResolve, const SCH_SHEET_PATH *aPath, bool aAllowExtraText, const wxString &aVariantName=wxEmptyString) const override
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly) const override
Populate a std::vector with SCH_FIELDs, sorted in ordinal order.
const wxString GetFootprintFieldText(bool aResolve, const SCH_SHEET_PATH *aPath, bool aAllowExtraText, const wxString &aVariantName=wxEmptyString) const
VECTOR2I GetPosition() const override
const LIB_ID & GetLibId() const override
bool GetInstance(SCH_SYMBOL_INSTANCE &aInstance, const KIID_PATH &aSheetPath, bool aTestFromEnd=false) const
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, bool aAllowExtraText, 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, bool aAllowExtraText, int aDepth=0) const
SIM_MODEL & CreateModel(SIM_MODEL::TYPE aType, const std::vector< SCH_PIN * > &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.
#define FOR_ERC_DRC
Expand '${var-name}' templates in text.
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)
#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