80 _(
"Bidirectional Pin" ),
84 _(
"Unspecified Pin" ),
85 _(
"Power Input Pin" ),
86 _(
"Power Output Pin" ),
87 _(
"Open Collector" ),
97 _(
"Bidirectional Pin" ),
101 _(
"Unspecified Pin" ),
102 _(
"Power Input Pin" ),
103 _(
"Power Output Pin" ),
104 _(
"Open Collector" ),
146 std::vector<SCH_SHEET*> list;
149 list.push_back(
static_cast<SCH_SHEET*
>( item ) );
151 for(
size_t i = 0; i < list.size(); i++ )
155 for(
size_t j = i + 1; j < list.size(); j++ )
167 ercItem->SetItems( sheet, test_item );
170 screen->Append( marker );
188 [
this]( wxString str )
191 return str.Matches( wxS(
"*${*}*" ) );
198 static wxRegEx warningExpr( wxS(
"^\\$\\{ERC_WARNING\\s*([^}]*)\\}(.*)$" ) );
199 static wxRegEx errorExpr( wxS(
"^\\$\\{ERC_ERROR\\s*([^}]*)\\}(.*)$" ) );
201 if( warningExpr.Matches(
text ) )
204 wxString ercText = warningExpr.GetMatch(
text, 1 );
207 ercItem->SetItems( item );
209 ercText +=
_(
" (in drawing sheet)" );
211 ercItem->SetSheetSpecificPath( sheet );
212 ercItem->SetErrorMessage( ercText );
215 screen->Append( marker );
220 if( errorExpr.Matches(
text ) )
223 wxString ercText = errorExpr.GetMatch(
text, 1 );
226 ercItem->SetItems( item );
228 ercText +=
_(
" (in drawing sheet)" );
230 ercItem->SetSheetSpecificPath( sheet );
231 ercItem->SetErrorMessage( ercText );
234 screen->Append( marker );
265 if( unresolved( field.GetShownText( &sheet,
true ) ) )
268 ercItem->SetItems( symbol );
269 ercItem->SetSheetSpecificPath( sheet );
275 testAssertion( &field, sheet, screen, field.GetText(), field.
GetPosition() );
287 SCH_TEXT* textItem = static_cast<SCH_TEXT*>( child );
289 if( unresolved( textItem->GetShownText( &sheet, true ) ) )
291 auto ercItem = ERC_ITEM::Create( ERCE_UNRESOLVED_VARIABLE );
292 ercItem->SetItems( symbol );
293 ercItem->SetSheetSpecificPath( sheet );
295 BOX2I bbox = textItem->GetBoundingBox();
296 bbox = symbol->GetTransform().TransformCoordinate( bbox );
297 VECTOR2I pos = bbox.Centre() + symbol->GetPosition();
299 SCH_MARKER* marker = new SCH_MARKER( ercItem, pos );
300 screen->Append( marker );
303 testAssertion( symbol, sheet, screen, textItem->GetText(),
308 SCH_TEXTBOX* textboxItem = static_cast<SCH_TEXTBOX*>( child );
310 if( unresolved( textboxItem->GetShownText( &sheet, true ) ) )
312 auto ercItem = ERC_ITEM::Create( ERCE_UNRESOLVED_VARIABLE );
313 ercItem->SetItems( symbol );
314 ercItem->SetSheetSpecificPath( sheet );
316 BOX2I bbox = textboxItem->GetBoundingBox();
317 bbox = symbol->GetTransform().TransformCoordinate( bbox );
318 VECTOR2I pos = bbox.Centre() + symbol->GetPosition();
320 SCH_MARKER* marker = new SCH_MARKER( ercItem, pos );
321 screen->Append( marker );
324 testAssertion( symbol, sheet, screen, textboxItem->GetText(),
331 for(
SCH_FIELD& field : label->GetFields() )
333 if( unresolved( field.GetShownText( &sheet,
true ) ) )
336 ercItem->SetItems( label );
337 ercItem->SetSheetSpecificPath( sheet );
340 screen->Append( marker );
343 testAssertion( &field, sheet, screen, field.GetText(), field.GetPosition() );
352 if( unresolved( field.GetShownText( &sheet,
true ) ) )
355 ercItem->SetItems( subSheet );
356 ercItem->SetSheetSpecificPath( sheet );
359 screen->Append( marker );
362 testAssertion( &field, sheet, screen, field.GetText(), field.GetPosition() );
370 if(
pin->GetShownText( &subSheetPath,
true ).Matches( wxS(
"*${*}*" ) ) )
373 ercItem->SetItems(
pin );
374 ercItem->SetSheetSpecificPath( sheet );
377 screen->Append( marker );
383 if(
text->GetShownText( &sheet,
true ).Matches( wxS(
"*${*}*" ) ) )
386 ercItem->SetItems(
text );
387 ercItem->SetSheetSpecificPath( sheet );
390 screen->Append( marker );
393 testAssertion(
text, sheet, screen,
text->GetText(),
text->GetPosition() );
397 if( textBox->GetShownText( &sheet,
true ).Matches( wxS(
"*${*}*" ) ) )
400 ercItem->SetItems( textBox );
401 ercItem->SetSheetSpecificPath( sheet );
404 screen->Append( marker );
407 testAssertion( textBox, sheet, screen, textBox->GetText(), textBox->GetPosition() );
411 for(
DS_DRAW_ITEM_BASE* item = wsItems.GetFirst(); item; item = wsItems.GetNext() )
415 if( testAssertion(
nullptr, sheet, screen,
text->GetText(),
text->GetPosition() ) )
419 else if(
text->GetShownText(
true ).Matches( wxS(
"*${*}*" ) ) )
422 erc->SetErrorMessage(
_(
"Unresolved text variable in drawing sheet" ) );
423 erc->SetSheetSpecificPath( sheet );
426 screen->Append( marker );
438 std::vector<std::shared_ptr<BUS_ALIAS>> aliases;
442 const auto& screen_aliases = screen->GetBusAliases();
444 for(
const std::shared_ptr<BUS_ALIAS>& alias : screen_aliases )
446 std::vector<wxString> aliasMembers = alias->Members();
447 std::sort( aliasMembers.begin(), aliasMembers.end() );
449 for(
const std::shared_ptr<BUS_ALIAS>&
test : aliases )
451 std::vector<wxString> testMembers =
test->Members();
452 std::sort( testMembers.begin(), testMembers.end() );
454 if( alias->GetName() ==
test->GetName() && aliasMembers != testMembers )
456 msg.Printf(
_(
"Bus alias %s has conflicting definitions on %s and %s" ),
458 alias->GetParent()->GetFileName(),
459 test->GetParent()->GetFileName() );
462 ercItem->SetErrorMessage( msg );
465 test->GetParent()->Append( marker );
472 aliases.insert( aliases.end(), screen_aliases.begin(), screen_aliases.end() );
483 for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol :
m_refMap )
498 for(
size_t ii = 0; ii < refList.
GetCount(); ++ii )
503 if( !unitFP.IsEmpty() )
506 unitName = unit->
GetRef( &sheetPath,
true );
511 for(
size_t ii = 0; ii < refList.
GetCount(); ++ii )
519 if( unit && !secondFp.IsEmpty() && unitFP != secondFp )
521 msg.Printf(
_(
"Different footprints assigned to %s and %s" ),
522 unitName, secondName );
525 ercItem->SetErrorMessage( msg );
526 ercItem->SetItems( unit, secondUnit );
544 for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol :
m_refMap )
548 wxCHECK2( refList.
GetCount(),
continue );
558 std::set<int> lib_units;
559 std::set<int> instance_units;
560 std::set<int> missing_units;
563 [&]( std::set<int>& aMissingUnits,
const wxString& aErrorMsg,
int aErrorCode )
566 wxString missing_pin_units = wxS(
"[ " );
569 for(
int missing_unit : aMissingUnits )
573 missing_pin_units += wxS(
"....." );
580 missing_pin_units.Truncate( missing_pin_units.length() - 2 );
581 missing_pin_units += wxS(
" ]" );
583 msg.Printf( aErrorMsg, symbol.first, missing_pin_units );
586 ercItem->SetErrorMessage( msg );
587 ercItem->SetItems( unit );
588 ercItem->SetSheetSpecificPath( base_ref.
GetSheetPath() );
597 for(
int ii = 1; ii <= libSymbol->
GetUnitCount(); ++ii )
598 lib_units.insert( lib_units.end(), ii );
600 for(
size_t ii = 0; ii < refList.
GetCount(); ++ii )
601 instance_units.insert( instance_units.end(), refList.
GetItem( ii ).
GetUnit() );
603 std::set_difference( lib_units.begin(), lib_units.end(),
604 instance_units.begin(), instance_units.end(),
605 std::inserter( missing_units, missing_units.begin() ) );
612 std::set<int> missing_power;
613 std::set<int> missing_input;
614 std::set<int> missing_bidi;
616 for(
int missing_unit : missing_units )
620 for(
size_t ii = 0; ii < refList.
GetCount(); ++ii )
631 switch(
pin->GetType() )
633 case ELECTRICAL_PINTYPE::PT_POWER_IN:
634 missing_power.insert( missing_unit );
637 case ELECTRICAL_PINTYPE::PT_BIDI:
638 missing_bidi.insert( missing_unit );
641 case ELECTRICAL_PINTYPE::PT_INPUT:
642 missing_input.insert( missing_unit );
653 report( missing_power,
654 _(
"Symbol %s has input power pins in units %s that are not placed." ),
660 report( missing_input,
661 _(
"Symbol %s has input pins in units %s that are not placed." ),
667 report( missing_bidi,
668 _(
"Symbol %s has bidirectional pins in units %s that are not placed." ),
681 wxString defaultNetclass = settings->GetDefaultNetclass()->GetName();
690 ercItem->SetItems( item );
691 ercItem->SetErrorMessage( wxString::Format(
_(
"Netclass %s is not defined" ),
707 SCH_FIELD* field = static_cast<SCH_FIELD*>( aChild );
709 if( field->GetCanonicalName() == wxT(
"Netclass" ) )
711 wxString netclass = field->GetShownText( &sheet, false );
713 if( !netclass.IsSameAs( defaultNetclass )
714 && !settings->HasNetclass( netclass ) )
716 logError( sheet, item, netclass );
736 std::map<VECTOR2I, std::vector<SCH_ITEM*>> connMap;
743 connMap[pt].emplace_back( label );
746 for(
const std::pair<
const VECTOR2I, std::vector<SCH_ITEM*>>& pair : connMap )
748 std::vector<SCH_ITEM*> lines;
750 for(
SCH_ITEM* item : sheet.LastScreen()->Items().Overlapping(
SCH_LINE_T, pair.first ) )
759 lines.emplace_back( line );
762 if( lines.size() > 1 )
768 wxString msg = wxString::Format(
_(
"Label connects more than one wire at %d, %d" ),
769 pair.first.x, pair.first.y );
771 ercItem->SetItems( pair.second.front(), lines[0], lines[1], lines[2] );
772 ercItem->SetErrorMessage( msg );
773 ercItem->SetSheetSpecificPath( sheet );
776 sheet.LastScreen()->Append( marker );
791 std::map<VECTOR2I, std::vector<SCH_ITEM*>> connMap;
799 connMap[
pin->GetPosition()].emplace_back(
pin );
810 connMap[pt].emplace_back( line );
813 for(
const std::pair<
const VECTOR2I, std::vector<SCH_ITEM*>>& pair : connMap )
815 if( pair.second.size() >= 4 )
821 ercItem->SetItems( pair.second[0], pair.second[1], pair.second[2], pair.second[3] );
823 wxString msg = wxString::Format(
_(
"Four items connected at %d, %d" ),
824 pair.first.x, pair.first.y );
825 ercItem->SetErrorMessage( msg );
827 ercItem->SetSheetSpecificPath( sheet );
830 sheet.LastScreen()->Append( marker );
845 std::map<VECTOR2I, std::vector<SCH_ITEM*>> pinMap;
850 if( pinMap.count( pt ) )
851 pinMap[pt].emplace_back( aOther );
860 if(
pin->GetLibPin()->GetType() == ELECTRICAL_PINTYPE::PT_NC )
861 pinMap[
pin->GetPosition()].emplace_back(
pin );
865 for(
SCH_ITEM* item : sheet.LastScreen()->Items() )
873 if(
pin->GetLibPin()->GetType() != ELECTRICAL_PINTYPE::PT_NC )
874 addOther(
pin->GetPosition(),
pin );
877 else if( item->IsConnectable() )
879 for(
const VECTOR2I& pt : item->GetConnectionPoints() )
880 addOther( pt, item );
884 for(
const std::pair<
const VECTOR2I, std::vector<SCH_ITEM*>>& pair : pinMap )
886 if( pair.second.size() > 1 )
892 ercItem->SetItems( pair.second[0], pair.second[1],
893 pair.second.size() > 2 ? pair.second[2] :
nullptr,
894 pair.second.size() > 3 ? pair.second[3] :
nullptr );
895 ercItem->SetErrorMessage(
_(
"Pin with 'no connection' type is connected" ) );
896 ercItem->SetSheetSpecificPath( sheet );
899 sheet.LastScreen()->Append( marker );
914 using iterator_t = std::vector<ERC_SCH_PIN_CONTEXT>::iterator;
915 std::vector<ERC_SCH_PIN_CONTEXT> pins;
916 std::unordered_map<EDA_ITEM*, SCH_SCREEN*> pinToScreenMap;
917 bool has_noconnect =
false;
922 has_noconnect =
true;
928 pins.emplace_back(
static_cast<SCH_PIN*
>( item ), subgraph->
GetSheet() );
934 std::sort( pins.begin(), pins.end(),
937 int ret = StrNumCmp( lhs.Pin()->GetParentSymbol()->GetRef( &lhs.Sheet() ),
938 rhs.Pin()->GetParentSymbol()->GetRef( &rhs.Sheet() ) );
941 ret = StrNumCmp( lhs.Pin()->GetNumber(), rhs.Pin()->GetNumber() );
951 bool hasDriver =
false;
956 bool ispowerNet =
false;
960 if( refPin.Pin()->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN )
967 std::vector<std::tuple<iterator_t, iterator_t, PIN_ERROR>> pin_mismatches;
968 std::map<iterator_t, int> pin_mismatch_counts;
970 for(
auto refIt = pins.begin(); refIt != pins.end(); ++refIt )
980 if( !needsDriver.
Pin()
982 || ( ispowerNet != ( needsDriverType == ELECTRICAL_PINTYPE::PT_POWER_IN )
983 && ispowerNet == ( refType == ELECTRICAL_PINTYPE::PT_POWER_IN ) ) )
985 needsDriver = refPin;
986 needsDriverType = needsDriver.
Pin()->
GetType();
995 for(
auto testIt = refIt + 1; testIt != pins.end(); ++testIt )
1016 pin_mismatches.emplace_back(
1017 std::tuple<iterator_t, iterator_t, PIN_ERROR>{ refIt, testIt,
erc } );
1021 pin_mismatch_counts[refIt] =
1024 pin_mismatch_counts[testIt] =
1029 if( !pin_mismatch_counts.contains( testIt ) )
1030 pin_mismatch_counts.emplace( testIt, 1 );
1032 pin_mismatch_counts[testIt]++;
1034 if( !pin_mismatch_counts.contains( refIt ) )
1035 pin_mismatch_counts.emplace( refIt, 1 );
1037 pin_mismatch_counts[refIt]++;
1043 std::multimap<size_t, iterator_t, std::greater<size_t>> pins_dsc;
1045 std::transform( pin_mismatch_counts.begin(), pin_mismatch_counts.end(),
1046 std::inserter( pins_dsc, pins_dsc.begin() ),
1049 return std::pair<size_t, iterator_t>( p.second, p.first );
1052 for(
const auto& [amount, pinItBind] : pins_dsc )
1054 auto& pinIt = pinItBind;
1056 if( pin_mismatches.empty() )
1062 iterator_t nearest_pin = pins.end();
1063 double smallest_distance = std::numeric_limits<double>::infinity();
1068 [&](
const auto& tuple )
1072 if( pinIt == std::get<0>( tuple ) )
1073 other = std::get<1>( tuple );
1074 else if( pinIt == std::get<1>( tuple ) )
1075 other = std::get<0>( tuple );
1079 if( ( *pinIt ).Sheet().Cmp( ( *other ).Sheet() ) != 0 )
1081 if( std::isinf( smallest_distance ) )
1083 nearest_pin = other;
1084 erc = std::get<2>( tuple );
1091 if( std::isinf( smallest_distance ) ||
distance < smallest_distance )
1093 smallest_distance = distance;
1094 nearest_pin = other;
1095 erc = std::get<2>( tuple );
1102 if( nearest_pin != pins.end() )
1104 SCH_PIN* other_pin = ( *nearest_pin ).Pin();
1106 std::shared_ptr<ERC_ITEM> ercItem =
1109 ercItem->SetItems(
pin, other_pin );
1110 ercItem->SetSheetSpecificPath( ( *pinIt ).Sheet() );
1111 ercItem->SetItemsSheetPaths( ( *pinIt ).Sheet(), ( *nearest_pin ).Sheet() );
1113 ercItem->SetErrorMessage(
1114 wxString::Format(
_(
"Pins of type %s and %s are connected" ),
1119 pinToScreenMap[
pin]->Append( marker );
1124 if( needsDriver.Pin() && !hasDriver && !has_noconnect )
1132 ercItem->SetItems( needsDriver.Pin() );
1133 ercItem->SetSheetSpecificPath( needsDriver.Sheet() );
1134 ercItem->SetItemsSheetPaths( needsDriver.Sheet() );
1137 pinToScreenMap[needsDriver.Pin()]->Append( marker );
1151 std::unordered_map<wxString, std::pair<wxString, SCH_PIN*>> pinToNetMap;
1155 const wxString& netName = net.first.Name;
1166 if( !
pin->GetLibPin()->GetParentSymbol()->IsMulti() )
1169 wxString
name =
pin->GetParentSymbol()->GetRef( &sheet ) +
1170 +
":" +
pin->GetShownNumber();
1172 if( !pinToNetMap.count(
name ) )
1174 pinToNetMap[
name] = std::make_pair( netName,
pin );
1176 else if( pinToNetMap[
name].first != netName )
1178 std::shared_ptr<ERC_ITEM> ercItem =
1181 ercItem->SetErrorMessage( wxString::Format(
1182 _(
"Pin %s is connected to both %s and %s" ),
1183 pin->GetShownNumber(),
1185 pinToNetMap[
name].first ) );
1187 ercItem->SetItems(
pin, pinToNetMap[
name].second );
1188 ercItem->SetSheetSpecificPath( sheet );
1189 ercItem->SetItemsSheetPaths( sheet, sheet );
1208 std::unordered_map<wxString, std::pair<SCH_ITEM*, SCH_SHEET_PATH>> globalLabels;
1209 std::unordered_map<wxString, std::pair<SCH_ITEM*, SCH_SHEET_PATH>> localLabels;
1224 auto& map = item->Type() ==
SCH_LABEL_T ? localLabels : globalLabels;
1226 if( !map.count(
text ) )
1228 map[
text] = std::make_pair( label, sheet );
1235 for(
auto& [globalText, globalItem] : globalLabels )
1237 for(
auto& [localText, localItem] : localLabels )
1239 if( globalText == localText )
1241 std::shared_ptr<ERC_ITEM> ercItem =
1243 ercItem->SetItems( globalItem.first, localItem.first );
1244 ercItem->SetSheetSpecificPath( globalItem.second );
1245 ercItem->SetItemsSheetPaths( globalItem.second, localItem.second );
1248 globalItem.second.LastScreen()->Append( marker );
1262 std::unordered_map<wxString, std::vector<std::tuple<wxString, SCH_ITEM*, SCH_SHEET_PATH>>> generalMap;
1265 const std::tuple<wxString, SCH_ITEM*, SCH_SHEET_PATH>& other )
1267 auto& [otherText, otherItem, otherSheet] = other;
1287 ercItem->SetItems( item, otherItem );
1288 ercItem->SetSheetSpecificPath( sheet );
1289 ercItem->SetItemsSheetPaths( sheet, otherSheet );
1292 sheet.LastScreen()->Append( marker );
1303 switch( item->Type() )
1310 wxString unnormalized = label->
GetShownText( &sheet,
false );
1311 wxString normalized = unnormalized.Lower();
1313 generalMap[normalized].emplace_back( std::make_tuple( unnormalized, label, sheet ) );
1315 for(
const auto& otherTuple : generalMap.at( normalized ) )
1317 const auto& [otherText, otherItem, otherSheet] = otherTuple;
1319 if( unnormalized != otherText )
1321 logError( normalized, label, sheet, otherTuple );
1332 if( !
pin->IsGlobalPower() )
1338 wxString unnormalized = symbol->
GetValue(
true, &sheet,
false );
1339 wxString normalized = unnormalized.Lower();
1341 generalMap[normalized].emplace_back( std::make_tuple( unnormalized,
pin, sheet ) );
1343 for(
const auto& otherTuple : generalMap.at( normalized ) )
1345 const auto& [otherText, otherItem, otherSheet] = otherTuple;
1347 if( unnormalized != otherText )
1349 logError( normalized,
pin, sheet, otherTuple );
1377 std::vector<SCH_MARKER*> markers;
1384 wxCHECK2( libSymbolInSchematic,
continue );
1394 ercItem->SetItems( symbol );
1395 msg.Printf(
_(
"The current configuration does not include the symbol library '%s'" ),
1397 ercItem->SetErrorMessage( msg );
1404 else if( !libTable->
HasLibrary( libName,
true ) )
1409 ercItem->SetItems( symbol );
1410 msg.Printf(
_(
"The library '%s' is not enabled in the current configuration" ),
1412 ercItem->SetErrorMessage( msg );
1423 if( libSymbol ==
nullptr )
1428 ercItem->SetItems( symbol );
1429 msg.Printf(
_(
"Symbol '%s' not found in symbol library '%s'" ),
1432 ercItem->SetErrorMessage( msg );
1440 std::unique_ptr<LIB_SYMBOL> flattenedSymbol = libSymbol->
Flatten();
1446 std::vector<wxString> messages;
1450 if( !messages.empty() )
1453 ercItem->SetItems( symbol );
1454 msg.Printf(
_(
"Symbol '%s' has multiple pins with the same pin number" ),
1456 ercItem->SetErrorMessage( msg );
1460 else if( flattenedSymbol->Compare( *libSymbolInSchematic, flags ) != 0 )
1463 ercItem->SetItems( symbol );
1464 msg.Printf(
_(
"Symbol '%s' doesn't match copy in library '%s'" ),
1467 ercItem->SetErrorMessage( msg );
1476 screen->Append( marker );
1492 typedef int (*TESTER_FN_PTR)(
const wxString&,
PROJECT* );
1498 std::vector<SCH_MARKER*> markers;
1505 if( footprint.IsEmpty() )
1510 if( fpID.
Parse( footprint,
true ) >= 0 )
1513 msg.Printf(
_(
"'%s' is not a valid footprint identifier." ), footprint );
1514 ercItem->SetErrorMessage( msg );
1515 ercItem->SetItems( symbol );
1522 int ret = (linkTester)( footprint, aProject );
1527 msg.Printf(
_(
"The current configuration does not include the footprint library '%s'." ),
1529 ercItem->SetErrorMessage( msg );
1530 ercItem->SetItems( symbol );
1536 msg.Printf(
_(
"The footprint library '%s' is not enabled in the current configuration." ),
1538 ercItem->SetErrorMessage( msg );
1539 ercItem->SetItems( symbol );
1545 msg.Printf(
_(
"Footprint '%s' not found in library '%s'." ),
1548 ercItem->SetErrorMessage( msg );
1549 ercItem->SetItems( symbol );
1556 sheet.LastScreen()->Append( marker );
1574 std::vector<SCH_MARKER*> markers;
1579 std::unique_ptr<LIB_SYMBOL>& lib_symbol = sch_symbol->
GetLibSymbolRef();
1584 wxArrayString filters = lib_symbol->GetFPFilters();
1586 if( filters.empty() )
1592 if( footprint.
Parse( lowerId ) > 0 )
1598 for( wxString
filter : filters )
1603 if(
filter.Contains( wxS(
":" ) ) )
1604 found |= lowerId.Matches(
filter );
1606 found |= lowerItemName.Matches(
filter );
1615 msg.Printf(
_(
"Assigned footprint (%s) doesn't match footprint filters (%s)." ),
1617 wxJoin( filters,
' ' ) );
1618 ercItem->SetErrorMessage( msg );
1619 ercItem->SetItems( sch_symbol );
1626 sheet.LastScreen()->Append( marker );
1642 std::vector<SCH_MARKER*> markers;
1644 for(
SCH_ITEM* item : screen->Items() )
1646 if( item->Type() ==
SCH_LINE_T && item->IsConnectable() )
1654 ercItem->SetItems( line );
1662 ercItem->SetItems( line );
1675 if( ( pinPos.
x % gridSize ) != 0 || ( pinPos.
y % gridSize ) != 0 )
1678 ercItem->SetItems(
pin );
1680 markers.emplace_back(
new SCH_MARKER( ercItem, pinPos ) );
1689 screen->Append( marker );
1706 if( sheet.GetExcludedFromSim() )
1709 std::vector<SCH_MARKER*> markers;
1733 ercItem->SetErrorMessage( msg );
1734 ercItem->SetItems( symbol );
1742 sheet.LastScreen()->Append( marker );
1760 if( aProgressReporter )
1761 aProgressReporter->
AdvancePhase(
_(
"Checking sheet names..." ) );
1768 if( aProgressReporter )
1769 aProgressReporter->
AdvancePhase(
_(
"Checking bus conflicts..." ) );
1775 if( aProgressReporter )
1776 aProgressReporter->
AdvancePhase(
_(
"Checking conflicts..." ) );
1789 if( aProgressReporter )
1790 aProgressReporter->
AdvancePhase(
_(
"Checking units..." ) );
1795 if( aProgressReporter )
1796 aProgressReporter->
AdvancePhase(
_(
"Checking footprints..." ) );
1809 if( aProgressReporter )
1830 if( aProgressReporter )
1831 aProgressReporter->
AdvancePhase(
_(
"Checking labels..." ) );
1839 if( aProgressReporter )
1840 aProgressReporter->
AdvancePhase(
_(
"Checking for unresolved variables..." ) );
1847 if( aProgressReporter )
1848 aProgressReporter->
AdvancePhase(
_(
"Checking SPICE models..." ) );
1855 if( aProgressReporter )
1856 aProgressReporter->
AdvancePhase(
_(
"Checking no connect pins for connections..." ) );
1864 if( aProgressReporter )
1865 aProgressReporter->
AdvancePhase(
_(
"Checking for library symbol issues..." ) );
1872 if( aProgressReporter )
1873 aProgressReporter->
AdvancePhase(
_(
"Checking for footprint link issues..." ) );
1880 if( aProgressReporter )
1881 aProgressReporter->
AdvancePhase(
_(
"Checking footprint assignments against footprint filters..." ) );
1888 if( aProgressReporter )
1889 aProgressReporter->
AdvancePhase(
_(
"Checking for off grid pins and wires..." ) );
1896 if( aProgressReporter )
1897 aProgressReporter->
AdvancePhase(
_(
"Checking for four way junctions..." ) );
1904 if( aProgressReporter )
1905 aProgressReporter->
AdvancePhase(
_(
"Checking for labels on more than one wire..." ) );
1912 if( aProgressReporter )
1913 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=0, int aBodyStyle=0) 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.
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
const wxString GetValue(bool aResolve, const SCH_SHEET_PATH *aPath, bool aAllowExtraText) const override
std::vector< SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieve a list of the SCH_PINs for the given sheet path.
const wxString GetFootprintFieldText(bool aResolve, const SCH_SHEET_PATH *aPath, bool aAllowExtraText) const
VECTOR2I GetPosition() const override
const LIB_ID & GetLibId() const override
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly)
Populate a std::vector with SCH_FIELDs.
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