Report all implicit rules for resolution reports.

This commit is contained in:
Jeff Young 2020-10-15 20:18:49 +01:00
parent 19155edde0
commit 6b7749658e
2 changed files with 128 additions and 86 deletions

View File

@ -617,101 +617,120 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRulesForItems( DRC_CONSTRAINT_TYPE_T aConstraintI
}
}
auto processConstraint =
[&]( const CONSTRAINT_WITH_CONDITIONS* c )
{
implicit = c->parentRule && c->parentRule->m_Implicit;
REPORT( "" )
if( aConstraintId == DRC_CONSTRAINT_TYPE_CLEARANCE )
{
int clearance = c->constraint.m_Value.Min();
REPORT( wxString::Format( _( "Checking %s; clearance: %s." ),
c->constraint.GetName(),
MessageTextFromValue( UNITS, clearance ) ) )
}
else if( aConstraintId == DRC_CONSTRAINT_TYPE_COURTYARD_CLEARANCE )
{
int clearance = c->constraint.m_Value.Min();
REPORT( wxString::Format( _( "Checking %s; courtyard clearance: %s." ),
c->constraint.GetName(),
MessageTextFromValue( UNITS, clearance ) ) )
}
else if( aConstraintId == DRC_CONSTRAINT_TYPE_SILK_CLEARANCE )
{
int clearance = c->constraint.m_Value.Min();
REPORT( wxString::Format( _( "Checking %s; silk clearance: %s." ),
c->constraint.GetName(),
MessageTextFromValue( UNITS, clearance ) ) )
}
else if( aConstraintId == DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE )
{
int clearance = c->constraint.m_Value.Min();
REPORT( wxString::Format( _( "Checking %s; hole clearance: %s." ),
c->constraint.GetName(),
MessageTextFromValue( UNITS, clearance ) ) )
}
else if( aConstraintId == DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE )
{
int clearance = c->constraint.m_Value.Min();
REPORT( wxString::Format( _( "Checking %s; edge clearance: %s." ),
c->constraint.GetName(),
MessageTextFromValue( UNITS, clearance ) ) )
}
else
{
REPORT( wxString::Format( _( "Checking %s." ),
c->constraint.GetName() ) )
}
if( aLayer != UNDEFINED_LAYER && !c->layerTest.test( aLayer ) )
{
if( c->parentRule )
{
REPORT( wxString::Format( _( "Rule layer \"%s\" not matched." ),
c->parentRule->m_LayerSource ) )
REPORT( "Rule ignored." )
}
return false;
}
if( !c->condition || c->condition->GetExpression().IsEmpty() )
{
REPORT( implicit ? _( "Unconditional constraint applied." )
: _( "Unconditional rule applied." ) );
constraintRef = &c->constraint;
return true;
}
else
{
// Don't report on implicit rule conditions; they're synthetic.
if( !implicit )
{
REPORT( wxString::Format( _( "Checking rule condition \"%s\"." ),
c->condition->GetExpression() ) )
}
if( c->condition->EvaluateFor( a, b, aLayer, aReporter ) )
{
REPORT( implicit ? _( "Constraint applied." )
: _( "Rule applied; overrides previous constraints." ) )
constraintRef = &c->constraint;
return true;
}
else
{
REPORT( implicit ? _( "Membership not satisfied; constraint ignored." )
: _( "Condition not satisfied; rule ignored." ) )
return false;
}
}
};
if( m_constraintMap.count( aConstraintId ) )
{
std::vector<CONSTRAINT_WITH_CONDITIONS*>* ruleset = m_constraintMap[ aConstraintId ];
// Last matching rule wins, so process in reverse order
for( int ii = (int) ruleset->size() - 1; ii >= 0; --ii )
if( aReporter )
{
const CONSTRAINT_WITH_CONDITIONS* rcons = ruleset->at( ii );
implicit = rcons->parentRule && rcons->parentRule->m_Implicit;
REPORT( "" )
if( aConstraintId == DRC_CONSTRAINT_TYPE_CLEARANCE )
// We want to see all results so process in "natural" order
for( int ii = 0; ii < (int) ruleset->size(); ++ii )
{
int clearance = rcons->constraint.m_Value.Min();
REPORT( wxString::Format( _( "Checking %s; clearance: %s." ),
rcons->constraint.GetName(),
MessageTextFromValue( UNITS, clearance ) ) )
processConstraint( ruleset->at( ii ) );
}
else if( aConstraintId == DRC_CONSTRAINT_TYPE_COURTYARD_CLEARANCE )
}
else
{
// Last matching rule wins, so process in reverse order and quit when match found
for( int ii = (int) ruleset->size() - 1; ii >= 0; --ii )
{
int clearance = rcons->constraint.m_Value.Min();
REPORT( wxString::Format( _( "Checking %s; courtyard clearance: %s." ),
rcons->constraint.GetName(),
MessageTextFromValue( UNITS, clearance ) ) )
}
else if( aConstraintId == DRC_CONSTRAINT_TYPE_SILK_CLEARANCE )
{
int clearance = rcons->constraint.m_Value.Min();
REPORT( wxString::Format( _( "Checking %s; silk clearance: %s." ),
rcons->constraint.GetName(),
MessageTextFromValue( UNITS, clearance ) ) )
}
else if( aConstraintId == DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE )
{
int clearance = rcons->constraint.m_Value.Min();
REPORT( wxString::Format( _( "Checking %s; hole clearance: %s." ),
rcons->constraint.GetName(),
MessageTextFromValue( UNITS, clearance ) ) )
}
else if( aConstraintId == DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE )
{
int clearance = rcons->constraint.m_Value.Min();
REPORT( wxString::Format( _( "Checking %s; edge clearance: %s." ),
rcons->constraint.GetName(),
MessageTextFromValue( UNITS, clearance ) ) )
}
else
{
REPORT( wxString::Format( _( "Checking %s." ),
rcons->constraint.GetName() ) )
}
if( aLayer != UNDEFINED_LAYER && !rcons->layerTest.test( aLayer ) )
{
if( rcons->parentRule )
{
REPORT( wxString::Format( _( "Rule layer \"%s\" not matched." ),
rcons->parentRule->m_LayerSource ) )
REPORT( "Rule ignored." )
}
continue;
}
if( !rcons->condition || rcons->condition->GetExpression().IsEmpty() )
{
REPORT( implicit ? _( "Unconditional constraint applied." )
: _( "Unconditional rule applied." ) )
constraintRef = &rcons->constraint;
break;
}
else
{
// Don't report on implicit rule conditions; they're synthetic.
if( !implicit )
{
REPORT( wxString::Format( _( "Checking rule condition \"%s\"." ),
rcons->condition->GetExpression() ) )
}
if( rcons->condition->EvaluateFor( a, b, aLayer, aReporter ) )
{
REPORT( implicit ? _( "Constraint applied." )
: _( "Rule applied. (No further rules will be checked.)" ) )
constraintRef = &rcons->constraint;
if( processConstraint( ruleset->at( ii ) ) )
break;
}
else
{
REPORT( implicit ? _( "Membership not satisfied; constraint ignored." )
: _( "Condition not satisfied; rule ignored." ) )
}
}
}
}

View File

@ -253,6 +253,29 @@ int PCB_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
BOARD_ITEM* a = static_cast<BOARD_ITEM*>( selection.GetItem( 0 ) );
BOARD_ITEM* b = static_cast<BOARD_ITEM*>( selection.GetItem( 1 ) );
if( a->Type() == PCB_TRACE_T || a->Type() == PCB_ARC_T )
layer = a->GetLayer();
else if( b->Type() == PCB_TRACE_T || b->Type() == PCB_ARC_T )
layer = b->GetLayer();
else if( a->Type() == PCB_PAD_T && static_cast<D_PAD*>( a )->GetAttribute() == PAD_ATTRIB_SMD )
{
D_PAD* pad = static_cast<D_PAD*>( a );
if( pad->GetAttribute() == PAD_ATTRIB_SMD && pad->IsOnLayer( F_Cu ) )
layer = F_Cu;
else
layer = B_Cu;
}
else if( b->Type() == PCB_PAD_T )
{
D_PAD* pad = static_cast<D_PAD*>( b );
if( pad->GetAttribute() == PAD_ATTRIB_SMD && pad->IsOnLayer( F_Cu ) )
layer = F_Cu;
else
layer = B_Cu;
}
if( a->Type() != PCB_ZONE_AREA_T && b->Type() == PCB_ZONE_AREA_T )
std::swap( a, b );
else if( !a->IsConnected() && b->IsConnected() )