Browse Source

Add hasExactNetclass function to DRC condition language

Following changes to the `A.NetClass == '<netclass>'` semantics to
match on exact netclass name OR any constituent netclass names, we
can have conditions where constituent netclass constraints match
before the composite netclass constraints in the DRC engine. This
adds the functionality to match on the exact full netclass name, and
modifies the implicit netclass DRC rules to use this function in
their rule condition.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/20797

(cherry picked from commit c25264528c)
pull/18/head
JamesJCode 8 months ago
parent
commit
1400eb7902
  1. 2
      pcbnew/drc/drc_engine.cpp
  2. 41
      pcbnew/pcbexpr_functions.cpp

2
pcbnew/drc/drc_engine.cpp

@ -255,7 +255,7 @@ void DRC_ENGINE::loadImplicitRules()
_( "netclass '%s'" ), nc->GetClearanceParent()->GetHumanReadableName() );
netclassRule->m_Implicit = true;
expr = wxString::Format( wxT( "A.NetClass == '%s'" ), ncName );
expr = wxString::Format( wxT( "A.hasExactNetclass('%s')" ), ncName );
netclassRule->m_Condition = new DRC_RULE_CONDITION( expr );
netclassClearanceRules.push_back( netclassRule );

41
pcbnew/pcbexpr_functions.cpp

@ -1301,6 +1301,46 @@ static void hasNetclassFunc( LIBEVAL::CONTEXT* aCtx, void* self )
} );
}
static void hasExactNetclassFunc( LIBEVAL::CONTEXT* aCtx, void* self )
{
LIBEVAL::VALUE* arg = aCtx->Pop();
LIBEVAL::VALUE* result = aCtx->AllocValue();
result->Set( 0.0 );
aCtx->Push( result );
if( !arg || arg->AsString().IsEmpty() )
{
if( aCtx->HasErrorCallback() )
aCtx->ReportError( _( "Missing netclass name argument to hasExactNetclass()" ) );
return;
}
PCBEXPR_VAR_REF* vref = static_cast<PCBEXPR_VAR_REF*>( self );
BOARD_ITEM* item = vref ? vref->GetObject( aCtx ) : nullptr;
if( !item )
return;
result->SetDeferredEval(
[item, arg]() -> double
{
if( !item->IsConnected() )
return 0.0;
BOARD_CONNECTED_ITEM* bcItem = static_cast<BOARD_CONNECTED_ITEM*>( item );
NETCLASS* netclass = bcItem->GetEffectiveNetClass();
if( netclass->GetName() == arg->AsString() )
return 1.0;
return 0.0;
} );
}
static void hasComponentClassFunc( LIBEVAL::CONTEXT* aCtx, void* self )
{
LIBEVAL::VALUE* arg = aCtx->Pop();
@ -1388,5 +1428,6 @@ void PCBEXPR_BUILTIN_FUNCTIONS::RegisterAllFunctions()
RegisterFunc( wxT( "getField('x')" ), getFieldFunc );
RegisterFunc( wxT( "hasNetclass('x')" ), hasNetclassFunc );
RegisterFunc( wxT( "hasExactNetclass('x')" ), hasExactNetclassFunc );
RegisterFunc( wxT( "hasComponentClass('x')" ), hasComponentClassFunc );
}
Loading…
Cancel
Save