81 _(
"Bidirectional Pin" ),
85 _(
"Unspecified Pin" ),
86 _(
"Power Input Pin" ),
87 _(
"Power Output Pin" ),
88 _(
"Open Collector" ),
98 _(
"Bidirectional Pin" ),
102 _(
"Unspecified Pin" ),
103 _(
"Power Input Pin" ),
104 _(
"Power Output Pin" ),
105 _(
"Open Collector" ),
147 std::vector<SCH_SHEET*> list;
150 list.push_back(
static_cast<SCH_SHEET*
>( item ) );
152 for(
size_t i = 0; i < list.size(); i++ )
156 for(
size_t j = i + 1; j < list.size(); j++ )
168 ercItem->SetItems( sheet, test_item );
171 screen->Append( marker );
189 [
this]( wxString str )
192 return str.Matches( wxS(
"*${*}*" ) );
199 static wxRegEx warningExpr( wxS(
"^\\$\\{ERC_WARNING\\s*([^}]*)\\}(.*)$" ) );
200 static wxRegEx errorExpr( wxS(
"^\\$\\{ERC_ERROR\\s*([^}]*)\\}(.*)$" ) );
202 if( warningExpr.Matches(
text ) )
205 wxString ercText = warningExpr.GetMatch(
text, 1 );
208 ercItem->SetItems( item );
210 ercText +=
_(
" (in drawing sheet)" );
212 ercItem->SetSheetSpecificPath( sheet );
213 ercItem->SetErrorMessage( ercText );
216 screen->Append( marker );
221 if( errorExpr.Matches(
text ) )
224 wxString ercText = errorExpr.GetMatch(
text, 1 );
227 ercItem->SetItems( item );
229 ercText +=
_(
" (in drawing sheet)" );
231 ercItem->SetSheetSpecificPath( sheet );
232 ercItem->SetErrorMessage( ercText );
235 screen->Append( marker );
266 if( unresolved( field.GetShownText( &sheet,
true ) ) )
269 ercItem->SetItems( symbol );
270 ercItem->SetSheetSpecificPath( sheet );
276 testAssertion( &field, sheet, screen, field.GetText(), field.
GetPosition() );
290 SCH_TEXT* textItem = static_cast<SCH_TEXT*>( child );
292 if( unresolved( textItem->GetShownText( &sheet, true ) ) )
294 auto ercItem = ERC_ITEM::Create( ERCE_UNRESOLVED_VARIABLE );
295 ercItem->SetItems( symbol );
296 ercItem->SetSheetSpecificPath( sheet );
298 BOX2I bbox = textItem->GetBoundingBox();
299 bbox = symbol->GetTransform().TransformCoordinate( bbox );
300 VECTOR2I pos = bbox.Centre() + symbol->GetPosition();
302 SCH_MARKER* marker = new SCH_MARKER( ercItem, pos );
303 screen->Append( marker );
306 testAssertion( symbol, sheet, screen, textItem->GetText(),
311 SCH_TEXTBOX* textboxItem = static_cast<SCH_TEXTBOX*>( child );
313 if( unresolved( textboxItem->GetShownText( &sheet, true ) ) )
315 auto ercItem = ERC_ITEM::Create( ERCE_UNRESOLVED_VARIABLE );
316 ercItem->SetItems( symbol );
317 ercItem->SetSheetSpecificPath( sheet );
319 BOX2I bbox = textboxItem->GetBoundingBox();
320 bbox = symbol->GetTransform().TransformCoordinate( bbox );
321 VECTOR2I pos = bbox.Centre() + symbol->GetPosition();
323 SCH_MARKER* marker = new SCH_MARKER( ercItem, pos );
324 screen->Append( marker );
327 testAssertion( symbol, sheet, screen, textboxItem->GetText(),
335 for(
SCH_FIELD& field : label->GetFields() )
337 if( unresolved( field.GetShownText( &sheet,
true ) ) )
340 ercItem->SetItems( label );
341 ercItem->SetSheetSpecificPath( sheet );
344 screen->Append( marker );
347 testAssertion( &field, sheet, screen, field.GetText(), field.GetPosition() );
356 if( unresolved( field.GetShownText( &sheet,
true ) ) )
359 ercItem->SetItems( subSheet );
360 ercItem->SetSheetSpecificPath( sheet );
363 screen->Append( marker );
366 testAssertion( &field, sheet, screen, field.GetText(), field.GetPosition() );
374 if(
pin->GetShownText( &subSheetPath,
true ).Matches( wxS(
"*${*}*" ) ) )
377 ercItem->SetItems(
pin );
378 ercItem->SetSheetSpecificPath( sheet );
381 screen->Append( marker );
387 if(
text->GetShownText( &sheet,
true ).Matches( wxS(
"*${*}*" ) ) )
390 ercItem->SetItems(
text );
391 ercItem->SetSheetSpecificPath( sheet );
394 screen->Append( marker );
397 testAssertion(
text, sheet, screen,
text->GetText(),
text->GetPosition() );
401 if( textBox->GetShownText( &sheet,
true ).Matches( wxS(
"*${*}*" ) ) )
404 ercItem->SetItems( textBox );
405 ercItem->SetSheetSpecificPath( sheet );
408 screen->Append( marker );
411 testAssertion( textBox, sheet, screen, textBox->GetText(), textBox->GetPosition() );
415 for(
DS_DRAW_ITEM_BASE* item = wsItems.GetFirst(); item; item = wsItems.GetNext() )
419 if( testAssertion(
nullptr, sheet, screen,
text->GetText(),
text->GetPosition() ) )
423 else if(
text->GetShownText(
true ).Matches( wxS(
"*${*}*" ) ) )
426 erc->SetErrorMessage(
_(
"Unresolved text variable in drawing sheet" ) );
427 erc->SetSheetSpecificPath( sheet );
430 screen->Append( marker );
442 std::vector<std::shared_ptr<BUS_ALIAS>> aliases;
446 const auto& screen_aliases = screen->GetBusAliases();
448 for(
const std::shared_ptr<BUS_ALIAS>& alias : screen_aliases )
450 std::vector<wxString> aliasMembers = alias->Members();
451 std::sort( aliasMembers.begin(), aliasMembers.end() );
453 for(
const std::shared_ptr<BUS_ALIAS>&
test : aliases )
455 std::vector<wxString> testMembers =
test->Members();
456 std::sort( testMembers.begin(), testMembers.end() );
458 if( alias->GetName() ==
test->GetName() && aliasMembers != testMembers )
460 msg.Printf(
_(
"Bus alias %s has conflicting definitions on %s and %s" ),
462 alias->GetParent()->GetFileName(),
463 test->GetParent()->GetFileName() );
466 ercItem->SetErrorMessage( msg );
469 test->GetParent()->Append( marker );
476 aliases.insert( aliases.end(), screen_aliases.begin(), screen_aliases.end() );
487 for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol :
m_refMap )
502 for(
size_t ii = 0; ii < refList.
GetCount(); ++ii )
507 if( !unitFP.IsEmpty() )
510 unitName = unit->
GetRef( &sheetPath,
true );
515 for(
size_t ii = 0; ii < refList.
GetCount(); ++ii )
523 if( unit && !secondFp.IsEmpty() && unitFP != secondFp )
525 msg.Printf(
_(
"Different footprints assigned to %s and %s" ),
526 unitName, secondName );
529 ercItem->SetErrorMessage( msg );
530 ercItem->SetItems( unit, secondUnit );
548 for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol :
m_refMap )
552 wxCHECK2( refList.
GetCount(),
continue );
562 std::set<int> lib_units;
563 std::set<int> instance_units;
564 std::set<int> missing_units;
567 [&]( std::set<int>& aMissingUnits,
const wxString& aErrorMsg,
int aErrorCode )
570 wxString missing_pin_units = wxS(
"[ " );
573 for(
int missing_unit : aMissingUnits )
577 missing_pin_units += wxS(
"....." );
584 missing_pin_units.Truncate( missing_pin_units.length() - 2 );
585 missing_pin_units += wxS(
" ]" );
587 msg.Printf( aErrorMsg, symbol.first, missing_pin_units );
590 ercItem->SetErrorMessage( msg );
591 ercItem->SetItems( unit );
592 ercItem->SetSheetSpecificPath( base_ref.
GetSheetPath() );
601 for(
int ii = 1; ii <= libSymbol->
GetUnitCount(); ++ii )
602 lib_units.insert( lib_units.end(), ii );
604 for(
size_t ii = 0; ii < refList.
GetCount(); ++ii )
605 instance_units.insert( instance_units.end(), refList.
GetItem( ii ).
GetUnit() );
607 std::set_difference( lib_units.begin(), lib_units.end(),
608 instance_units.begin(), instance_units.end(),
609 std::inserter( missing_units, missing_units.begin() ) );
616 std::set<int> missing_power;
617 std::set<int> missing_input;
618 std::set<int> missing_bidi;
620 for(
int missing_unit : missing_units )
624 for(
size_t ii = 0; ii < refList.
GetCount(); ++ii )
635 switch(
pin->GetType() )
637 case ELECTRICAL_PINTYPE::PT_POWER_IN:
638 missing_power.insert( missing_unit );
641 case ELECTRICAL_PINTYPE::PT_BIDI:
642 missing_bidi.insert( missing_unit );
645 case ELECTRICAL_PINTYPE::PT_INPUT:
646 missing_input.insert( missing_unit );
657 report( missing_power,
658 _(
"Symbol %s has input power pins in units %s that are not placed." ),
664 report( missing_input,
665 _(
"Symbol %s has input pins in units %s that are not placed." ),
671 report( missing_bidi,
672 _(
"Symbol %s has bidirectional pins in units %s that are not placed." ),
685 wxString defaultNetclass = settings->GetDefaultNetclass()->GetName();
694 ercItem->SetItems( item );
695 ercItem->SetErrorMessage( wxString::Format(
_(
"Netclass %s is not defined" ),
711 SCH_FIELD* field = static_cast<SCH_FIELD*>( aChild );
713 if( field->GetCanonicalName() == wxT(
"Netclass" ) )
715 wxString netclass = field->GetShownText( &sheet, false );
717 if( !netclass.IsSameAs( defaultNetclass )
718 && !settings->HasNetclass( netclass ) )
720 logError( sheet, item, netclass );
740 std::map<VECTOR2I, std::vector<SCH_ITEM*>> connMap;
747 connMap[pt].emplace_back( label );
750 for(
const std::pair<
const VECTOR2I, std::vector<SCH_ITEM*>>& pair : connMap )
752 std::vector<SCH_ITEM*> lines;
754 for(
SCH_ITEM* item : sheet.LastScreen()->Items().Overlapping(
SCH_LINE_T, pair.first ) )
763 lines.emplace_back( line );
766 if( lines.size() > 1 )
772 wxString msg = wxString::Format(
_(
"Label connects more than one wire at %d, %d" ),
773 pair.first.x, pair.first.y );
775 ercItem->SetItems( pair.second.front(), lines[0], lines[1], lines[2] );
776 ercItem->SetErrorMessage( msg );
777 ercItem->SetSheetSpecificPath( sheet );
780 sheet.LastScreen()->Append( marker );
795 std::map<VECTOR2I, std::vector<SCH_ITEM*>> connMap;
803 connMap[
pin->GetPosition()].emplace_back(
pin );
814 connMap[pt].emplace_back( line );
817 for(
const std::pair<
const VECTOR2I, std::vector<SCH_ITEM*>>& pair : connMap )
819 if( pair.second.size() >= 4 )
825 ercItem->SetItems( pair.second[0], pair.second[1], pair.second[2], pair.second[3] );
827 wxString msg = wxString::Format(
_(
"Four items connected at %d, %d" ),
828 pair.first.x, pair.first.y );
829 ercItem->SetErrorMessage( msg );
831 ercItem->SetSheetSpecificPath( sheet );
834 sheet.LastScreen()->Append( marker );
849 std::map<VECTOR2I, std::vector<SCH_ITEM*>> pinMap;
854 if( pinMap.count( pt ) )
855 pinMap[pt].emplace_back( aOther );
864 if(
pin->GetLibPin()->GetType() == ELECTRICAL_PINTYPE::PT_NC )
865 pinMap[
pin->GetPosition()].emplace_back(
pin );
869 for(
SCH_ITEM* item : sheet.LastScreen()->Items() )
877 if(
pin->GetLibPin()->GetType() != ELECTRICAL_PINTYPE::PT_NC )
878 addOther(
pin->GetPosition(),
pin );
881 else if( item->IsConnectable() )
883 for(
const VECTOR2I& pt : item->GetConnectionPoints() )
884 addOther( pt, item );
888 for(
const std::pair<
const VECTOR2I, std::vector<SCH_ITEM*>>& pair : pinMap )
890 if( pair.second.size() > 1 )
896 ercItem->SetItems( pair.second[0], pair.second[1],
897 pair.second.size() > 2 ? pair.second[2] :
nullptr,
898 pair.second.size() > 3 ? pair.second[3] :
nullptr );
899 ercItem->SetErrorMessage(
_(
"Pin with 'no connection' type is connected" ) );
900 ercItem->SetSheetSpecificPath( sheet );
903 sheet.LastScreen()->Append( marker );
918 using iterator_t = std::vector<ERC_SCH_PIN_CONTEXT>::iterator;
919 std::vector<ERC_SCH_PIN_CONTEXT> pins;
920 std::unordered_map<EDA_ITEM*, SCH_SCREEN*> pinToScreenMap;
921 bool has_noconnect =
false;
926 has_noconnect =
true;
932 pins.emplace_back(
static_cast<SCH_PIN*
>( item ), subgraph->
GetSheet() );
938 std::sort( pins.begin(), pins.end(),
941 int ret = StrNumCmp( lhs.Pin()->GetParentSymbol()->GetRef( &lhs.Sheet() ),
942 rhs.Pin()->GetParentSymbol()->GetRef( &rhs.Sheet() ) );
945 ret = StrNumCmp( lhs.Pin()->GetNumber(), rhs.Pin()->GetNumber() );
955 bool hasDriver =
false;
960 bool ispowerNet =
false;
964 if( refPin.Pin()->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN )
971 std::vector<std::tuple<iterator_t, iterator_t, PIN_ERROR>> pin_mismatches;
972 std::map<iterator_t, int> pin_mismatch_counts;
974 for(
auto refIt = pins.begin(); refIt != pins.end(); ++refIt )
984 if( !needsDriver.
Pin()
986 || ( ispowerNet != ( needsDriverType == ELECTRICAL_PINTYPE::PT_POWER_IN )
987 && ispowerNet == ( refType == ELECTRICAL_PINTYPE::PT_POWER_IN ) ) )
989 needsDriver = refPin;
990 needsDriverType = needsDriver.
Pin()->
GetType();
999 for(
auto testIt = refIt + 1; testIt != pins.end(); ++testIt )
1020 pin_mismatches.emplace_back(
1021 std::tuple<iterator_t, iterator_t, PIN_ERROR>{ refIt, testIt,
erc } );
1025 pin_mismatch_counts[refIt] =
1028 pin_mismatch_counts[testIt] =
1033 if( !pin_mismatch_counts.contains( testIt ) )
1034 pin_mismatch_counts.emplace( testIt, 1 );
1036 pin_mismatch_counts[testIt]++;
1038 if( !pin_mismatch_counts.contains( refIt ) )
1039 pin_mismatch_counts.emplace( refIt, 1 );
1041 pin_mismatch_counts[refIt]++;
1047 std::multimap<size_t, iterator_t, std::greater<size_t>> pins_dsc;
1049 std::transform( pin_mismatch_counts.begin(), pin_mismatch_counts.end(),
1050 std::inserter( pins_dsc, pins_dsc.begin() ),
1053 return std::pair<size_t, iterator_t>( p.second, p.first );
1056 for(
const auto& [amount, pinItBind] : pins_dsc )
1058 auto& pinIt = pinItBind;
1060 if( pin_mismatches.empty() )
1066 iterator_t nearest_pin = pins.end();
1067 double smallest_distance = std::numeric_limits<double>::infinity();
1072 [&](
const auto& tuple )
1076 if( pinIt == std::get<0>( tuple ) )
1077 other = std::get<1>( tuple );
1078 else if( pinIt == std::get<1>( tuple ) )
1079 other = std::get<0>( tuple );
1083 if( ( *pinIt ).Sheet().Cmp( ( *other ).Sheet() ) != 0 )
1085 if( std::isinf( smallest_distance ) )
1087 nearest_pin = other;
1088 erc = std::get<2>( tuple );
1095 if( std::isinf( smallest_distance ) ||
distance < smallest_distance )
1097 smallest_distance = distance;
1098 nearest_pin = other;
1099 erc = std::get<2>( tuple );
1106 if( nearest_pin != pins.end() )
1108 SCH_PIN* other_pin = ( *nearest_pin ).Pin();
1110 std::shared_ptr<ERC_ITEM> ercItem =
1113 ercItem->SetItems(
pin, other_pin );
1114 ercItem->SetSheetSpecificPath( ( *pinIt ).Sheet() );
1115 ercItem->SetItemsSheetPaths( ( *pinIt ).Sheet(), ( *nearest_pin ).Sheet() );
1117 ercItem->SetErrorMessage(
1118 wxString::Format(
_(
"Pins of type %s and %s are connected" ),
1123 pinToScreenMap[
pin]->Append( marker );
1128 if( needsDriver.Pin() && !hasDriver && !has_noconnect )
1136 ercItem->SetItems( needsDriver.Pin() );
1137 ercItem->SetSheetSpecificPath( needsDriver.Sheet() );
1138 ercItem->SetItemsSheetPaths( needsDriver.Sheet() );
1141 pinToScreenMap[needsDriver.Pin()]->Append( marker );
1155 std::unordered_map<wxString, std::pair<wxString, SCH_PIN*>> pinToNetMap;
1159 const wxString& netName = net.first.Name;
1170 if( !
pin->GetLibPin()->GetParentSymbol()->IsMulti() )
1173 wxString
name =
pin->GetParentSymbol()->GetRef( &sheet ) +
1174 +
":" +
pin->GetShownNumber();
1176 if( !pinToNetMap.count(
name ) )
1178 pinToNetMap[
name] = std::make_pair( netName,
pin );
1180 else if( pinToNetMap[
name].first != netName )
1182 std::shared_ptr<ERC_ITEM> ercItem =
1185 ercItem->SetErrorMessage( wxString::Format(
1186 _(
"Pin %s is connected to both %s and %s" ),
1187 pin->GetShownNumber(),
1189 pinToNetMap[
name].first ) );
1191 ercItem->SetItems(
pin, pinToNetMap[
name].second );
1192 ercItem->SetSheetSpecificPath( sheet );
1193 ercItem->SetItemsSheetPaths( sheet, sheet );
1212 std::unordered_map<wxString, std::pair<SCH_ITEM*, SCH_SHEET_PATH>> globalLabels;
1213 std::unordered_map<wxString, std::pair<SCH_ITEM*, SCH_SHEET_PATH>> localLabels;
1228 auto& map = item->Type() ==
SCH_LABEL_T ? localLabels : globalLabels;
1230 if( !map.count(
text ) )
1232 map[
text] = std::make_pair( label, sheet );
1239 for(
auto& [globalText, globalItem] : globalLabels )
1241 for(
auto& [localText, localItem] : localLabels )
1243 if( globalText == localText )
1245 std::shared_ptr<ERC_ITEM> ercItem =
1247 ercItem->SetItems( globalItem.first, localItem.first );
1248 ercItem->SetSheetSpecificPath( globalItem.second );
1249 ercItem->SetItemsSheetPaths( globalItem.second, localItem.second );
1252 globalItem.second.LastScreen()->Append( marker );
1266 std::unordered_map<wxString, std::vector<std::tuple<wxString, SCH_ITEM*, SCH_SHEET_PATH>>> generalMap;
1269 const std::tuple<wxString, SCH_ITEM*, SCH_SHEET_PATH>& other )
1271 auto& [otherText, otherItem, otherSheet] = other;
1291 ercItem->SetItems( item, otherItem );
1292 ercItem->SetSheetSpecificPath( sheet );
1293 ercItem->SetItemsSheetPaths( sheet, otherSheet );
1296 sheet.LastScreen()->Append( marker );
1307 switch( item->Type() )
1314 wxString unnormalized = label->
GetShownText( &sheet,
false );
1315 wxString normalized = unnormalized.Lower();
1317 generalMap[normalized].emplace_back( std::make_tuple( unnormalized, label, sheet ) );
1319 for(
const auto& otherTuple : generalMap.at( normalized ) )
1321 const auto& [otherText, otherItem, otherSheet] = otherTuple;
1323 if( unnormalized != otherText )
1325 logError( normalized, label, sheet, otherTuple );
1336 if( !
pin->IsGlobalPower() )
1342 wxString unnormalized = symbol->
GetValue(
true, &sheet,
false );
1343 wxString normalized = unnormalized.Lower();
1345 generalMap[normalized].emplace_back( std::make_tuple( unnormalized,
pin, sheet ) );
1347 for(
const auto& otherTuple : generalMap.at( normalized ) )
1349 const auto& [otherText, otherItem, otherSheet] = otherTuple;
1351 if( unnormalized != otherText )
1353 logError( normalized,
pin, sheet, otherTuple );
1381 std::vector<SCH_MARKER*> markers;
1388 wxCHECK2( libSymbolInSchematic,
continue );
1398 ercItem->SetItems( symbol );
1399 msg.Printf(
_(
"The current configuration does not include the symbol library '%s'" ),
1401 ercItem->SetErrorMessage( msg );
1408 else if( !libTable->
HasLibrary( libName,
true ) )
1413 ercItem->SetItems( symbol );
1414 msg.Printf(
_(
"The library '%s' is not enabled in the current configuration" ),
1416 ercItem->SetErrorMessage( msg );
1427 if( libSymbol ==
nullptr )
1432 ercItem->SetItems( symbol );
1433 msg.Printf(
_(
"Symbol '%s' not found in symbol library '%s'" ),
1436 ercItem->SetErrorMessage( msg );
1444 std::unique_ptr<LIB_SYMBOL> flattenedSymbol = libSymbol->
Flatten();
1450 std::vector<wxString> messages;
1454 if( !messages.empty() )
1457 ercItem->SetItems( symbol );
1458 msg.Printf(
_(
"Symbol '%s' has multiple pins with the same pin number" ),
1460 ercItem->SetErrorMessage( msg );
1464 else if( flattenedSymbol->Compare( *libSymbolInSchematic, flags ) != 0 )
1467 ercItem->SetItems( symbol );
1468 msg.Printf(
_(
"Symbol '%s' doesn't match copy in library '%s'" ),
1471 ercItem->SetErrorMessage( msg );
1480 screen->Append( marker );
1496 typedef int (*TESTER_FN_PTR)(
const wxString&,
PROJECT* );
1502 std::vector<SCH_MARKER*> markers;
1509 if( footprint.IsEmpty() )
1514 if( fpID.
Parse( footprint,
true ) >= 0 )
1517 msg.Printf(
_(
"'%s' is not a valid footprint identifier." ), footprint );
1518 ercItem->SetErrorMessage( msg );
1519 ercItem->SetItems( symbol );
1526 int ret = (linkTester)( footprint, aProject );
1531 msg.Printf(
_(
"The current configuration does not include the footprint library '%s'." ),
1533 ercItem->SetErrorMessage( msg );
1534 ercItem->SetItems( symbol );
1540 msg.Printf(
_(
"The footprint library '%s' is not enabled in the current configuration." ),
1542 ercItem->SetErrorMessage( msg );
1543 ercItem->SetItems( symbol );
1549 msg.Printf(
_(
"Footprint '%s' not found in library '%s'." ),
1552 ercItem->SetErrorMessage( msg );
1553 ercItem->SetItems( symbol );
1560 sheet.LastScreen()->Append( marker );
1578 std::vector<SCH_MARKER*> markers;
1583 std::unique_ptr<LIB_SYMBOL>& lib_symbol = sch_symbol->
GetLibSymbolRef();
1588 wxArrayString filters = lib_symbol->GetFPFilters();
1590 if( filters.empty() )
1596 if( footprint.
Parse( lowerId ) > 0 )
1602 for( wxString
filter : filters )
1607 if(
filter.Contains( wxS(
":" ) ) )
1608 found |= lowerId.Matches(
filter );
1610 found |= lowerItemName.Matches(
filter );
1619 msg.Printf(
_(
"Assigned footprint (%s) doesn't match footprint filters (%s)." ),
1621 wxJoin( filters,
' ' ) );
1622 ercItem->SetErrorMessage( msg );
1623 ercItem->SetItems( sch_symbol );
1630 sheet.LastScreen()->Append( marker );
1646 std::vector<SCH_MARKER*> markers;
1648 for(
SCH_ITEM* item : screen->Items() )
1650 if( item->Type() ==
SCH_LINE_T && item->IsConnectable() )
1658 ercItem->SetItems( line );
1666 ercItem->SetItems( line );
1677 if( ( point.x % gridSize ) != 0
1678 || ( point.y % gridSize ) != 0 )
1681 ercItem->SetItems( entry );
1683 markers.emplace_back(
new SCH_MARKER( ercItem, point ) );
1695 if( ( pinPos.
x % gridSize ) != 0 || ( pinPos.
y % gridSize ) != 0 )
1698 ercItem->SetItems(
pin );
1700 markers.emplace_back(
new SCH_MARKER( ercItem, pinPos ) );
1709 screen->Append( marker );
1726 if( sheet.GetExcludedFromSim() )
1729 std::vector<SCH_MARKER*> markers;
1753 ercItem->SetErrorMessage( msg );
1754 ercItem->SetItems( symbol );
1762 sheet.LastScreen()->Append( marker );
1780 if( aProgressReporter )
1781 aProgressReporter->
AdvancePhase(
_(
"Checking sheet names..." ) );
1788 if( aProgressReporter )
1789 aProgressReporter->
AdvancePhase(
_(
"Checking bus conflicts..." ) );
1795 if( aProgressReporter )
1796 aProgressReporter->
AdvancePhase(
_(
"Checking conflicts..." ) );
1809 if( aProgressReporter )
1810 aProgressReporter->
AdvancePhase(
_(
"Checking units..." ) );
1815 if( aProgressReporter )
1816 aProgressReporter->
AdvancePhase(
_(
"Checking footprints..." ) );
1829 if( aProgressReporter )
1849 if( aProgressReporter )
1850 aProgressReporter->
AdvancePhase(
_(
"Checking similar labels..." ) );
1857 if( aProgressReporter )
1858 aProgressReporter->
AdvancePhase(
_(
"Checking local and global labels..." ) );
1865 if( aProgressReporter )
1866 aProgressReporter->
AdvancePhase(
_(
"Checking for unresolved variables..." ) );
1873 if( aProgressReporter )
1874 aProgressReporter->
AdvancePhase(
_(
"Checking SPICE models..." ) );
1881 if( aProgressReporter )
1882 aProgressReporter->
AdvancePhase(
_(
"Checking no connect pins for connections..." ) );
1890 if( aProgressReporter )
1891 aProgressReporter->
AdvancePhase(
_(
"Checking for library symbol issues..." ) );
1898 if( aProgressReporter )
1899 aProgressReporter->
AdvancePhase(
_(
"Checking for footprint link issues..." ) );
1906 if( aProgressReporter )
1907 aProgressReporter->
AdvancePhase(
_(
"Checking footprint assignments against footprint filters..." ) );
1914 if( aProgressReporter )
1915 aProgressReporter->
AdvancePhase(
_(
"Checking for off grid pins and wires..." ) );
1922 if( aProgressReporter )
1923 aProgressReporter->
AdvancePhase(
_(
"Checking for four way junctions..." ) );
1930 if( aProgressReporter )
1931 aProgressReporter->
AdvancePhase(
_(
"Checking for labels on more than one wire..." ) );
1938 if( aProgressReporter )
1939 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.
int RunERC()
Run electrical rule checks on the connectivity graph.
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...
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.
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.
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.
bool IsTestEnabled(int aErrorCode) const
ERC_PIN_SORTING_METRIC GetERCSortingMetric() const
Get the type of sorting metric the ERC checker should use to resolve multi-pin errors.
PIN_ERROR GetPinMapValue(int aFirstType, int aSecondType) const
int GetPinTypeWeight(ELECTRICAL_PINTYPE aPinType) const
Get the weight for an electrical pin type.
int TestLibSymbolIssues()
Test symbols for changed library symbols and broken symbol library links.
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 TestConflictingBusAliases()
Check that there are no conflicting bus alias definitions in the schematic.
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.
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
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.
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< SCH_PIN * > GetPins(int aUnit, int aBodyStyle) const
Return a list of pin object pointers from the draw item list.
wxString GetUnitDisplayName(int aUnit) override
Return the user-defined display name for aUnit for symbols with units.
int GetUnitCount() const override
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
Hold a record identifying a library accessed by the appropriate plug in object in the LIB_TABLE.
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library table.
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.
std::shared_ptr< NET_SETTINGS > & NetSettings()
static SYMBOL_LIB_TABLE * SchSymbolLibTable(PROJECT *aProject)
Accessor for project symbol library table.
Container for project specific data.
virtual PROJECT_FILE & GetProjectFile() const
void ResolveERCExclusionsPostUpdate()
Update markers to match recorded exclusions.
SCHEMATIC_SETTINGS & Settings() const
CONNECTION_GRAPH * ConnectionGraph() const override
PROJECT & Prj() const override
Return a reference to the project this schematic is part of.
std::vector< VECTOR2I > GetConnectionPoints() const override
Add all the connection points for this item to aPoints.
Class for a wire to bus entry.
Schematic editor (Eeschema) main window.
void RecalculateConnections(SCH_COMMIT *aCommit, SCH_CLEANUP_FLAGS aCleanupFlags)
Generate the connection data for the entire schematic hierarchy.
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Base class for any item which can be embedded within the SCHEMATIC container class,...
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
bool IsGraphicLine() const
Return if the line is a graphic (non electrical line)
bool IsStacked(const SCH_PIN *aPin) const
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()
Gets the full RTree, usually for iterating.
void AnnotatePowerSymbols()
Silently annotate the not yet annotated power symbols of the entire hierarchy of the sheet path list.
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()
VECTOR2I GetPosition() const override
std::vector< SCH_SHEET_PIN * > & GetPins()
wxString GetShownName(bool aAllowExtraText) const
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly) override
Populate a std::vector with SCH_FIELDs.
const wxString GetValue(bool aResolve, const SCH_SHEET_PATH *aPath, bool aAllowExtraText) const override
const wxString GetFootprintFieldText(bool aResolve, const SCH_SHEET_PATH *aPath, bool aAllowExtraText) const
VECTOR2I GetPosition() const override
std::vector< SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet) const
Retrieve a list of the SCH_PINs for the given sheet path.
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
SIM_MODEL & CreateModel(SIM_MODEL::TYPE aType, const std::vector< SCH_PIN * > &aPins, REPORTER &aReporter)
SYMBOL_LIB_TABLE_ROW * FindRow(const wxString &aNickName, bool aCheckIfEnabled=false)
Return an SYMBOL_LIB_TABLE_ROW if aNickName is found in this table or in any chained fallBack table f...
bool GetExcludedFromSim() const override
double Distance(const VECTOR2< extended_type > &aVector) const
Compute the distance between two vectors.
A wrapper for reporting to a wxString object.
bool HasMessage() const override
Returns true if the reporter client is non-empty.
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_SIMILAR_LABELS
2 labels are equal for case insensitive comparisons.
@ 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_BUS_ALIAS_CONFLICT
Conflicting bus alias definitions across sheets.
@ 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
wxString ElectricalPinTypeGetText(ELECTRICAL_PINTYPE aType)
ELECTRICAL_PINTYPE
The symbol library pin object electrical types used in ERC tests.
@ PT_INPUT
usual pin input: must be connected
@ PT_TRISTATE
tris 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_PASSIVE
pin for passive symbols: must be connected, and can be connected to any pin
static float distance(const SFVEC2UI &a, const SFVEC2UI &b)
LIB_SYMBOL * SchGetLibSymbol(const LIB_ID &aLibId, SYMBOL_LIB_TABLE *aLibTable, SYMBOL_LIB *aCacheLib, wxWindow *aParent, bool aShowErrorMsg)
Load symbol from symbol library table.
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