ADDED memberOfFootprint() to DRC custom rules functions.

Also added memberOfGroup(), and deprecated memberOf().
This commit is contained in:
Jeff Young 2023-04-12 13:53:43 +01:00
parent 66f48d56ae
commit e1c9e0e6fc
5 changed files with 82 additions and 8 deletions

View File

@ -606,7 +606,8 @@ void DIALOG_DRC::OnDRCItemRClick( wxDataViewEvent& aEvent )
|| rcItem->GetErrorCode() == DRCE_ANNULAR_WIDTH
|| rcItem->GetErrorCode() == DRCE_DRILL_OUT_OF_RANGE
|| rcItem->GetErrorCode() == DRCE_MICROVIA_DRILL_OUT_OF_RANGE
|| rcItem->GetErrorCode() == DRCE_CONNECTION_WIDTH )
|| rcItem->GetErrorCode() == DRCE_CONNECTION_WIDTH
|| rcItem->GetErrorCode() == DRCE_ASSERTION_FAILURE )
{
menu.Append( 3, _( "Run Inspect > Constraints Resolution" ) );
}

View File

@ -176,8 +176,14 @@ matches items in the `/CLK_P` and `/CLK_N` nets.
True if `A` and `B` are members of the same diff pair.
<br><br>
A.memberOf('<group_name>')
True if `A` is a member of the given group. Includes nested membership.
A.memberOfGroup('<group_name>')
True if `A` is a member of the given group. The name can contain wildcards.
Includes nested membership.
<br><br>
A.memberOfFootprint('<footprint_reference>')
True if `A` is a member of a footprint matching the given reference designator. The
reference can contain wildcards.
<br><br>
A.existsOnLayer('<layer_name>')
@ -188,6 +194,10 @@ the canonical name (ie: `F.Cu`).
NB: this returns true if `A` is on the given layer, independently
of whether or not the rule is being evaluated for that layer.
For the latter use a `(layer "layer_name")` clause in the rule.
<br><br>
!!! A.memberOf('<group_name>') !!!
Deprecated; use `memberOfGroup()` instead.
<br><br>
!!! A.insideCourtyard('<footprint_refdes>') !!!

View File

@ -177,8 +177,14 @@ _HKI( "### Top-level Clauses\n"
"True if `A` and `B` are members of the same diff pair.\n"
"<br><br>\n"
"\n"
" A.memberOf('<group_name>')\n"
"True if `A` is a member of the given group. Includes nested membership.\n"
" A.memberOfGroup('<group_name>')\n"
"True if `A` is a member of the given group. The name can contain wildcards.\n"
"Includes nested membership.\n"
"<br><br>\n"
"\n"
" A.memberOfFootprint('<footprint_reference>')\n"
"True if `A` is a member of a footprint matching the given reference designator. The\n"
"reference can contain wildcards.\n"
"<br><br>\n"
"\n"
" A.existsOnLayer('<layer_name>')\n"
@ -191,6 +197,10 @@ _HKI( "### Top-level Clauses\n"
"For the latter use a `(layer \"layer_name\")` clause in the rule.\n"
"<br><br>\n"
"\n"
" !!! A.memberOf('<group_name>') !!!\n"
"Deprecated; use `memberOfGroup()` instead.\n"
"<br><br>\n"
"\n"
" !!! A.insideCourtyard('<footprint_refdes>') !!!\n"
"Deprecated; use `intersectsCourtyard()` instead.\n"
"<br><br>\n"

View File

@ -755,7 +755,7 @@ static void enclosedByAreaFunc( LIBEVAL::CONTEXT* aCtx, void* self )
#define MISSING_GROUP_ARG( f ) \
wxString::Format( _( "Missing group name argument to %s." ), f )
static void memberOfFunc( LIBEVAL::CONTEXT* aCtx, void* self )
static void memberOfGroupFunc( LIBEVAL::CONTEXT* aCtx, void* self )
{
LIBEVAL::VALUE* arg = aCtx->Pop();
LIBEVAL::VALUE* result = aCtx->AllocValue();
@ -766,7 +766,7 @@ static void memberOfFunc( LIBEVAL::CONTEXT* aCtx, void* self )
if( !arg )
{
if( aCtx->HasErrorCallback() )
aCtx->ReportError( MISSING_GROUP_ARG( wxT( "memberOf()" ) ) );
aCtx->ReportError( MISSING_GROUP_ARG( wxT( "memberOfGroup()" ) ) );
return;
}
@ -798,6 +798,47 @@ static void memberOfFunc( LIBEVAL::CONTEXT* aCtx, void* self )
}
#define MISSING_REF_ARG( f ) \
wxString::Format( _( "Missing footprint argument (reference designator) to %s." ), f )
static void memberOfFootprintFunc( LIBEVAL::CONTEXT* aCtx, void* self )
{
LIBEVAL::VALUE* arg = aCtx->Pop();
LIBEVAL::VALUE* result = aCtx->AllocValue();
result->Set( 0.0 );
aCtx->Push( result );
if( !arg )
{
if( aCtx->HasErrorCallback() )
aCtx->ReportError( MISSING_REF_ARG( wxT( "memberOfFootprint()" ) ) );
return;
}
PCB_EXPR_VAR_REF* vref = static_cast<PCB_EXPR_VAR_REF*>( self );
BOARD_ITEM* item = vref ? vref->GetObject( aCtx ) : nullptr;
if( !item )
return;
result->SetDeferredEval(
[item, arg]() -> double
{
;
if( FOOTPRINT* parentFP = item->GetParentFootprint() )
{
if( parentFP->GetReference().Matches( arg->AsString() ) )
return 1.0;
}
return 0.0;
} );
}
static void isMicroVia( LIBEVAL::CONTEXT* aCtx, void* self )
{
PCB_EXPR_VAR_REF* vref = static_cast<PCB_EXPR_VAR_REF*>( self );
@ -988,7 +1029,9 @@ void PCB_EXPR_BUILTIN_FUNCTIONS::RegisterAllFunctions()
RegisterFunc( wxT( "isMicroVia()" ), isMicroVia );
RegisterFunc( wxT( "isBlindBuriedVia()" ), isBlindBuriedViaFunc );
RegisterFunc( wxT( "memberOf('x')" ), memberOfFunc );
RegisterFunc( wxT( "memberOf('x') DEPRECATED" ), memberOfGroupFunc );
RegisterFunc( wxT( "memberOfGroup('x')" ), memberOfGroupFunc );
RegisterFunc( wxT( "memberOfFootprint('x')" ), memberOfFootprintFunc );
RegisterFunc( wxT( "fromTo('x','y')" ), fromToFunc );
RegisterFunc( wxT( "isCoupledDiffPair()" ), isCoupledDiffPairFunc );

View File

@ -543,6 +543,16 @@ void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr<RC_ITEM>& aDR
break;
case DRCE_ASSERTION_FAILURE:
r = dialog->AddHTMLPage( _( "Assertions" ) );
reportHeader( _( "Assertions for:" ), a, r );
if( compileError )
reportCompileError( r );
drcEngine.ProcessAssertions( a, []( const DRC_CONSTRAINT* c ){}, r );
break;
default:
return;
}