ADDED: ERC check for missing hier labels for sheet ports

A subsheet may have more than one instance of a hier label,
but it's generally a mistake if there is no matching hier label
for a port on the parent sheet.

This is harder to do today now that we don't have manual tool
for placing hier ports, but it's still possible if you place
ports but then rename the label on the subsheet.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/3468
This commit is contained in:
Jon Evans 2020-08-25 21:52:52 -04:00
parent f50dba6b62
commit d40ae3de46
3 changed files with 68 additions and 0 deletions

View File

@ -54,6 +54,9 @@ PANEL_SETUP_SEVERITIES::PANEL_SETUP_SEVERITIES( PAGED_DIALOG* aParent,
int errorCode = item.GetErrorCode(); int errorCode = item.GetErrorCode();
wxString msg = item.GetErrorText(); wxString msg = item.GetErrorText();
if( m_pinMapSpecialCase && errorCode == m_pinMapSpecialCase->GetErrorCode() )
continue;
// When msg is empty, for some reason, the current errorCode is not supported // When msg is empty, for some reason, the current errorCode is not supported
// by the RC_ITEM aDummyItem. // by the RC_ITEM aDummyItem.
// Skip this errorCode. // Skip this errorCode.

View File

@ -393,6 +393,8 @@ void CONNECTION_GRAPH::Recalculate( const SCH_SHEET_LIST& aSheetList, bool aUnco
PROF_COUNTER update_items( "updateItemConnectivity" ); PROF_COUNTER update_items( "updateItemConnectivity" );
m_sheetList = aSheetList;
for( const SCH_SHEET_PATH& sheet : aSheetList ) for( const SCH_SHEET_PATH& sheet : aSheetList )
{ {
std::vector<SCH_ITEM*> items; std::vector<SCH_ITEM*> items;
@ -2075,6 +2077,10 @@ int CONNECTION_GRAPH::RunERC()
error_count++; error_count++;
} }
// Hierarchical sheet checking is done at the schematic level
if( settings.IsTestEnabled( ERCE_HIERACHICAL_LABEL ) )
error_count += ercCheckHierSheets();
return error_count; return error_count;
} }
@ -2561,3 +2567,50 @@ bool CONNECTION_GRAPH::ercCheckLabels( const CONNECTION_SUBGRAPH* aSubgraph )
return true; return true;
} }
int CONNECTION_GRAPH::ercCheckHierSheets()
{
int errors = 0;
for( const SCH_SHEET_PATH& sheet : m_sheetList )
{
for( SCH_ITEM* item : sheet.LastScreen()->Items() )
{
if( item->Type() != SCH_SHEET_T )
continue;
SCH_SHEET* parentSheet = static_cast<SCH_SHEET*>( item );
std::map<wxString, SCH_SHEET_PIN*> pins;
for( SCH_SHEET_PIN* pin : parentSheet->GetPins() )
pins[pin->GetText()] = pin;
for( SCH_ITEM* subItem : parentSheet->GetScreen()->Items() )
{
if( subItem->Type() == SCH_HIER_LABEL_T )
{
SCH_HIERLABEL* label = static_cast<SCH_HIERLABEL*>( subItem );
pins.erase( label->GetText() );
}
}
for( const std::pair<const wxString, SCH_SHEET_PIN*>& unmatched : pins )
{
std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_HIERACHICAL_LABEL );
ercItem->SetItems( unmatched.second );
ercItem->SetErrorMessage( wxString::Format(
_( "Sheet port %s has no matching hierarchical label inside the sheet" ),
unmatched.first ) );
SCH_MARKER* marker = new SCH_MARKER( ercItem, unmatched.second->GetPosition() );
sheet.LastScreen()->Append( marker );
errors++;
}
}
}
return errors;
}

View File

@ -301,7 +301,10 @@ public:
static bool m_allowRealTime; static bool m_allowRealTime;
private: private:
// All the sheets in the schematic (as long as we don't have partial updates)
SCH_SHEET_LIST m_sheetList;
// All connectable items in the schematic
std::vector<SCH_ITEM*> m_items; std::vector<SCH_ITEM*> m_items;
// The owner of all CONNECTION_SUBGRAPH objects // The owner of all CONNECTION_SUBGRAPH objects
@ -502,6 +505,15 @@ private:
*/ */
bool ercCheckLabels( const CONNECTION_SUBGRAPH* aSubgraph ); bool ercCheckLabels( const CONNECTION_SUBGRAPH* aSubgraph );
/**
* Checks that a hierarchical sheet has at least one matching label inside the sheet for each
* port on the parent sheet object
*
* @param aSubgraph is the subgraph to examine
* @return the number of errors found
*/
int ercCheckHierSheets();
}; };
#endif #endif