83 _(
"Bidirectional Pin" ),
87 _(
"Unspecified Pin" ),
88 _(
"Power Input Pin" ),
89 _(
"Power Output Pin" ),
90 _(
"Open Collector" ),
100 _(
"Bidirectional Pin" ),
101 _(
"Tri-State Pin" ),
104 _(
"Unspecified Pin" ),
105 _(
"Power Input Pin" ),
106 _(
"Power Output Pin" ),
107 _(
"Open Collector" ),
149 std::vector<SCH_SHEET*> list;
152 list.push_back(
static_cast<SCH_SHEET*
>( item ) );
154 for(
size_t i = 0; i < list.size(); i++ )
158 for(
size_t j = i + 1; j < list.size(); j++ )
170 ercItem->SetItems( sheet, test_item );
173 screen->Append( marker );
191 [
this]( wxString str )
194 return str.Matches( wxS(
"*${*}*" ) );
201 static wxRegEx warningExpr( wxS(
"^\\$\\{ERC_WARNING\\s*([^}]*)\\}(.*)$" ) );
202 static wxRegEx errorExpr( wxS(
"^\\$\\{ERC_ERROR\\s*([^}]*)\\}(.*)$" ) );
204 if( warningExpr.Matches(
text ) )
207 wxString ercText = warningExpr.GetMatch(
text, 1 );
210 ercItem->SetItems( item );
212 ercText +=
_(
" (in drawing sheet)" );
214 ercItem->SetSheetSpecificPath( sheet );
215 ercItem->SetErrorMessage( ercText );
218 screen->Append( marker );
223 if( errorExpr.Matches(
text ) )
226 wxString ercText = errorExpr.GetMatch(
text, 1 );
229 ercItem->SetItems( item );
231 ercText +=
_(
" (in drawing sheet)" );
233 ercItem->SetSheetSpecificPath( sheet );
234 ercItem->SetErrorMessage( ercText );
237 screen->Append( marker );
268 if( unresolved( field.GetShownText( &sheet,
true ) ) )
271 ercItem->SetItems( symbol );
272 ercItem->SetSheetSpecificPath( sheet );
278 testAssertion( &field, sheet, screen, field.GetText(), field.
GetPosition() );
294 if( unresolved( textItem->
GetShownText( &sheet,
true ) ) )
297 ercItem->SetItems( symbol );
298 ercItem->SetSheetSpecificPath( sheet );
308 testAssertion( symbol, sheet, screen, textItem->
GetText(),
315 if( unresolved( textboxItem->
GetShownText(
nullptr, &sheet,
true ) ) )
318 ercItem->SetItems( symbol );
319 ercItem->SetSheetSpecificPath( sheet );
329 testAssertion( symbol, sheet, screen, textboxItem->
GetText(),
338 for(
SCH_FIELD& field : label->GetFields() )
340 if( unresolved( field.GetShownText( &sheet,
true ) ) )
343 ercItem->SetItems( label );
344 ercItem->SetSheetSpecificPath( sheet );
350 testAssertion( &field, sheet, screen, field.GetText(), field.
GetPosition() );
359 if( unresolved( field.GetShownText( &sheet,
true ) ) )
362 ercItem->SetItems( subSheet );
363 ercItem->SetSheetSpecificPath( sheet );
369 testAssertion( &field, sheet, screen, field.GetText(), field.
GetPosition() );
377 if(
pin->GetShownText( &subSheetPath,
true ).Matches( wxS(
"*${*}*" ) ) )
380 ercItem->SetItems(
pin );
381 ercItem->SetSheetSpecificPath( sheet );
390 if(
text->GetShownText( &sheet,
true ).Matches( wxS(
"*${*}*" ) ) )
393 ercItem->SetItems(
text );
394 ercItem->SetSheetSpecificPath( sheet );
400 testAssertion(
text, sheet, screen,
text->GetText(),
text->GetPosition() );
404 if( textBox->GetShownText(
nullptr, &sheet,
true ).Matches( wxS(
"*${*}*" ) ) )
407 ercItem->SetItems( textBox );
408 ercItem->SetSheetSpecificPath( sheet );
414 testAssertion( textBox, sheet, screen, textBox->GetText(), textBox->
GetPosition() );
422 if( testAssertion(
nullptr, sheet, screen,
text->GetText(),
text->GetPosition() ) )
426 else if(
text->GetShownText(
true ).Matches( wxS(
"*${*}*" ) ) )
429 ercItem->SetErrorMessage(
_(
"Unresolved text variable in drawing sheet" ) );
430 ercItem->SetSheetSpecificPath( sheet );
445 for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol :
m_refMap )
460 for(
size_t ii = 0; ii < refList.
GetCount(); ++ii )
465 if( !unitFP.IsEmpty() )
468 unitName = unit->
GetRef( &sheetPath,
true );
473 for(
size_t ii = 0; ii < refList.
GetCount(); ++ii )
481 if( unit && !secondFp.IsEmpty() && unitFP != secondFp )
483 msg.Printf(
_(
"Different footprints assigned to %s and %s" ),
484 unitName, secondName );
487 ercItem->SetErrorMessage( msg );
488 ercItem->SetItems( unit, secondUnit );
506 for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol :
m_refMap )
510 wxCHECK2( refList.
GetCount(),
continue );
520 std::set<int> lib_units;
521 std::set<int> instance_units;
522 std::set<int> missing_units;
525 [&]( std::set<int>& aMissingUnits,
const wxString& aErrorMsg,
int aErrorCode )
528 wxString missing_pin_units = wxS(
"[ " );
531 for(
int missing_unit : aMissingUnits )
535 missing_pin_units += wxS(
"..." );
542 missing_pin_units.Truncate( missing_pin_units.length() - 2 );
543 missing_pin_units += wxS(
" ]" );
545 msg.Printf( aErrorMsg, symbol.first, missing_pin_units );
548 ercItem->SetErrorMessage( msg );
549 ercItem->SetItems( unit );
550 ercItem->SetSheetSpecificPath( base_ref.
GetSheetPath() );
559 for(
int ii = 1; ii <= libSymbol->
GetUnitCount(); ++ii )
560 lib_units.insert( lib_units.end(), ii );
562 for(
size_t ii = 0; ii < refList.
GetCount(); ++ii )
563 instance_units.insert( instance_units.end(), refList.
GetItem( ii ).
GetUnit() );
565 std::set_difference( lib_units.begin(), lib_units.end(),
566 instance_units.begin(), instance_units.end(),
567 std::inserter( missing_units, missing_units.begin() ) );
574 std::set<int> missing_power;
575 std::set<int> missing_input;
576 std::set<int> missing_bidi;
578 for(
int missing_unit : missing_units )
582 for(
size_t ii = 0; ii < refList.
GetCount(); ++ii )
593 switch(
pin->GetType() )
596 missing_power.insert( missing_unit );
600 missing_bidi.insert( missing_unit );
604 missing_input.insert( missing_unit );
615 report( missing_power,
_(
"Symbol %s has input power pins in units %s that are not placed" ),
621 report( missing_input,
_(
"Symbol %s has input pins in units %s that are not placed" ),
627 report( missing_bidi,
_(
"Symbol %s has bidirectional pins in units %s that are not placed" ),
639 std::shared_ptr<NET_SETTINGS>& settings =
m_schematic->Project().GetProjectFile().NetSettings();
640 wxString defaultNetclass = settings->GetDefaultNetclass()->GetName();
649 ercItem->SetItems( item );
650 ercItem->SetErrorMessage( wxString::Format(
_(
"Netclass %s is not defined" ), netclass ) );
669 wxString netclass = field->
GetShownText( &sheet,
false );
671 if( !netclass.empty() && !netclass.IsSameAs( defaultNetclass )
672 && !settings->HasNetclass( netclass ) )
674 logError( sheet, item, netclass );
695 std::map<VECTOR2I, std::vector<SCH_ITEM*>> connMap;
702 connMap[pt].emplace_back( label );
705 for(
const std::pair<
const VECTOR2I, std::vector<SCH_ITEM*>>& pair : connMap )
707 std::vector<SCH_ITEM*> lines;
709 for(
SCH_ITEM* item : sheet.LastScreen()->Items().Overlapping(
SCH_LINE_T, pair.first ) )
718 lines.emplace_back( line );
721 if( lines.size() > 1 )
727 wxString msg = wxString::Format(
_(
"Label connects more than one wire at %d, %d" ),
728 pair.first.x, pair.first.y );
730 ercItem->SetItems( pair.second.front(), lines[0], lines[1], lines[2] );
731 ercItem->SetErrorMessage( msg );
732 ercItem->SetSheetSpecificPath( sheet );
735 sheet.LastScreen()->Append( marker );
748 auto pinStackAlreadyRepresented =
749 [](
SCH_PIN*
pin, std::vector<SCH_ITEM*>& collection ) ->
bool
753 if( item->Type() ==
SCH_PIN_T && item->GetParentSymbol() ==
pin->GetParentSymbol() )
767 std::map<VECTOR2I, std::vector<SCH_ITEM*>> connMap;
776 std::vector<SCH_ITEM*>& entry = connMap[
pin->GetPosition()];
779 if( pinStackAlreadyRepresented(
pin, entry ) )
782 entry.emplace_back(
pin );
794 connMap[pt].emplace_back( line );
797 for(
const std::pair<
const VECTOR2I, std::vector<SCH_ITEM*>>& pair : connMap )
799 if( pair.second.size() >= 4 )
805 ercItem->SetItems( pair.second[0], pair.second[1], pair.second[2], pair.second[3] );
807 wxString msg = wxString::Format(
_(
"Four items connected at %d, %d" ),
808 pair.first.x, pair.first.y );
809 ercItem->SetErrorMessage( msg );
811 ercItem->SetSheetSpecificPath( sheet );
814 sheet.LastScreen()->Append( marker );
829 std::map<VECTOR2I, std::vector<SCH_ITEM*>> pinMap;
834 if( pinMap.count( pt ) )
835 pinMap[pt].emplace_back( aOther );
845 pinMap[
pin->GetPosition()].emplace_back(
pin );
849 for(
SCH_ITEM* item : sheet.LastScreen()->Items() )
858 addOther(
pin->GetPosition(),
pin );
863 for(
const VECTOR2I& pt : item->GetConnectionPoints() )
864 addOther( pt, item );
868 for(
const std::pair<
const VECTOR2I, std::vector<SCH_ITEM*>>& pair : pinMap )
870 if( pair.second.size() > 1 )
898 ercItem->SetItems( pair.second[0], pair.second[1],
899 pair.second.size() > 2 ? pair.second[2] :
nullptr,
900 pair.second.size() > 3 ? pair.second[3] :
nullptr );
901 ercItem->SetErrorMessage(
_(
"Pin with 'no connection' type is connected" ) );
902 ercItem->SetSheetSpecificPath( sheet );
905 sheet.LastScreen()->Append( marker );
920 using iterator_t = std::vector<ERC_SCH_PIN_CONTEXT>::iterator;
921 std::vector<ERC_SCH_PIN_CONTEXT> pins;
922 std::unordered_map<EDA_ITEM*, SCH_SCREEN*> pinToScreenMap;
923 bool has_noconnect =
false;
928 has_noconnect =
true;
934 pins.emplace_back(
static_cast<SCH_PIN*
>( item ), subgraph->
GetSheet() );
940 std::sort( pins.begin(), pins.end(),
943 int ret = StrNumCmp( lhs.Pin()->GetParentSymbol()->GetRef( &lhs.Sheet() ),
944 rhs.Pin()->GetParentSymbol()->GetRef( &rhs.Sheet() ) );
947 ret = StrNumCmp( lhs.Pin()->GetNumber(), rhs.Pin()->GetNumber() );
957 bool hasDriver =
false;
958 std::vector<ERC_SCH_PIN_CONTEXT*> pinsNeedingDrivers;
959 std::vector<ERC_SCH_PIN_CONTEXT*> nonPowerPinsNeedingDrivers;
964 bool ispowerNet =
false;
975 std::vector<std::tuple<iterator_t, iterator_t, PIN_ERROR>> pin_mismatches;
976 std::map<iterator_t, int> pin_mismatch_counts;
978 for(
auto refIt = pins.begin(); refIt != pins.end(); ++refIt )
988 pinsNeedingDrivers.push_back( &refPin );
991 nonPowerPinsNeedingDrivers.push_back( &refPin );
993 if( !needsDriver.
Pin()
998 needsDriver = refPin;
999 needsDriverType = needsDriver.
Pin()->
GetType();
1008 for(
auto testIt = refIt + 1; testIt != pins.end(); ++testIt )
1029 pin_mismatches.emplace_back( std::tuple<iterator_t, iterator_t, PIN_ERROR>{ refIt, testIt,
erc } );
1033 pin_mismatch_counts[refIt] =
m_settings.GetPinTypeWeight( ( *refIt ).Pin()->GetType() );
1034 pin_mismatch_counts[testIt] =
m_settings.GetPinTypeWeight( ( *testIt ).Pin()->GetType() );
1038 if( !pin_mismatch_counts.contains( testIt ) )
1039 pin_mismatch_counts.emplace( testIt, 1 );
1041 pin_mismatch_counts[testIt]++;
1043 if( !pin_mismatch_counts.contains( refIt ) )
1044 pin_mismatch_counts.emplace( refIt, 1 );
1046 pin_mismatch_counts[refIt]++;
1052 std::multimap<size_t, iterator_t, std::greater<size_t>> pins_dsc;
1054 std::transform( pin_mismatch_counts.begin(), pin_mismatch_counts.end(),
1055 std::inserter( pins_dsc, pins_dsc.begin() ),
1058 return std::pair<size_t, iterator_t>( p.second, p.first );
1061 for(
const auto& [amount, pinItBind] : pins_dsc )
1063 auto& pinIt = pinItBind;
1065 if( pin_mismatches.empty() )
1071 iterator_t nearest_pin = pins.end();
1072 double smallest_distance = std::numeric_limits<double>::infinity();
1077 [&](
const auto& tuple )
1081 if( pinIt == std::get<0>( tuple ) )
1082 other = std::get<1>( tuple );
1083 else if( pinIt == std::get<1>( tuple ) )
1084 other = std::get<0>( tuple );
1088 if( ( *pinIt ).Sheet().Cmp( ( *other ).Sheet() ) != 0 )
1090 if( std::isinf( smallest_distance ) )
1092 nearest_pin = other;
1093 erc = std::get<2>( tuple );
1100 if( std::isinf( smallest_distance ) ||
distance < smallest_distance )
1103 nearest_pin = other;
1104 erc = std::get<2>( tuple );
1111 if( nearest_pin != pins.end() )
1113 SCH_PIN* other_pin = ( *nearest_pin ).Pin();
1117 ercItem->SetItems(
pin, other_pin );
1118 ercItem->SetSheetSpecificPath( ( *pinIt ).Sheet() );
1119 ercItem->SetItemsSheetPaths( ( *pinIt ).Sheet(), ( *nearest_pin ).Sheet() );
1121 ercItem->SetErrorMessage( wxString::Format(
_(
"Pins of type %s and %s are connected" ),
1126 pinToScreenMap[
pin]->Append( marker );
1131 if( needsDriver.
Pin() && !hasDriver && !has_noconnect )
1137 std::vector<ERC_SCH_PIN_CONTEXT*> pinsToMark;
1141 if( !nonPowerPinsNeedingDrivers.empty() )
1142 pinsToMark = nonPowerPinsNeedingDrivers;
1144 pinsToMark = pinsNeedingDrivers;
1148 if( !nonPowerPinsNeedingDrivers.empty() )
1149 pinsToMark.push_back( nonPowerPinsNeedingDrivers.front() );
1151 pinsToMark.push_back( &needsDriver );
1158 ercItem->SetItems( pinCtx->Pin() );
1159 ercItem->SetSheetSpecificPath( pinCtx->Sheet() );
1160 ercItem->SetItemsSheetPaths( pinCtx->Sheet() );
1163 pinToScreenMap[pinCtx->Pin()]->Append( marker );
1178 std::unordered_map<wxString, std::pair<wxString, SCH_PIN*>> pinToNetMap;
1182 const wxString& netName = net.first.Name;
1193 if( !
pin->GetParentSymbol()->IsMultiUnit() )
1196 wxString
name =
pin->GetParentSymbol()->GetRef( &sheet ) +
":" +
pin->GetShownNumber();
1198 if( !pinToNetMap.count(
name ) )
1200 pinToNetMap[
name] = std::make_pair( netName,
pin );
1202 else if( pinToNetMap[
name].first != netName )
1206 ercItem->SetErrorMessage( wxString::Format(
_(
"Pin %s is connected to both %s and %s" ),
1207 pin->GetShownNumber(),
1209 pinToNetMap[
name].first ) );
1211 ercItem->SetItems(
pin, pinToNetMap[
name].second );
1212 ercItem->SetSheetSpecificPath( sheet );
1213 ercItem->SetItemsSheetPaths( sheet, sheet );
1247 std::vector<SCH_PIN*> pins = symbol->
GetPins( &sheet );
1249 std::map<wxString, std::vector<std::pair<SCH_PIN*, wxString>>> pinsByNumber;
1254 wxString netName = conn ? conn->
GetNetName() : wxString();
1256 pinsByNumber[
pin->GetNumber()].emplace_back(
pin, netName );
1259 for(
const auto& [pinNumber, pinNetPairs] : pinsByNumber )
1261 if( pinNetPairs.size() < 2 )
1264 wxString firstNet = pinNetPairs[0].second;
1265 bool hasDifferentNets =
false;
1266 SCH_PIN* conflictPin =
nullptr;
1268 for(
size_t i = 1; i < pinNetPairs.size(); i++ )
1270 if( pinNetPairs[i].second != firstNet )
1272 hasDifferentNets =
true;
1273 conflictPin = pinNetPairs[i].first;
1278 if( hasDifferentNets )
1283 msg.Printf(
_(
"Pin %s on symbol '%s' is connected to different nets: %s and %s" ),
1285 symbol->
GetRef( &sheet ),
1286 firstNet.IsEmpty() ?
_(
"<no net>" ) : firstNet,
1287 pinNetPairs[1].second.IsEmpty() ?
_(
"<no net>" ) : pinNetPairs[1].second );
1289 ercItem->SetErrorMessage( msg );
1290 ercItem->SetItems( pinNetPairs[0].first, conflictPin );
1291 ercItem->SetSheetSpecificPath( sheet );
1292 ercItem->SetItemsSheetPaths( sheet, sheet );
1295 pinNetPairs[0].first->GetPosition() );
1296 screen->
Append( marker );
1312 [](
const wxString& txt )
1314 wxString upper = txt.Upper();
1315 return upper.Contains( wxT(
"GND" ) );
1325 bool hasGroundNet =
false;
1326 std::vector<SCH_PIN*> mismatched;
1331 wxString net = conn ? conn->
GetNetName() : wxString();
1332 bool netIsGround = isGround( net );
1342 hasGroundNet =
true;
1344 if( isGround(
pin->GetShownName() ) && !netIsGround )
1345 mismatched.push_back(
pin );
1354 ercItem->SetErrorMessage( wxString::Format(
_(
"Pin %s not connected to ground net" ),
1355 pin->GetShownName() ) );
1356 ercItem->SetItems(
pin );
1357 ercItem->SetSheetSpecificPath( sheet );
1358 ercItem->SetItemsSheetPaths( sheet );
1361 screen->
Append( marker );
1387 pin->GetStackedPinNumbers( &valid );
1392 ercItem->SetItems(
pin );
1393 ercItem->SetSheetSpecificPath( sheet );
1394 ercItem->SetItemsSheetPaths( sheet );
1397 screen->
Append( marker );
1412 std::unordered_map<wxString, std::pair<SCH_ITEM*, SCH_SHEET_PATH>> globalLabels;
1413 std::unordered_map<wxString, std::pair<SCH_ITEM*, SCH_SHEET_PATH>> localLabels;
1428 auto& map = item->Type() ==
SCH_LABEL_T ? localLabels : globalLabels;
1430 if( !map.count(
text ) )
1432 map[
text] = std::make_pair( label, sheet );
1439 for(
auto& [globalText, globalItem] : globalLabels )
1441 for(
auto& [localText, localItem] : localLabels )
1443 if( globalText == localText )
1446 ercItem->SetItems( globalItem.first, localItem.first );
1447 ercItem->SetSheetSpecificPath( globalItem.second );
1448 ercItem->SetItemsSheetPaths( globalItem.second, localItem.second );
1451 globalItem.second.LastScreen()->Append( marker );
1465 std::unordered_map<wxString, std::vector<std::tuple<wxString, SCH_ITEM*, SCH_SHEET_PATH>>> generalMap;
1469 const std::tuple<wxString, SCH_ITEM*, SCH_SHEET_PATH>& other )
1471 auto& [otherText, otherItem, otherSheet] = other;
1491 ercItem->SetItems( item, otherItem );
1492 ercItem->SetSheetSpecificPath( sheet );
1493 ercItem->SetItemsSheetPaths( sheet, otherSheet );
1496 sheet.LastScreen()->Append( marker );
1507 switch( item->Type() )
1514 wxString unnormalized = label->
GetShownText( &sheet,
false );
1515 wxString normalized = unnormalized.Lower();
1517 generalMap[normalized].emplace_back( std::make_tuple( unnormalized, label, sheet ) );
1519 for(
const auto& otherTuple : generalMap.at( normalized ) )
1521 const auto& [otherText, otherItem, otherSheet] = otherTuple;
1523 if( unnormalized != otherText )
1527 && sheet != otherSheet )
1532 logError( normalized, label, sheet, otherTuple );
1543 if( !
pin->IsPower() )
1547 wxString unnormalized = symbol->
GetValue(
true, &sheet,
false );
1548 wxString normalized = unnormalized.Lower();
1550 generalMap[normalized].emplace_back( std::make_tuple( unnormalized,
pin, sheet ) );
1552 for(
const auto& otherTuple : generalMap.at( normalized ) )
1554 const auto& [otherText, otherItem, otherSheet] = otherTuple;
1556 if( unnormalized != otherText )
1558 logError( normalized,
pin, sheet, otherTuple );
1588 std::vector<SCH_MARKER*> markers;
1595 if( !libSymbolInSchematic )
1600 std::optional<const LIBRARY_TABLE_ROW*> optRow =
1603 if( !optRow || ( *optRow )->Disabled() )
1608 ercItem->SetItems( symbol );
1609 msg.Printf(
_(
"The current configuration does not include the symbol library '%s'" ),
1611 ercItem->SetErrorMessage( msg );
1623 std::optional<wxString> uri =
1625 wxCHECK2( uri.has_value(), uri = wxEmptyString );
1626 ercItem->SetItems( symbol );
1627 msg.Printf(
_(
"The symbol library '%s' was not found at '%s'" ),
1629 ercItem->SetErrorMessage( msg );
1640 if( libSymbol ==
nullptr )
1645 ercItem->SetItems( symbol );
1646 msg.Printf(
_(
"Symbol '%s' not found in symbol library '%s'" ),
1649 ercItem->SetErrorMessage( msg );
1657 std::unique_ptr<LIB_SYMBOL> flattenedSymbol = libSymbol->
Flatten();
1666 std::vector<wxString> messages;
1674 if( messages.empty() && flattenedSymbol->Compare( *libSymbolInSchematic, flags ) != 0 )
1677 ercItem->SetItems( symbol );
1678 msg.Printf(
_(
"Symbol '%s' doesn't match copy in library '%s'" ),
1681 ercItem->SetErrorMessage( msg );
1690 screen->Append( marker );
1706 typedef int (*TESTER_FN_PTR)(
const wxString&,
PROJECT* );
1712 std::vector<SCH_MARKER*> markers;
1719 if( footprint.IsEmpty() )
1724 if( fpID.
Parse( footprint,
true ) >= 0 )
1727 msg.Printf(
_(
"'%s' is not a valid footprint identifier" ), footprint );
1728 ercItem->SetErrorMessage( msg );
1729 ercItem->SetItems( symbol );
1736 int ret = (linkTester)( footprint, aProject );
1741 msg.Printf(
_(
"The current configuration does not include the footprint library '%s'" ),
1743 ercItem->SetErrorMessage( msg );
1744 ercItem->SetItems( symbol );
1750 msg.Printf(
_(
"The footprint library '%s' is not enabled in the current configuration" ),
1752 ercItem->SetErrorMessage( msg );
1753 ercItem->SetItems( symbol );
1759 msg.Printf(
_(
"Footprint '%s' not found in library '%s'" ),
1762 ercItem->SetErrorMessage( msg );
1763 ercItem->SetItems( symbol );
1770 sheet.LastScreen()->Append( marker );
1788 std::vector<SCH_MARKER*> markers;
1793 std::unique_ptr<LIB_SYMBOL>& lib_symbol = sch_symbol->
GetLibSymbolRef();
1798 wxArrayString filters = lib_symbol->GetFPFilters();
1800 if( filters.empty() )
1806 if( footprint.
Parse( lowerId ) > 0 )
1812 for( wxString
filter : filters )
1817 if(
filter.Contains( wxS(
":" ) ) )
1818 found |= lowerId.Matches(
filter );
1820 found |= lowerItemName.Matches(
filter );
1829 msg.Printf(
_(
"Assigned footprint (%s) doesn't match footprint filters (%s)" ),
1831 wxJoin( filters,
' ' ) );
1832 ercItem->SetErrorMessage( msg );
1833 ercItem->SetItems( sch_symbol );
1840 sheet.LastScreen()->Append( marker );
1851 const int gridSize =
m_schematic->Settings().m_ConnectionGridSize;
1856 std::vector<SCH_MARKER*> markers;
1858 for(
SCH_ITEM* item : screen->Items() )
1860 if( item->Type() ==
SCH_LINE_T && item->IsConnectable() )
1868 ercItem->SetItems( line );
1876 ercItem->SetItems( line );
1887 if( ( point.x % gridSize ) != 0
1888 || ( point.y % gridSize ) != 0 )
1891 ercItem->SetItems( entry );
1893 markers.emplace_back(
new SCH_MARKER( std::move( ercItem ), point ) );
1908 if( ( pinPos.
x % gridSize ) != 0 || ( pinPos.
y % gridSize ) != 0 )
1911 ercItem->SetItems(
pin );
1913 markers.emplace_back(
new SCH_MARKER( std::move( ercItem ), pinPos ) );
1922 screen->Append( marker );
1936 wxString variant =
m_schematic->GetCurrentVariant();
1940 if( sheet.GetExcludedFromSim( variant ) )
1943 std::vector<SCH_MARKER*> markers;
1967 ercItem->SetErrorMessage( msg );
1968 ercItem->SetItems( symbol );
1976 sheet.LastScreen()->Append( marker );
1994 if( aProgressReporter )
1995 aProgressReporter->
AdvancePhase(
_(
"Checking sheet names..." ) );
2001 if( aProgressReporter )
2002 aProgressReporter->
AdvancePhase(
_(
"Checking conflicts..." ) );
2015 if( aProgressReporter )
2016 aProgressReporter->
AdvancePhase(
_(
"Checking units..." ) );
2021 if( aProgressReporter )
2022 aProgressReporter->
AdvancePhase(
_(
"Checking footprints..." ) );
2035 if( aProgressReporter )
2064 if( aProgressReporter )
2065 aProgressReporter->
AdvancePhase(
_(
"Checking similar labels..." ) );
2072 if( aProgressReporter )
2073 aProgressReporter->
AdvancePhase(
_(
"Checking local and global labels..." ) );
2080 if( aProgressReporter )
2081 aProgressReporter->
AdvancePhase(
_(
"Checking for unresolved variables..." ) );
2088 if( aProgressReporter )
2089 aProgressReporter->
AdvancePhase(
_(
"Checking SPICE models..." ) );
2096 if( aProgressReporter )
2097 aProgressReporter->
AdvancePhase(
_(
"Checking no connect pins for connections..." ) );
2105 if( aProgressReporter )
2106 aProgressReporter->
AdvancePhase(
_(
"Checking for library symbol issues..." ) );
2113 if( aProgressReporter )
2114 aProgressReporter->
AdvancePhase(
_(
"Checking for footprint link issues..." ) );
2121 if( aProgressReporter )
2122 aProgressReporter->
AdvancePhase(
_(
"Checking footprint assignments against footprint filters..." ) );
2129 if( aProgressReporter )
2130 aProgressReporter->
AdvancePhase(
_(
"Checking for off grid pins and wires..." ) );
2137 if( aProgressReporter )
2138 aProgressReporter->
AdvancePhase(
_(
"Checking for four way junctions..." ) );
2145 if( aProgressReporter )
2146 aProgressReporter->
AdvancePhase(
_(
"Checking for labels on more than one wire..." ) );
2153 if( aProgressReporter )
2154 aProgressReporter->
AdvancePhase(
_(
"Checking for undefined netclasses..." ) );
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 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 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 TestMultiunitFootprints()
Test if all units of each multiunit symbol have the same footprint assigned.
bool IsLibraryLoaded(const wxString &aNickname)
std::optional< wxString > GetFullURI(LIBRARY_TABLE_TYPE aType, const wxString &aNickname, bool aSubstituted=false) const
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) const
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.
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.
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
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 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.
virtual bool HasMessage() const
Returns true if any messages were reported.
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)
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.
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
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 & GetMessages() const
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_STACKED_PIN_SYNTAX
Pin name resembles stacked pin notation.
@ ERCE_ENDPOINT_OFF_GRID
Pin or wire-end off grid.
@ 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_FOOTPRINT_LINK_ISSUES
The footprint link is invalid, or points to a missing (or inactive) footprint or library.
@ 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_DUPLICATE_SHEET_NAME
Duplicate sheet names within a given sheet.
@ 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_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.
@ KIFACE_TEST_FOOTPRINT_LINK_LIBRARY_NOT_ENABLED
@ KIFACE_TEST_FOOTPRINT_LINK
@ KIFACE_TEST_FOOTPRINT_LINK_NO_LIBRARY
@ KIFACE_TEST_FOOTPRINT_LINK_NO_FOOTPRINT
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)
wxString UnescapeString(const wxString &aSource)
Implement a participant in the KIWAY alchemy.
virtual void * IfaceOrAddress(int aDataId)=0
Return pointer to the requested object.
VECTOR2< int32_t > VECTOR2I