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( std::move( 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( nullptr, &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( std::move( ercItem ), pos );
324 screen->Append( marker );
327 testAssertion( symbol, sheet, screen, textboxItem->GetText(),
331 RECURSE_MODE::NO_RECURSE );
336 for(
SCH_FIELD& field : label->GetFields() )
338 if( unresolved( field.GetShownText( &sheet,
true ) ) )
341 ercItem->SetItems( label );
342 ercItem->SetSheetSpecificPath( sheet );
345 screen->Append( marker );
348 testAssertion( &field, sheet, screen, field.GetText(), field.GetPosition() );
357 if( unresolved( field.GetShownText( &sheet,
true ) ) )
360 ercItem->SetItems( subSheet );
361 ercItem->SetSheetSpecificPath( sheet );
364 screen->Append( marker );
367 testAssertion( &field, sheet, screen, field.GetText(), field.GetPosition() );
375 if(
pin->GetShownText( &subSheetPath,
true ).Matches( wxS(
"*${*}*" ) ) )
378 ercItem->SetItems(
pin );
379 ercItem->SetSheetSpecificPath( sheet );
382 screen->Append( marker );
388 if(
text->GetShownText( &sheet,
true ).Matches( wxS(
"*${*}*" ) ) )
391 ercItem->SetItems(
text );
392 ercItem->SetSheetSpecificPath( sheet );
395 screen->Append( marker );
398 testAssertion(
text, sheet, screen,
text->GetText(),
text->GetPosition() );
402 if( textBox->GetShownText(
nullptr, &sheet,
true ).Matches( wxS(
"*${*}*" ) ) )
405 ercItem->SetItems( textBox );
406 ercItem->SetSheetSpecificPath( sheet );
409 screen->Append( marker );
412 testAssertion( textBox, sheet, screen, textBox->GetText(), textBox->GetPosition() );
416 for(
DS_DRAW_ITEM_BASE* item = wsItems.GetFirst(); item; item = wsItems.GetNext() )
420 if( testAssertion(
nullptr, sheet, screen,
text->GetText(),
text->GetPosition() ) )
424 else if(
text->GetShownText(
true ).Matches( wxS(
"*${*}*" ) ) )
427 ercItem->SetErrorMessage(
_(
"Unresolved text variable in drawing sheet" ) );
428 ercItem->SetSheetSpecificPath( sheet );
431 screen->Append( marker );
443 std::vector<std::shared_ptr<BUS_ALIAS>> aliases;
447 const auto& screen_aliases = screen->GetBusAliases();
449 for(
const std::shared_ptr<BUS_ALIAS>& alias : screen_aliases )
451 std::vector<wxString> aliasMembers = alias->Members();
452 std::sort( aliasMembers.begin(), aliasMembers.end() );
454 for(
const std::shared_ptr<BUS_ALIAS>&
test : aliases )
456 std::vector<wxString> testMembers =
test->Members();
457 std::sort( testMembers.begin(), testMembers.end() );
459 if( alias->GetName() ==
test->GetName() && aliasMembers != testMembers )
461 msg.Printf(
_(
"Bus alias %s has conflicting definitions on %s and %s" ),
463 alias->GetParent()->GetFileName(),
464 test->GetParent()->GetFileName() );
467 ercItem->SetErrorMessage( msg );
470 test->GetParent()->Append( marker );
477 aliases.insert( aliases.end(), screen_aliases.begin(), screen_aliases.end() );
488 for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol :
m_refMap )
503 for(
size_t ii = 0; ii < refList.
GetCount(); ++ii )
508 if( !unitFP.IsEmpty() )
511 unitName = unit->
GetRef( &sheetPath,
true );
516 for(
size_t ii = 0; ii < refList.
GetCount(); ++ii )
524 if( unit && !secondFp.IsEmpty() && unitFP != secondFp )
526 msg.Printf(
_(
"Different footprints assigned to %s and %s" ),
527 unitName, secondName );
530 ercItem->SetErrorMessage( msg );
531 ercItem->SetItems( unit, secondUnit );
549 for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol :
m_refMap )
553 wxCHECK2( refList.
GetCount(),
continue );
563 std::set<int> lib_units;
564 std::set<int> instance_units;
565 std::set<int> missing_units;
568 [&]( std::set<int>& aMissingUnits,
const wxString& aErrorMsg,
int aErrorCode )
571 wxString missing_pin_units = wxS(
"[ " );
574 for(
int missing_unit : aMissingUnits )
578 missing_pin_units += wxS(
"....." );
585 missing_pin_units.Truncate( missing_pin_units.length() - 2 );
586 missing_pin_units += wxS(
" ]" );
588 msg.Printf( aErrorMsg, symbol.first, missing_pin_units );
591 ercItem->SetErrorMessage( msg );
592 ercItem->SetItems( unit );
593 ercItem->SetSheetSpecificPath( base_ref.
GetSheetPath() );
602 for(
int ii = 1; ii <= libSymbol->
GetUnitCount(); ++ii )
603 lib_units.insert( lib_units.end(), ii );
605 for(
size_t ii = 0; ii < refList.
GetCount(); ++ii )
606 instance_units.insert( instance_units.end(), refList.
GetItem( ii ).
GetUnit() );
608 std::set_difference( lib_units.begin(), lib_units.end(),
609 instance_units.begin(), instance_units.end(),
610 std::inserter( missing_units, missing_units.begin() ) );
617 std::set<int> missing_power;
618 std::set<int> missing_input;
619 std::set<int> missing_bidi;
621 for(
int missing_unit : missing_units )
625 for(
size_t ii = 0; ii < refList.
GetCount(); ++ii )
636 switch(
pin->GetType() )
638 case ELECTRICAL_PINTYPE::PT_POWER_IN:
639 missing_power.insert( missing_unit );
642 case ELECTRICAL_PINTYPE::PT_BIDI:
643 missing_bidi.insert( missing_unit );
646 case ELECTRICAL_PINTYPE::PT_INPUT:
647 missing_input.insert( missing_unit );
658 report( missing_power,
659 _(
"Symbol %s has input power pins in units %s that are not placed." ),
665 report( missing_input,
666 _(
"Symbol %s has input pins in units %s that are not placed." ),
672 report( missing_bidi,
673 _(
"Symbol %s has bidirectional pins in units %s that are not placed." ),
686 wxString defaultNetclass = settings->GetDefaultNetclass()->GetName();
695 ercItem->SetItems( item );
696 ercItem->SetErrorMessage( wxString::Format(
_(
"Netclass %s is not defined" ),
712 SCH_FIELD* field = static_cast<SCH_FIELD*>( aChild );
714 if( field->GetCanonicalName() == wxT(
"Netclass" ) )
716 wxString netclass = field->GetShownText( &sheet, false );
718 if( !netclass.IsSameAs( defaultNetclass )
719 && !settings->HasNetclass( netclass ) )
721 logError( sheet, item, netclass );
728 RECURSE_MODE::NO_RECURSE );
742 std::map<VECTOR2I, std::vector<SCH_ITEM*>> connMap;
749 connMap[pt].emplace_back( label );
752 for(
const std::pair<
const VECTOR2I, std::vector<SCH_ITEM*>>& pair : connMap )
754 std::vector<SCH_ITEM*> lines;
756 for(
SCH_ITEM* item : sheet.LastScreen()->Items().Overlapping(
SCH_LINE_T, pair.first ) )
765 lines.emplace_back( line );
768 if( lines.size() > 1 )
774 wxString msg = wxString::Format(
_(
"Label connects more than one wire at %d, %d" ),
775 pair.first.x, pair.first.y );
777 ercItem->SetItems( pair.second.front(), lines[0], lines[1], lines[2] );
778 ercItem->SetErrorMessage( msg );
779 ercItem->SetSheetSpecificPath( sheet );
782 sheet.LastScreen()->Append( marker );
795 auto pinStackAlreadyRepresented =
796 [](
SCH_PIN*
pin, std::vector<SCH_ITEM*>& collection ) ->
bool
800 if( item->Type() ==
SCH_PIN_T && item->GetParentSymbol() ==
pin->GetParentSymbol() )
802 if(
pin->IsVisible() && !
static_cast<SCH_PIN*
>( item )->IsVisible() )
814 std::map<VECTOR2I, std::vector<SCH_ITEM*>> connMap;
823 std::vector<SCH_ITEM*>& entry = connMap[
pin->GetPosition()];
826 if( pinStackAlreadyRepresented(
pin, entry ) )
829 entry.emplace_back(
pin );
841 connMap[pt].emplace_back( line );
844 for(
const std::pair<
const VECTOR2I, std::vector<SCH_ITEM*>>& pair : connMap )
846 if( pair.second.size() >= 4 )
852 ercItem->SetItems( pair.second[0], pair.second[1], pair.second[2], pair.second[3] );
854 wxString msg = wxString::Format(
_(
"Four items connected at %d, %d" ),
855 pair.first.x, pair.first.y );
856 ercItem->SetErrorMessage( msg );
858 ercItem->SetSheetSpecificPath( sheet );
861 sheet.LastScreen()->Append( marker );
876 std::map<VECTOR2I, std::vector<SCH_ITEM*>> pinMap;
881 if( pinMap.count( pt ) )
882 pinMap[pt].emplace_back( aOther );
891 if(
pin->GetLibPin()->GetType() == ELECTRICAL_PINTYPE::PT_NC )
892 pinMap[
pin->GetPosition()].emplace_back(
pin );
896 for(
SCH_ITEM* item : sheet.LastScreen()->Items() )
904 if(
pin->GetLibPin()->GetType() != ELECTRICAL_PINTYPE::PT_NC )
905 addOther(
pin->GetPosition(),
pin );
910 for(
const VECTOR2I& pt : item->GetConnectionPoints() )
911 addOther( pt, item );
915 for(
const std::pair<
const VECTOR2I, std::vector<SCH_ITEM*>>& pair : pinMap )
917 if( pair.second.size() > 1 )
923 ercItem->SetItems( pair.second[0], pair.second[1],
924 pair.second.size() > 2 ? pair.second[2] :
nullptr,
925 pair.second.size() > 3 ? pair.second[3] :
nullptr );
926 ercItem->SetErrorMessage(
_(
"Pin with 'no connection' type is connected" ) );
927 ercItem->SetSheetSpecificPath( sheet );
930 sheet.LastScreen()->Append( marker );
945 using iterator_t = std::vector<ERC_SCH_PIN_CONTEXT>::iterator;
946 std::vector<ERC_SCH_PIN_CONTEXT> pins;
947 std::unordered_map<EDA_ITEM*, SCH_SCREEN*> pinToScreenMap;
948 bool has_noconnect =
false;
953 has_noconnect =
true;
959 pins.emplace_back(
static_cast<SCH_PIN*
>( item ), subgraph->
GetSheet() );
965 std::sort( pins.begin(), pins.end(),
968 int ret = StrNumCmp( lhs.Pin()->GetParentSymbol()->GetRef( &lhs.Sheet() ),
969 rhs.Pin()->GetParentSymbol()->GetRef( &rhs.Sheet() ) );
972 ret = StrNumCmp( lhs.Pin()->GetNumber(), rhs.Pin()->GetNumber() );
982 bool hasDriver =
false;
987 bool ispowerNet =
false;
991 if( refPin.Pin()->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN )
998 std::vector<std::tuple<iterator_t, iterator_t, PIN_ERROR>> pin_mismatches;
999 std::map<iterator_t, int> pin_mismatch_counts;
1001 for(
auto refIt = pins.begin(); refIt != pins.end(); ++refIt )
1011 if( !needsDriver.
Pin()
1013 || ( ispowerNet != ( needsDriverType == ELECTRICAL_PINTYPE::PT_POWER_IN )
1014 && ispowerNet == ( refType == ELECTRICAL_PINTYPE::PT_POWER_IN ) ) )
1016 needsDriver = refPin;
1017 needsDriverType = needsDriver.
Pin()->
GetType();
1026 for(
auto testIt = refIt + 1; testIt != pins.end(); ++testIt )
1047 pin_mismatches.emplace_back(
1048 std::tuple<iterator_t, iterator_t, PIN_ERROR>{ refIt, testIt,
erc } );
1052 pin_mismatch_counts[refIt] =
1055 pin_mismatch_counts[testIt] =
1060 if( !pin_mismatch_counts.contains( testIt ) )
1061 pin_mismatch_counts.emplace( testIt, 1 );
1063 pin_mismatch_counts[testIt]++;
1065 if( !pin_mismatch_counts.contains( refIt ) )
1066 pin_mismatch_counts.emplace( refIt, 1 );
1068 pin_mismatch_counts[refIt]++;
1074 std::multimap<size_t, iterator_t, std::greater<size_t>> pins_dsc;
1076 std::transform( pin_mismatch_counts.begin(), pin_mismatch_counts.end(),
1077 std::inserter( pins_dsc, pins_dsc.begin() ),
1080 return std::pair<size_t, iterator_t>( p.second, p.first );
1083 for(
const auto& [amount, pinItBind] : pins_dsc )
1085 auto& pinIt = pinItBind;
1087 if( pin_mismatches.empty() )
1093 iterator_t nearest_pin = pins.end();
1094 double smallest_distance = std::numeric_limits<double>::infinity();
1099 [&](
const auto& tuple )
1103 if( pinIt == std::get<0>( tuple ) )
1104 other = std::get<1>( tuple );
1105 else if( pinIt == std::get<1>( tuple ) )
1106 other = std::get<0>( tuple );
1110 if( ( *pinIt ).Sheet().Cmp( ( *other ).Sheet() ) != 0 )
1112 if( std::isinf( smallest_distance ) )
1114 nearest_pin = other;
1115 erc = std::get<2>( tuple );
1122 if( std::isinf( smallest_distance ) ||
distance < smallest_distance )
1124 smallest_distance = distance;
1125 nearest_pin = other;
1126 erc = std::get<2>( tuple );
1133 if( nearest_pin != pins.end() )
1135 SCH_PIN* other_pin = ( *nearest_pin ).Pin();
1137 std::shared_ptr<ERC_ITEM> ercItem =
1140 ercItem->SetItems(
pin, other_pin );
1141 ercItem->SetSheetSpecificPath( ( *pinIt ).Sheet() );
1142 ercItem->SetItemsSheetPaths( ( *pinIt ).Sheet(), ( *nearest_pin ).Sheet() );
1144 ercItem->SetErrorMessage(
1145 wxString::Format(
_(
"Pins of type %s and %s are connected" ),
1150 pinToScreenMap[
pin]->Append( marker );
1155 if( needsDriver.Pin() && !hasDriver && !has_noconnect )
1163 ercItem->SetItems( needsDriver.Pin() );
1164 ercItem->SetSheetSpecificPath( needsDriver.Sheet() );
1165 ercItem->SetItemsSheetPaths( needsDriver.Sheet() );
1168 needsDriver.Pin()->GetPosition() );
1169 pinToScreenMap[needsDriver.Pin()]->Append( marker );
1183 std::unordered_map<wxString, std::pair<wxString, SCH_PIN*>> pinToNetMap;
1187 const wxString& netName = net.first.Name;
1198 if( !
pin->GetLibPin()->GetParentSymbol()->IsMulti() )
1201 wxString
name =
pin->GetParentSymbol()->GetRef( &sheet ) +
1202 +
":" +
pin->GetShownNumber();
1204 if( !pinToNetMap.count(
name ) )
1206 pinToNetMap[
name] = std::make_pair( netName,
pin );
1208 else if( pinToNetMap[
name].first != netName )
1212 ercItem->SetErrorMessage( wxString::Format(
_(
"Pin %s is connected to both %s and %s" ),
1213 pin->GetShownNumber(),
1215 pinToNetMap[
name].first ) );
1217 ercItem->SetItems(
pin, pinToNetMap[
name].second );
1218 ercItem->SetSheetSpecificPath( sheet );
1219 ercItem->SetItemsSheetPaths( sheet, sheet );
1238 std::unordered_map<wxString, std::pair<SCH_ITEM*, SCH_SHEET_PATH>> globalLabels;
1239 std::unordered_map<wxString, std::pair<SCH_ITEM*, SCH_SHEET_PATH>> localLabels;
1254 auto& map = item->Type() ==
SCH_LABEL_T ? localLabels : globalLabels;
1256 if( !map.count(
text ) )
1258 map[
text] = std::make_pair( label, sheet );
1265 for(
auto& [globalText, globalItem] : globalLabels )
1267 for(
auto& [localText, localItem] : localLabels )
1269 if( globalText == localText )
1272 ercItem->SetItems( globalItem.first, localItem.first );
1273 ercItem->SetSheetSpecificPath( globalItem.second );
1274 ercItem->SetItemsSheetPaths( globalItem.second, localItem.second );
1277 globalItem.first->GetPosition() );
1278 globalItem.second.LastScreen()->Append( marker );
1292 std::unordered_map<wxString, std::vector<std::tuple<wxString, SCH_ITEM*, SCH_SHEET_PATH>>> generalMap;
1295 const std::tuple<wxString, SCH_ITEM*, SCH_SHEET_PATH>& other )
1297 auto& [otherText, otherItem, otherSheet] = other;
1317 ercItem->SetItems( item, otherItem );
1318 ercItem->SetSheetSpecificPath( sheet );
1319 ercItem->SetItemsSheetPaths( sheet, otherSheet );
1322 sheet.LastScreen()->Append( marker );
1333 switch( item->Type() )
1340 wxString unnormalized = label->
GetShownText( &sheet,
false );
1341 wxString normalized = unnormalized.Lower();
1343 generalMap[normalized].emplace_back( std::make_tuple( unnormalized, label, sheet ) );
1345 for(
const auto& otherTuple : generalMap.at( normalized ) )
1347 const auto& [otherText, otherItem, otherSheet] = otherTuple;
1349 if( unnormalized != otherText )
1351 logError( normalized, label, sheet, otherTuple );
1362 if( !
pin->IsPower() )
1368 wxString unnormalized = symbol->
GetValue(
true, &sheet,
false );
1369 wxString normalized = unnormalized.Lower();
1371 generalMap[normalized].emplace_back( std::make_tuple( unnormalized,
pin, sheet ) );
1373 for(
const auto& otherTuple : generalMap.at( normalized ) )
1375 const auto& [otherText, otherItem, otherSheet] = otherTuple;
1377 if( unnormalized != otherText )
1379 logError( normalized,
pin, sheet, otherTuple );
1407 std::vector<SCH_MARKER*> markers;
1414 if( !libSymbolInSchematic )
1425 ercItem->SetItems( symbol );
1426 msg.Printf(
_(
"The current configuration does not include the symbol library '%s'" ),
1428 ercItem->SetErrorMessage( msg );
1435 else if( !libTable->
HasLibrary( libName,
true ) )
1440 ercItem->SetItems( symbol );
1441 msg.Printf(
_(
"The symbol library '%s' is not enabled in the current configuration" ),
1443 ercItem->SetErrorMessage( msg );
1455 ercItem->SetItems( symbol );
1456 msg.Printf(
_(
"The symbol library '%s' was not found at '%s'." ),
1459 ercItem->SetErrorMessage( msg );
1470 if( libSymbol ==
nullptr )
1475 ercItem->SetItems( symbol );
1476 msg.Printf(
_(
"Symbol '%s' not found in symbol library '%s'" ),
1479 ercItem->SetErrorMessage( msg );
1487 std::unique_ptr<LIB_SYMBOL> flattenedSymbol = libSymbol->
Flatten();
1493 std::vector<wxString> messages;
1497 if( !messages.empty() )
1500 ercItem->SetItems( symbol );
1501 msg.Printf(
_(
"Symbol '%s' has multiple pins with the same pin number" ),
1503 ercItem->SetErrorMessage( msg );
1507 else if( flattenedSymbol->Compare( *libSymbolInSchematic, flags ) != 0 )
1510 ercItem->SetItems( symbol );
1511 msg.Printf(
_(
"Symbol '%s' doesn't match copy in library '%s'" ),
1514 ercItem->SetErrorMessage( msg );
1523 screen->Append( marker );
1539 typedef int (*TESTER_FN_PTR)(
const wxString&,
PROJECT* );
1545 std::vector<SCH_MARKER*> markers;
1552 if( footprint.IsEmpty() )
1557 if( fpID.
Parse( footprint,
true ) >= 0 )
1560 msg.Printf(
_(
"'%s' is not a valid footprint identifier." ), footprint );
1561 ercItem->SetErrorMessage( msg );
1562 ercItem->SetItems( symbol );
1569 int ret = (linkTester)( footprint, aProject );
1574 msg.Printf(
_(
"The current configuration does not include the footprint library '%s'." ),
1576 ercItem->SetErrorMessage( msg );
1577 ercItem->SetItems( symbol );
1583 msg.Printf(
_(
"The footprint library '%s' is not enabled in the current configuration." ),
1585 ercItem->SetErrorMessage( msg );
1586 ercItem->SetItems( symbol );
1592 msg.Printf(
_(
"Footprint '%s' not found in library '%s'." ),
1595 ercItem->SetErrorMessage( msg );
1596 ercItem->SetItems( symbol );
1603 sheet.LastScreen()->Append( marker );
1621 std::vector<SCH_MARKER*> markers;
1626 std::unique_ptr<LIB_SYMBOL>& lib_symbol = sch_symbol->
GetLibSymbolRef();
1631 wxArrayString filters = lib_symbol->GetFPFilters();
1633 if( filters.empty() )
1639 if( footprint.
Parse( lowerId ) > 0 )
1645 for( wxString
filter : filters )
1650 if(
filter.Contains( wxS(
":" ) ) )
1651 found |= lowerId.Matches(
filter );
1653 found |= lowerItemName.Matches(
filter );
1662 msg.Printf(
_(
"Assigned footprint (%s) doesn't match footprint filters (%s)." ),
1664 wxJoin( filters,
' ' ) );
1665 ercItem->SetErrorMessage( msg );
1666 ercItem->SetItems( sch_symbol );
1667 markers.emplace_back(
new SCH_MARKER( std::move( ercItem ),
1674 sheet.LastScreen()->Append( marker );
1690 std::vector<SCH_MARKER*> markers;
1692 for(
SCH_ITEM* item : screen->Items() )
1694 if( item->Type() ==
SCH_LINE_T && item->IsConnectable() )
1702 ercItem->SetItems( line );
1710 ercItem->SetItems( line );
1721 if( ( point.x % gridSize ) != 0
1722 || ( point.y % gridSize ) != 0 )
1725 ercItem->SetItems( entry );
1727 markers.emplace_back(
new SCH_MARKER( std::move( ercItem ), point ) );
1737 if(
pin->GetType() == ELECTRICAL_PINTYPE::PT_NC )
1742 if( ( pinPos.
x % gridSize ) != 0 || ( pinPos.
y % gridSize ) != 0 )
1745 ercItem->SetItems(
pin );
1747 markers.emplace_back(
new SCH_MARKER( std::move( ercItem ), pinPos ) );
1756 screen->Append( marker );
1773 if( sheet.GetExcludedFromSim() )
1776 std::vector<SCH_MARKER*> markers;
1800 ercItem->SetErrorMessage( msg );
1801 ercItem->SetItems( symbol );
1809 sheet.LastScreen()->Append( marker );
1827 if( aProgressReporter )
1828 aProgressReporter->
AdvancePhase(
_(
"Checking sheet names..." ) );
1835 if( aProgressReporter )
1836 aProgressReporter->
AdvancePhase(
_(
"Checking bus conflicts..." ) );
1842 if( aProgressReporter )
1843 aProgressReporter->
AdvancePhase(
_(
"Checking conflicts..." ) );
1856 if( aProgressReporter )
1857 aProgressReporter->
AdvancePhase(
_(
"Checking units..." ) );
1862 if( aProgressReporter )
1863 aProgressReporter->
AdvancePhase(
_(
"Checking footprints..." ) );
1876 if( aProgressReporter )
1896 if( aProgressReporter )
1897 aProgressReporter->
AdvancePhase(
_(
"Checking similar labels..." ) );
1904 if( aProgressReporter )
1905 aProgressReporter->
AdvancePhase(
_(
"Checking local and global labels..." ) );
1912 if( aProgressReporter )
1913 aProgressReporter->
AdvancePhase(
_(
"Checking for unresolved variables..." ) );
1920 if( aProgressReporter )
1921 aProgressReporter->
AdvancePhase(
_(
"Checking SPICE models..." ) );
1928 if( aProgressReporter )
1929 aProgressReporter->
AdvancePhase(
_(
"Checking no connect pins for connections..." ) );
1937 if( aProgressReporter )
1938 aProgressReporter->
AdvancePhase(
_(
"Checking for library symbol issues..." ) );
1945 if( aProgressReporter )
1946 aProgressReporter->
AdvancePhase(
_(
"Checking for footprint link issues..." ) );
1953 if( aProgressReporter )
1954 aProgressReporter->
AdvancePhase(
_(
"Checking footprint assignments against footprint filters..." ) );
1961 if( aProgressReporter )
1962 aProgressReporter->
AdvancePhase(
_(
"Checking for off grid pins and wires..." ) );
1969 if( aProgressReporter )
1970 aProgressReporter->
AdvancePhase(
_(
"Checking for four way junctions..." ) );
1977 if( aProgressReporter )
1978 aProgressReporter->
AdvancePhase(
_(
"Checking for labels on more than one wire..." ) );
1985 if( aProgressReporter )
1986 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.
virtual bool LibraryExists() const =0
const wxString GetFullURI(bool aSubstituted=false) const
Return the full location specifying URI for the LIB, either in original UI form or in environment var...
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
PROJECT & Prj() const
Return a reference to the project this schematic is part of.
void ResolveERCExclusionsPostUpdate()
Update markers to match recorded exclusions.
SCHEMATIC_SETTINGS & Settings() const
CONNECTION_GRAPH * ConnectionGraph() const
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, PROGRESS_REPORTER *aProgressReporter=nullptr)
Generate the connection data for the entire schematic hierarchy.
Base class for any item which can be embedded within the SCHEMATIC container class,...
bool ResolveExcludedFromSim() 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
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.
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()
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
const wxString GetValue(bool aResolve, const SCH_SHEET_PATH *aPath, bool aAllowExtraText) 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
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...
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
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_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