// Helper function: creates a marker for similar labels ERC warning static void SimilarLabelsDiagnose( NETLIST_OBJECT* aItemA, NETLIST_OBJECT* aItemB ) { // Create new marker for ERC. SCH_MARKER* marker = new SCH_MARKER(); marker->SetTimeStamp( GetNewTimeStamp() ); marker->SetMarkerType( MARKER_BASE::MARKER_ERC ); marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_WARNING ); SCH_SCREEN* screen = aItemA->m_SheetPath.LastScreen(); screen->Append( marker ); wxString fmt = aItemA->IsLabelGlobal() ? _( "Global label \"%s\" (sheet \"%s\") looks like:" ) : _( "Local label \"%s\" (sheet \"%s\") looks like:" ); wxString msg; msg.Printf( fmt, GetChars( aItemA->m_Label ), GetChars( aItemA->m_SheetPath.PathHumanReadable() ) ); marker->SetData( aItemA->IsLabelGlobal() && aItemB->IsLabelGlobal() ? ERCE_SIMILAR_GLBL_LABELS : ERCE_SIMILAR_LABELS, aItemA->m_Start, msg, aItemA->m_Start ); fmt = aItemB->IsLabelGlobal() ? _( "Global label \"%s\" (sheet \"%s\")" ) : _( "Local label \"%s\" (sheet \"%s\")" ); msg.Printf( fmt, GetChars( aItemB->m_Label ), GetChars( aItemB->m_SheetPath.PathHumanReadable() ) ); marker->SetAuxiliaryData( msg, aItemB->m_Start ); }
int TestDuplicateSheetNames( bool aCreateMarker ) { SCH_SCREEN* screen; SCH_ITEM* item; SCH_ITEM* test_item; int err_count = 0; SCH_SCREENS screenList; // Created the list of screen for( screen = screenList.GetFirst(); screen != NULL; screen = screenList.GetNext() ) { for( item = screen->GetDrawItems(); item != NULL; item = item->Next() ) { // search for a sheet; if( item->Type() != SCH_SHEET_T ) continue; for( test_item = item->Next(); test_item != NULL; test_item = test_item->Next() ) { if( test_item->Type() != SCH_SHEET_T ) continue; // We have found a second sheet: compare names // we are using case insensitive comparison to avoid mistakes between // similar names like Mysheet and mysheet if( ( (SCH_SHEET*) item )->GetName().CmpNoCase( ( ( SCH_SHEET* ) test_item )->GetName() ) == 0 ) { if( aCreateMarker ) { /* Create a new marker type ERC error*/ SCH_MARKER* marker = new SCH_MARKER(); marker->SetTimeStamp( GetNewTimeStamp() ); marker->SetData( ERCE_DUPLICATE_SHEET_NAME, ( (SCH_SHEET*) test_item )->GetPosition(), _( "Duplicate sheet name" ), ( (SCH_SHEET*) test_item )->GetPosition() ); marker->SetMarkerType( MARKER_BASE::MARKER_ERC ); marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_ERROR ); screen->Append( marker ); } err_count++; } } } } return err_count; }
void Diagnose( NETLIST_OBJECT* aNetItemRef, NETLIST_OBJECT* aNetItemTst, int aMinConn, int aDiag ) { SCH_MARKER* marker = NULL; SCH_SCREEN* screen; int ii, jj; if( aDiag == OK ) return; /* Create new marker for ERC error. */ marker = new SCH_MARKER(); marker->SetTimeStamp( GetNewTimeStamp() ); marker->SetMarkerType( MARK_ERC ); marker->SetErrorLevel( WAR ); screen = aNetItemRef->m_SheetPath.LastScreen(); screen->Append( marker ); wxString msg; if( aMinConn < 0 ) { if( (aNetItemRef->m_Type == NET_HIERLABEL) || (aNetItemRef->m_Type == NET_HIERBUSLABELMEMBER) ) { msg.Printf( _( "Hierarchical label %s is not connected to a sheet label." ), GetChars( aNetItemRef->m_Label ) ); } else { msg.Printf( _( "Sheet label %s is not connected to a hierarchical label." ), GetChars( aNetItemRef->m_Label ) ); } marker->SetData( ERCE_HIERACHICAL_LABEL, aNetItemRef->m_Start, msg, aNetItemRef->m_Start ); return; } ii = aNetItemRef->m_ElectricalType; wxString string_pinnum, cmp_ref; char ascii_buf[5]; ascii_buf[4] = 0; memcpy( ascii_buf, &aNetItemRef->m_PinNum, 4 ); string_pinnum = FROM_UTF8( ascii_buf ); cmp_ref = wxT( "?" ); if( aNetItemRef->m_Type == NET_PIN && aNetItemRef->m_Link ) cmp_ref = aNetItemRef->GetComponentParent()->GetRef( &aNetItemRef->m_SheetPath ); if( aNetItemTst == NULL ) { if( aMinConn == NOC ) /* Only 1 element in the net. */ { msg.Printf( _( "Pin %s (%s) of component %s is unconnected." ), GetChars( string_pinnum ), MsgPinElectricType[ii], GetChars( cmp_ref ) ); marker->SetData( ERCE_PIN_NOT_CONNECTED, aNetItemRef->m_Start, msg, aNetItemRef->m_Start ); return; } if( aMinConn == NOD ) /* Nothing driving the net. */ { if( aNetItemRef->m_Type == NET_PIN && aNetItemRef->m_Link ) cmp_ref = aNetItemRef->GetComponentParent()->GetRef( &aNetItemRef->m_SheetPath ); msg.Printf( _( "Pin %s (%s) of component %s is not driven (Net %d)." ), GetChars( string_pinnum ), MsgPinElectricType[ii], GetChars( cmp_ref ), aNetItemRef->GetNet() ); marker->SetData( ERCE_PIN_NOT_DRIVEN, aNetItemRef->m_Start, msg, aNetItemRef->m_Start ); return; } if( aDiag == UNC ) { msg.Printf( _( "More than 1 pin connected to an UnConnect symbol." ) ); marker->SetData( ERCE_NOCONNECT_CONNECTED, aNetItemRef->m_Start, msg, aNetItemRef->m_Start ); return; } } if( aNetItemTst ) /* Error between 2 pins */ { jj = aNetItemTst->m_ElectricalType; int errortype = ERCE_PIN_TO_PIN_WARNING; if( aDiag == ERR ) { marker->SetErrorLevel( ERR ); errortype = ERCE_PIN_TO_PIN_ERROR; } wxString alt_string_pinnum, alt_cmp; memcpy( ascii_buf, &aNetItemTst->m_PinNum, 4 ); alt_string_pinnum = FROM_UTF8( ascii_buf ); alt_cmp = wxT( "?" ); if( aNetItemTst->m_Type == NET_PIN && aNetItemTst->m_Link ) alt_cmp = aNetItemTst->GetComponentParent()->GetRef( &aNetItemTst->m_SheetPath ); msg.Printf( _( "Pin %s (%s) of component %s is connected to " ), GetChars( string_pinnum ), MsgPinElectricType[ii], GetChars( cmp_ref ) ); marker->SetData( errortype, aNetItemRef->m_Start, msg, aNetItemRef->m_Start ); msg.Printf( _( "pin %s (%s) of component %s (net %d)." ), GetChars( alt_string_pinnum ), MsgPinElectricType[jj], GetChars( alt_cmp ), aNetItemRef->GetNet() ); marker->SetAuxiliaryData( msg, aNetItemTst->m_Start ); } }
void Diagnose( NETLIST_OBJECT* aNetItemRef, NETLIST_OBJECT* aNetItemTst, int aMinConn, int aDiag ) { SCH_MARKER* marker = NULL; SCH_SCREEN* screen; ELECTRICAL_PINTYPE ii, jj; if( aDiag == OK || aMinConn < 1 ) return; /* Create new marker for ERC error. */ marker = new SCH_MARKER(); marker->SetTimeStamp( GetNewTimeStamp() ); marker->SetMarkerType( MARKER_BASE::MARKER_ERC ); marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_WARNING ); screen = aNetItemRef->m_SheetPath.LastScreen(); screen->Append( marker ); wxString msg; ii = aNetItemRef->m_ElectricalPinType; wxString cmp_ref( "?" ); if( aNetItemRef->m_Type == NET_PIN && aNetItemRef->m_Link ) cmp_ref = aNetItemRef->GetComponentParent()->GetRef( &aNetItemRef->m_SheetPath ); if( aNetItemTst == NULL ) { if( aMinConn == NOD ) /* Nothing driving the net. */ { if( aNetItemRef->m_Type == NET_PIN && aNetItemRef->m_Link ) cmp_ref = aNetItemRef->GetComponentParent()->GetRef( &aNetItemRef->m_SheetPath ); msg.Printf( _( "Pin %s (%s) of component %s is not driven (Net %d)." ), aNetItemRef->m_PinNum, GetChars( GetText( ii ) ), GetChars( cmp_ref ), aNetItemRef->GetNet() ); marker->SetData( ERCE_PIN_NOT_DRIVEN, aNetItemRef->m_Start, msg, aNetItemRef->m_Start ); return; } } if( aNetItemTst ) /* Error between 2 pins */ { jj = aNetItemTst->m_ElectricalPinType; int errortype = ERCE_PIN_TO_PIN_WARNING; if( aDiag == ERR ) { marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_ERROR ); errortype = ERCE_PIN_TO_PIN_ERROR; } wxString alt_cmp( "?" ); if( aNetItemTst->m_Type == NET_PIN && aNetItemTst->m_Link ) alt_cmp = aNetItemTst->GetComponentParent()->GetRef( &aNetItemTst->m_SheetPath ); msg.Printf( _( "Pin %s (%s) of component %s is connected to " ), aNetItemRef->m_PinNum, GetChars( GetText( ii ) ), GetChars( cmp_ref ) ); marker->SetData( errortype, aNetItemRef->m_Start, msg, aNetItemRef->m_Start ); msg.Printf( _( "pin %s (%s) of component %s (net %d)." ), aNetItemTst->m_PinNum, GetChars( GetText( jj ) ), GetChars( alt_cmp ), aNetItemRef->GetNet() ); marker->SetAuxiliaryData( msg, aNetItemTst->m_Start ); } }
int TestMultiunitFootprints( SCH_SHEET_LIST& aSheetList ) { int errors = 0; std::map<wxString, LIB_ID> footprints; SCH_MULTI_UNIT_REFERENCE_MAP refMap; aSheetList.GetMultiUnitComponents( refMap, true ); for( auto& component : refMap ) { auto& refList = component.second; if( refList.GetCount() == 0 ) { wxFAIL; // it should not happen continue; } // Reference footprint wxString fp; wxString unitName; for( unsigned i = 0; i < component.second.GetCount(); ++i ) { SCH_COMPONENT* cmp = refList.GetItem( i ).GetComp(); SCH_SHEET_PATH sheetPath = refList.GetItem( i ).GetSheetPath(); fp = cmp->GetField( FOOTPRINT )->GetText(); if( !fp.IsEmpty() ) { unitName = cmp->GetRef( &sheetPath ) + LIB_PART::SubReference( cmp->GetUnit(), false ); break; } } for( unsigned i = 0; i < component.second.GetCount(); ++i ) { SCH_REFERENCE& ref = refList.GetItem( i ); SCH_COMPONENT* unit = ref.GetComp(); SCH_SHEET_PATH sheetPath = refList.GetItem( i ).GetSheetPath(); const wxString curFp = unit->GetField( FOOTPRINT )->GetText(); if( !curFp.IsEmpty() && fp != curFp ) { wxString curUnitName = unit->GetRef( &sheetPath ) + LIB_PART::SubReference( unit->GetUnit(), false ); wxString msg = wxString::Format( _( "Unit %s has '%s' assigned, " "whereas unit %s has '%s' assigned" ), unitName, fp, curUnitName, curFp ); wxPoint pos = unit->GetPosition(); SCH_MARKER* marker = new SCH_MARKER(); marker->SetTimeStamp( GetNewTimeStamp() ); marker->SetData( ERCE_DIFFERENT_UNIT_FP, pos, msg, pos ); marker->SetMarkerType( MARKER_BASE::MARKER_ERC ); marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_WARNING ); ref.GetSheetPath().LastScreen()->Append( marker ); ++errors; } } } return errors; }