Tag geometry-dependent DRC functions at registration
The geometry-dependent function set in CreateFuncCall was a hardcoded copy of names that had to be manually synchronized with RegisterAllFunctions. Adding a new geometry-dependent function without updating both lists would silently skip per-segment DRC evaluation for rules using that function. Add an isGeometryDependent flag to RegisterFunc and query it from CreateFuncCall so there is a single source of truth.
This commit is contained in:
@@ -530,21 +530,13 @@ LIBEVAL::VALUE* PCBEXPR_TYPE_REF::GetValue( LIBEVAL::CONTEXT* aCtx )
|
||||
|
||||
LIBEVAL::FUNC_CALL_REF PCBEXPR_UCODE::CreateFuncCall( const wxString& aName )
|
||||
{
|
||||
static const std::set<wxString> geometryFunctions = {
|
||||
wxT( "intersectscourtyard" ), wxT( "intersectsfrontcourtyard" ),
|
||||
wxT( "intersectsbackcourtyard" ), wxT( "intersectsarea" ),
|
||||
wxT( "enclosedbyarea" ),
|
||||
wxT( "insidecourtyard" ), wxT( "insidefrontcourtyard" ),
|
||||
wxT( "insidebackcourtyard" ), wxT( "insidearea" )
|
||||
};
|
||||
|
||||
wxString nameLower = aName.Lower();
|
||||
|
||||
if( geometryFunctions.count( nameLower ) )
|
||||
m_hasGeometryDependentFunctions = true;
|
||||
|
||||
PCBEXPR_BUILTIN_FUNCTIONS& registry = PCBEXPR_BUILTIN_FUNCTIONS::Instance();
|
||||
|
||||
if( registry.IsGeometryDependent( nameLower ) )
|
||||
m_hasGeometryDependentFunctions = true;
|
||||
|
||||
return registry.Get( nameLower );
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#ifndef PCBEXPR_EVALUATOR_H
|
||||
#define PCBEXPR_EVALUATOR_H
|
||||
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <layer_ids.h>
|
||||
@@ -195,22 +196,33 @@ public:
|
||||
return m_funcs[ name ];
|
||||
}
|
||||
|
||||
bool IsGeometryDependent( const wxString& name ) const
|
||||
{
|
||||
return m_geometryDependentFuncs.count( name ) > 0;
|
||||
}
|
||||
|
||||
const wxArrayString GetSignatures() const
|
||||
{
|
||||
return m_funcSigs;
|
||||
}
|
||||
|
||||
void RegisterFunc( const wxString& funcSignature, LIBEVAL::FUNC_CALL_REF funcPtr )
|
||||
void RegisterFunc( const wxString& funcSignature, LIBEVAL::FUNC_CALL_REF funcPtr,
|
||||
bool aIsGeometryDependent = false )
|
||||
{
|
||||
wxString funcName = funcSignature.BeforeFirst( '(' );
|
||||
m_funcs[std::string( funcName.Lower() )] = std::move( funcPtr );
|
||||
wxString lower = funcName.Lower();
|
||||
m_funcs[std::string( lower )] = std::move( funcPtr );
|
||||
m_funcSigs.Add( funcSignature );
|
||||
|
||||
if( aIsGeometryDependent )
|
||||
m_geometryDependentFuncs.insert( lower );
|
||||
}
|
||||
|
||||
void RegisterAllFunctions();
|
||||
|
||||
private:
|
||||
std::map<wxString, LIBEVAL::FUNC_CALL_REF> m_funcs;
|
||||
std::set<wxString> m_geometryDependentFuncs;
|
||||
|
||||
wxArrayString m_funcSigs;
|
||||
};
|
||||
|
||||
@@ -1505,19 +1505,18 @@ void PCBEXPR_BUILTIN_FUNCTIONS::RegisterAllFunctions()
|
||||
|
||||
RegisterFunc( wxT( "isPlated()" ), isPlatedFunc );
|
||||
|
||||
// When adding new geometry-dependent functions (functions whose result depends on item
|
||||
// position/shape rather than item properties), also add the function name to the
|
||||
// geometryFunctions set in PCBEXPR_UCODE::CreateFuncCall() (pcbexpr_evaluator.cpp).
|
||||
RegisterFunc( wxT( "insideCourtyard('x') DEPRECATED" ), intersectsCourtyardFunc );
|
||||
RegisterFunc( wxT( "insideFrontCourtyard('x') DEPRECATED" ), intersectsFrontCourtyardFunc );
|
||||
RegisterFunc( wxT( "insideBackCourtyard('x') DEPRECATED" ), intersectsBackCourtyardFunc );
|
||||
RegisterFunc( wxT( "intersectsCourtyard('x')" ), intersectsCourtyardFunc );
|
||||
RegisterFunc( wxT( "intersectsFrontCourtyard('x')" ), intersectsFrontCourtyardFunc );
|
||||
RegisterFunc( wxT( "intersectsBackCourtyard('x')" ), intersectsBackCourtyardFunc );
|
||||
// Geometry-dependent functions depend on item position/shape rather than item properties.
|
||||
// The third argument marks them so that CreateFuncCall() can detect them automatically.
|
||||
RegisterFunc( wxT( "insideCourtyard('x') DEPRECATED" ), intersectsCourtyardFunc, true );
|
||||
RegisterFunc( wxT( "insideFrontCourtyard('x') DEPRECATED" ), intersectsFrontCourtyardFunc, true );
|
||||
RegisterFunc( wxT( "insideBackCourtyard('x') DEPRECATED" ), intersectsBackCourtyardFunc, true );
|
||||
RegisterFunc( wxT( "intersectsCourtyard('x')" ), intersectsCourtyardFunc, true );
|
||||
RegisterFunc( wxT( "intersectsFrontCourtyard('x')" ), intersectsFrontCourtyardFunc, true );
|
||||
RegisterFunc( wxT( "intersectsBackCourtyard('x')" ), intersectsBackCourtyardFunc, true );
|
||||
|
||||
RegisterFunc( wxT( "insideArea('x') DEPRECATED" ), intersectsAreaFunc );
|
||||
RegisterFunc( wxT( "intersectsArea('x')" ), intersectsAreaFunc );
|
||||
RegisterFunc( wxT( "enclosedByArea('x')" ), enclosedByAreaFunc );
|
||||
RegisterFunc( wxT( "insideArea('x') DEPRECATED" ), intersectsAreaFunc, true );
|
||||
RegisterFunc( wxT( "intersectsArea('x')" ), intersectsAreaFunc, true );
|
||||
RegisterFunc( wxT( "enclosedByArea('x')" ), enclosedByAreaFunc, true );
|
||||
|
||||
RegisterFunc( wxT( "isMicroVia()" ), isMicroVia );
|
||||
RegisterFunc( wxT( "isBlindVia()" ), isBlindVia );
|
||||
|
||||
Reference in New Issue
Block a user