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_ANNULAR_WIDTH
|| rcItem->GetErrorCode() == DRCE_DRILL_OUT_OF_RANGE || rcItem->GetErrorCode() == DRCE_DRILL_OUT_OF_RANGE
|| rcItem->GetErrorCode() == DRCE_MICROVIA_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" ) ); 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. True if `A` and `B` are members of the same diff pair.
<br><br> <br><br>
A.memberOf('<group_name>') A.memberOfGroup('<group_name>')
True if `A` is a member of the given group. Includes nested membership. 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> <br><br>
A.existsOnLayer('<layer_name>') 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 NB: this returns true if `A` is on the given layer, independently
of whether or not the rule is being evaluated for that layer. of whether or not the rule is being evaluated for that layer.
For the latter use a `(layer "layer_name")` clause in the rule. For the latter use a `(layer "layer_name")` clause in the rule.
<br><br>
!!! A.memberOf('<group_name>') !!!
Deprecated; use `memberOfGroup()` instead.
<br><br> <br><br>
!!! A.insideCourtyard('<footprint_refdes>') !!! !!! 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" "True if `A` and `B` are members of the same diff pair.\n"
"<br><br>\n" "<br><br>\n"
"\n" "\n"
" A.memberOf('<group_name>')\n" " A.memberOfGroup('<group_name>')\n"
"True if `A` is a member of the given group. Includes nested membership.\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" "<br><br>\n"
"\n" "\n"
" A.existsOnLayer('<layer_name>')\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" "For the latter use a `(layer \"layer_name\")` clause in the rule.\n"
"<br><br>\n" "<br><br>\n"
"\n" "\n"
" !!! A.memberOf('<group_name>') !!!\n"
"Deprecated; use `memberOfGroup()` instead.\n"
"<br><br>\n"
"\n"
" !!! A.insideCourtyard('<footprint_refdes>') !!!\n" " !!! A.insideCourtyard('<footprint_refdes>') !!!\n"
"Deprecated; use `intersectsCourtyard()` instead.\n" "Deprecated; use `intersectsCourtyard()` instead.\n"
"<br><br>\n" "<br><br>\n"

View File

@ -755,7 +755,7 @@ static void enclosedByAreaFunc( LIBEVAL::CONTEXT* aCtx, void* self )
#define MISSING_GROUP_ARG( f ) \ #define MISSING_GROUP_ARG( f ) \
wxString::Format( _( "Missing group name argument to %s." ), 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* arg = aCtx->Pop();
LIBEVAL::VALUE* result = aCtx->AllocValue(); LIBEVAL::VALUE* result = aCtx->AllocValue();
@ -766,7 +766,7 @@ static void memberOfFunc( LIBEVAL::CONTEXT* aCtx, void* self )
if( !arg ) if( !arg )
{ {
if( aCtx->HasErrorCallback() ) if( aCtx->HasErrorCallback() )
aCtx->ReportError( MISSING_GROUP_ARG( wxT( "memberOf()" ) ) ); aCtx->ReportError( MISSING_GROUP_ARG( wxT( "memberOfGroup()" ) ) );
return; 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 ) static void isMicroVia( LIBEVAL::CONTEXT* aCtx, void* self )
{ {
PCB_EXPR_VAR_REF* vref = static_cast<PCB_EXPR_VAR_REF*>( 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( "isMicroVia()" ), isMicroVia );
RegisterFunc( wxT( "isBlindBuriedVia()" ), isBlindBuriedViaFunc ); 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( "fromTo('x','y')" ), fromToFunc );
RegisterFunc( wxT( "isCoupledDiffPair()" ), isCoupledDiffPairFunc ); RegisterFunc( wxT( "isCoupledDiffPair()" ), isCoupledDiffPairFunc );

View File

@ -543,6 +543,16 @@ void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr<RC_ITEM>& aDR
break; 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: default:
return; return;
} }