|
|
|
@ -26,27 +26,27 @@ |
|
|
|
#include <memory>
|
|
|
|
#include <board.h>
|
|
|
|
#include <board_connected_item.h>
|
|
|
|
#include <pcb_expr_evaluator.h>
|
|
|
|
#include <pcbexpr_evaluator.h>
|
|
|
|
#include <drc/drc_engine.h>
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Specialized Expression References |
|
|
|
*/ |
|
|
|
|
|
|
|
BOARD_ITEM* PCB_EXPR_VAR_REF::GetObject( const LIBEVAL::CONTEXT* aCtx ) const |
|
|
|
BOARD_ITEM* PCBEXPR_VAR_REF::GetObject( const LIBEVAL::CONTEXT* aCtx ) const |
|
|
|
{ |
|
|
|
wxASSERT( dynamic_cast<const PCB_EXPR_CONTEXT*>( aCtx ) ); |
|
|
|
wxASSERT( dynamic_cast<const PCBEXPR_CONTEXT*>( aCtx ) ); |
|
|
|
|
|
|
|
const PCB_EXPR_CONTEXT* ctx = static_cast<const PCB_EXPR_CONTEXT*>( aCtx ); |
|
|
|
BOARD_ITEM* item = ctx->GetItem( m_itemIndex ); |
|
|
|
const PCBEXPR_CONTEXT* ctx = static_cast<const PCBEXPR_CONTEXT*>( aCtx ); |
|
|
|
BOARD_ITEM* item = ctx->GetItem( m_itemIndex ); |
|
|
|
return item; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
class PCB_LAYER_VALUE : public LIBEVAL::VALUE |
|
|
|
class PCBEXPR_LAYER_VALUE : public LIBEVAL::VALUE |
|
|
|
{ |
|
|
|
public: |
|
|
|
PCB_LAYER_VALUE( PCB_LAYER_ID aLayer ) : |
|
|
|
PCBEXPR_LAYER_VALUE( PCB_LAYER_ID aLayer ) : |
|
|
|
LIBEVAL::VALUE( LayerName( aLayer ) ), |
|
|
|
m_layer( aLayer ) |
|
|
|
{}; |
|
|
|
@ -59,7 +59,7 @@ public: |
|
|
|
|
|
|
|
wxPGChoices& layerMap = ENUM_MAP<PCB_LAYER_ID>::Instance().Choices(); |
|
|
|
const wxString& layerName = b->AsString(); |
|
|
|
BOARD* board = static_cast<PCB_EXPR_CONTEXT*>( aCtx )->GetBoard(); |
|
|
|
BOARD* board = static_cast<PCBEXPR_CONTEXT*>( aCtx )->GetBoard(); |
|
|
|
std::unique_lock<std::mutex> cacheLock( board->m_CachesMutex ); |
|
|
|
auto i = board->m_LayerExpressionCache.find( layerName ); |
|
|
|
LSET mask; |
|
|
|
@ -89,23 +89,23 @@ protected: |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
class PCB_NETCLASS_VALUE : public LIBEVAL::VALUE |
|
|
|
class PCBEXPR_NETCLASS_VALUE : public LIBEVAL::VALUE |
|
|
|
{ |
|
|
|
public: |
|
|
|
PCB_NETCLASS_VALUE( BOARD_CONNECTED_ITEM* aItem ) : |
|
|
|
PCBEXPR_NETCLASS_VALUE( BOARD_CONNECTED_ITEM* aItem ) : |
|
|
|
LIBEVAL::VALUE( wxEmptyString ), |
|
|
|
m_item( aItem ) |
|
|
|
{}; |
|
|
|
|
|
|
|
const wxString& AsString() const override |
|
|
|
{ |
|
|
|
const_cast<PCB_NETCLASS_VALUE*>( this )->Set( m_item->GetEffectiveNetClass()->GetName() ); |
|
|
|
const_cast<PCBEXPR_NETCLASS_VALUE*>( this )->Set( m_item->GetEffectiveNetClass()->GetName() ); |
|
|
|
return LIBEVAL::VALUE::AsString(); |
|
|
|
} |
|
|
|
|
|
|
|
bool EqualTo( LIBEVAL::CONTEXT* aCtx, const VALUE* b ) const override |
|
|
|
{ |
|
|
|
if( const PCB_NETCLASS_VALUE* bValue = dynamic_cast<const PCB_NETCLASS_VALUE*>( b ) ) |
|
|
|
if( const PCBEXPR_NETCLASS_VALUE* bValue = dynamic_cast<const PCBEXPR_NETCLASS_VALUE*>( b ) ) |
|
|
|
return m_item->GetEffectiveNetClass() == bValue->m_item->GetEffectiveNetClass(); |
|
|
|
else |
|
|
|
return LIBEVAL::VALUE::EqualTo( aCtx, b ); |
|
|
|
@ -113,7 +113,7 @@ public: |
|
|
|
|
|
|
|
bool NotEqualTo( LIBEVAL::CONTEXT* aCtx, const LIBEVAL::VALUE* b ) const override |
|
|
|
{ |
|
|
|
if( const PCB_NETCLASS_VALUE* bValue = dynamic_cast<const PCB_NETCLASS_VALUE*>( b ) ) |
|
|
|
if( const PCBEXPR_NETCLASS_VALUE* bValue = dynamic_cast<const PCBEXPR_NETCLASS_VALUE*>( b ) ) |
|
|
|
return m_item->GetEffectiveNetClass() != bValue->m_item->GetEffectiveNetClass(); |
|
|
|
else |
|
|
|
return LIBEVAL::VALUE::NotEqualTo( aCtx, b ); |
|
|
|
@ -124,23 +124,23 @@ protected: |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
class PCB_NET_VALUE : public LIBEVAL::VALUE |
|
|
|
class PCBEXPR_NET_VALUE : public LIBEVAL::VALUE |
|
|
|
{ |
|
|
|
public: |
|
|
|
PCB_NET_VALUE( BOARD_CONNECTED_ITEM* aItem ) : |
|
|
|
PCBEXPR_NET_VALUE( BOARD_CONNECTED_ITEM* aItem ) : |
|
|
|
LIBEVAL::VALUE( wxEmptyString ), |
|
|
|
m_item( aItem ) |
|
|
|
{}; |
|
|
|
|
|
|
|
const wxString& AsString() const override |
|
|
|
{ |
|
|
|
const_cast<PCB_NET_VALUE*>( this )->Set( m_item->GetNetname() ); |
|
|
|
const_cast<PCBEXPR_NET_VALUE*>( this )->Set( m_item->GetNetname() ); |
|
|
|
return LIBEVAL::VALUE::AsString(); |
|
|
|
} |
|
|
|
|
|
|
|
bool EqualTo( LIBEVAL::CONTEXT* aCtx, const VALUE* b ) const override |
|
|
|
{ |
|
|
|
if( const PCB_NET_VALUE* bValue = dynamic_cast<const PCB_NET_VALUE*>( b ) ) |
|
|
|
if( const PCBEXPR_NET_VALUE* bValue = dynamic_cast<const PCBEXPR_NET_VALUE*>( b ) ) |
|
|
|
return m_item->GetNetCode() == bValue->m_item->GetNetCode(); |
|
|
|
else |
|
|
|
return LIBEVAL::VALUE::EqualTo( aCtx, b ); |
|
|
|
@ -148,7 +148,7 @@ public: |
|
|
|
|
|
|
|
bool NotEqualTo( LIBEVAL::CONTEXT* aCtx, const LIBEVAL::VALUE* b ) const override |
|
|
|
{ |
|
|
|
if( const PCB_NET_VALUE* bValue = dynamic_cast<const PCB_NET_VALUE*>( b ) ) |
|
|
|
if( const PCBEXPR_NET_VALUE* bValue = dynamic_cast<const PCBEXPR_NET_VALUE*>( b ) ) |
|
|
|
return m_item->GetNetCode() != bValue->m_item->GetNetCode(); |
|
|
|
else |
|
|
|
return LIBEVAL::VALUE::NotEqualTo( aCtx, b ); |
|
|
|
@ -159,12 +159,12 @@ protected: |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
LIBEVAL::VALUE* PCB_EXPR_VAR_REF::GetValue( LIBEVAL::CONTEXT* aCtx ) |
|
|
|
LIBEVAL::VALUE* PCBEXPR_VAR_REF::GetValue( LIBEVAL::CONTEXT* aCtx ) |
|
|
|
{ |
|
|
|
PCB_EXPR_CONTEXT* context = static_cast<PCB_EXPR_CONTEXT*>( aCtx ); |
|
|
|
PCBEXPR_CONTEXT* context = static_cast<PCBEXPR_CONTEXT*>( aCtx ); |
|
|
|
|
|
|
|
if( m_itemIndex == 2 ) |
|
|
|
return new PCB_LAYER_VALUE( context->GetLayer() ); |
|
|
|
return new PCBEXPR_LAYER_VALUE( context->GetLayer() ); |
|
|
|
|
|
|
|
BOARD_ITEM* item = GetObject( aCtx ); |
|
|
|
|
|
|
|
@ -202,9 +202,9 @@ LIBEVAL::VALUE* PCB_EXPR_VAR_REF::GetValue( LIBEVAL::CONTEXT* aCtx ) |
|
|
|
if( it->second->Name() == wxT( "Layer" ) ) |
|
|
|
{ |
|
|
|
if( any.GetAs<PCB_LAYER_ID>( &layer ) ) |
|
|
|
return new PCB_LAYER_VALUE( layer ); |
|
|
|
return new PCBEXPR_LAYER_VALUE( layer ); |
|
|
|
else if( any.GetAs<wxString>( &str ) ) |
|
|
|
return new PCB_LAYER_VALUE( context->GetBoard()->GetLayerID( str ) ); |
|
|
|
return new PCBEXPR_LAYER_VALUE( context->GetBoard()->GetLayerID( str ) ); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
@ -219,29 +219,29 @@ LIBEVAL::VALUE* PCB_EXPR_VAR_REF::GetValue( LIBEVAL::CONTEXT* aCtx ) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
LIBEVAL::VALUE* PCB_EXPR_NETCLASS_REF::GetValue( LIBEVAL::CONTEXT* aCtx ) |
|
|
|
LIBEVAL::VALUE* PCBEXPR_NETCLASS_REF::GetValue( LIBEVAL::CONTEXT* aCtx ) |
|
|
|
{ |
|
|
|
BOARD_CONNECTED_ITEM* item = dynamic_cast<BOARD_CONNECTED_ITEM*>( GetObject( aCtx ) ); |
|
|
|
|
|
|
|
if( !item ) |
|
|
|
return new LIBEVAL::VALUE(); |
|
|
|
|
|
|
|
return new PCB_NETCLASS_VALUE( item ); |
|
|
|
return new PCBEXPR_NETCLASS_VALUE( item ); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
LIBEVAL::VALUE* PCB_EXPR_NETNAME_REF::GetValue( LIBEVAL::CONTEXT* aCtx ) |
|
|
|
LIBEVAL::VALUE* PCBEXPR_NETNAME_REF::GetValue( LIBEVAL::CONTEXT* aCtx ) |
|
|
|
{ |
|
|
|
BOARD_CONNECTED_ITEM* item = dynamic_cast<BOARD_CONNECTED_ITEM*>( GetObject( aCtx ) ); |
|
|
|
|
|
|
|
if( !item ) |
|
|
|
return new LIBEVAL::VALUE(); |
|
|
|
|
|
|
|
return new PCB_NET_VALUE( item ); |
|
|
|
return new PCBEXPR_NET_VALUE( item ); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
LIBEVAL::VALUE* PCB_EXPR_TYPE_REF::GetValue( LIBEVAL::CONTEXT* aCtx ) |
|
|
|
LIBEVAL::VALUE* PCBEXPR_TYPE_REF::GetValue( LIBEVAL::CONTEXT* aCtx ) |
|
|
|
{ |
|
|
|
BOARD_ITEM* item = GetObject( aCtx ); |
|
|
|
|
|
|
|
@ -252,56 +252,56 @@ LIBEVAL::VALUE* PCB_EXPR_TYPE_REF::GetValue( LIBEVAL::CONTEXT* aCtx ) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
LIBEVAL::FUNC_CALL_REF PCB_EXPR_UCODE::CreateFuncCall( const wxString& aName ) |
|
|
|
LIBEVAL::FUNC_CALL_REF PCBEXPR_UCODE::CreateFuncCall( const wxString& aName ) |
|
|
|
{ |
|
|
|
PCB_EXPR_BUILTIN_FUNCTIONS& registry = PCB_EXPR_BUILTIN_FUNCTIONS::Instance(); |
|
|
|
PCBEXPR_BUILTIN_FUNCTIONS& registry = PCBEXPR_BUILTIN_FUNCTIONS::Instance(); |
|
|
|
|
|
|
|
return registry.Get( aName.Lower() ); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<LIBEVAL::VAR_REF> PCB_EXPR_UCODE::CreateVarRef( const wxString& aVar, |
|
|
|
std::unique_ptr<LIBEVAL::VAR_REF> PCBEXPR_UCODE::CreateVarRef( const wxString& aVar, |
|
|
|
const wxString& aField ) |
|
|
|
{ |
|
|
|
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance(); |
|
|
|
std::unique_ptr<PCB_EXPR_VAR_REF> vref; |
|
|
|
std::unique_ptr<PCBEXPR_VAR_REF> vref; |
|
|
|
|
|
|
|
// Check for a couple of very common cases and compile them straight to "object code".
|
|
|
|
|
|
|
|
if( aField.CmpNoCase( wxT( "NetClass" ) ) == 0 ) |
|
|
|
{ |
|
|
|
if( aVar == wxT( "A" ) ) |
|
|
|
return std::make_unique<PCB_EXPR_NETCLASS_REF>( 0 ); |
|
|
|
return std::make_unique<PCBEXPR_NETCLASS_REF>( 0 ); |
|
|
|
else if( aVar == wxT( "B" ) ) |
|
|
|
return std::make_unique<PCB_EXPR_NETCLASS_REF>( 1 ); |
|
|
|
return std::make_unique<PCBEXPR_NETCLASS_REF>( 1 ); |
|
|
|
else |
|
|
|
return nullptr; |
|
|
|
} |
|
|
|
else if( aField.CmpNoCase( wxT( "NetName" ) ) == 0 ) |
|
|
|
{ |
|
|
|
if( aVar == wxT( "A" ) ) |
|
|
|
return std::make_unique<PCB_EXPR_NETNAME_REF>( 0 ); |
|
|
|
return std::make_unique<PCBEXPR_NETNAME_REF>( 0 ); |
|
|
|
else if( aVar == wxT( "B" ) ) |
|
|
|
return std::make_unique<PCB_EXPR_NETNAME_REF>( 1 ); |
|
|
|
return std::make_unique<PCBEXPR_NETNAME_REF>( 1 ); |
|
|
|
else |
|
|
|
return nullptr; |
|
|
|
} |
|
|
|
else if( aField.CmpNoCase( wxT( "Type" ) ) == 0 ) |
|
|
|
{ |
|
|
|
if( aVar == wxT( "A" ) ) |
|
|
|
return std::make_unique<PCB_EXPR_TYPE_REF>( 0 ); |
|
|
|
return std::make_unique<PCBEXPR_TYPE_REF>( 0 ); |
|
|
|
else if( aVar == wxT( "B" ) ) |
|
|
|
return std::make_unique<PCB_EXPR_TYPE_REF>( 1 ); |
|
|
|
return std::make_unique<PCBEXPR_TYPE_REF>( 1 ); |
|
|
|
else |
|
|
|
return nullptr; |
|
|
|
} |
|
|
|
|
|
|
|
if( aVar == wxT( "A" ) || aVar == wxT( "AB" ) ) |
|
|
|
vref = std::make_unique<PCB_EXPR_VAR_REF>( 0 ); |
|
|
|
vref = std::make_unique<PCBEXPR_VAR_REF>( 0 ); |
|
|
|
else if( aVar == wxT( "B" ) ) |
|
|
|
vref = std::make_unique<PCB_EXPR_VAR_REF>( 1 ); |
|
|
|
vref = std::make_unique<PCBEXPR_VAR_REF>( 1 ); |
|
|
|
else if( aVar == wxT( "L" ) ) |
|
|
|
vref = std::make_unique<PCB_EXPR_VAR_REF>( 2 ); |
|
|
|
vref = std::make_unique<PCBEXPR_VAR_REF>( 2 ); |
|
|
|
else |
|
|
|
return nullptr; |
|
|
|
|
|
|
|
@ -342,7 +342,7 @@ std::unique_ptr<LIBEVAL::VAR_REF> PCB_EXPR_UCODE::CreateVarRef( const wxString& |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
wxFAIL_MSG( wxT( "PCB_EXPR_UCODE::createVarRef: Unknown property type." ) ); |
|
|
|
wxFAIL_MSG( wxT( "PCBEXPR_UCODE::createVarRef: Unknown property type." ) ); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -355,7 +355,7 @@ std::unique_ptr<LIBEVAL::VAR_REF> PCB_EXPR_UCODE::CreateVarRef( const wxString& |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
BOARD* PCB_EXPR_CONTEXT::GetBoard() const |
|
|
|
BOARD* PCBEXPR_CONTEXT::GetBoard() const |
|
|
|
{ |
|
|
|
if( m_items[0] ) |
|
|
|
return m_items[0]->GetBoard(); |
|
|
|
@ -368,7 +368,7 @@ BOARD* PCB_EXPR_CONTEXT::GetBoard() const |
|
|
|
* Unit Resolvers |
|
|
|
*/ |
|
|
|
|
|
|
|
const std::vector<wxString>& PCB_UNIT_RESOLVER::GetSupportedUnits() const |
|
|
|
const std::vector<wxString>& PCBEXPR_UNIT_RESOLVER::GetSupportedUnits() const |
|
|
|
{ |
|
|
|
static const std::vector<wxString> pcbUnits = { wxT( "mil" ), wxT( "mm" ), wxT( "in" ) }; |
|
|
|
|
|
|
|
@ -376,13 +376,13 @@ const std::vector<wxString>& PCB_UNIT_RESOLVER::GetSupportedUnits() const |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
wxString PCB_UNIT_RESOLVER::GetSupportedUnitsMessage() const |
|
|
|
wxString PCBEXPR_UNIT_RESOLVER::GetSupportedUnitsMessage() const |
|
|
|
{ |
|
|
|
return _( "must be mm, in, or mil" ); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
double PCB_UNIT_RESOLVER::Convert( const wxString& aString, int unitId ) const |
|
|
|
double PCBEXPR_UNIT_RESOLVER::Convert( const wxString& aString, int unitId ) const |
|
|
|
{ |
|
|
|
double v = wxAtof( aString ); |
|
|
|
|
|
|
|
@ -396,7 +396,7 @@ double PCB_UNIT_RESOLVER::Convert( const wxString& aString, int unitId ) const |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
const std::vector<wxString>& PCB_UNITLESS_RESOLVER::GetSupportedUnits() const |
|
|
|
const std::vector<wxString>& PCBEXPR_UNITLESS_RESOLVER::GetSupportedUnits() const |
|
|
|
{ |
|
|
|
static const std::vector<wxString> emptyUnits; |
|
|
|
|
|
|
|
@ -404,13 +404,13 @@ const std::vector<wxString>& PCB_UNITLESS_RESOLVER::GetSupportedUnits() const |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
double PCB_UNITLESS_RESOLVER::Convert( const wxString& aString, int unitId ) const |
|
|
|
double PCBEXPR_UNITLESS_RESOLVER::Convert( const wxString& aString, int unitId ) const |
|
|
|
{ |
|
|
|
return wxAtof( aString ); |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
PCB_EXPR_COMPILER::PCB_EXPR_COMPILER( LIBEVAL::UNIT_RESOLVER* aUnitResolver ) |
|
|
|
PCBEXPR_COMPILER::PCBEXPR_COMPILER( LIBEVAL::UNIT_RESOLVER* aUnitResolver ) |
|
|
|
{ |
|
|
|
m_unitResolver.reset( aUnitResolver ); |
|
|
|
} |
|
|
|
@ -420,7 +420,7 @@ PCB_EXPR_COMPILER::PCB_EXPR_COMPILER( LIBEVAL::UNIT_RESOLVER* aUnitResolver ) |
|
|
|
* PCB Expression Evaluator |
|
|
|
*/ |
|
|
|
|
|
|
|
PCB_EXPR_EVALUATOR::PCB_EXPR_EVALUATOR( LIBEVAL::UNIT_RESOLVER* aUnitResolver ) : |
|
|
|
PCBEXPR_EVALUATOR::PCBEXPR_EVALUATOR( LIBEVAL::UNIT_RESOLVER* aUnitResolver ) : |
|
|
|
m_result( 0 ), |
|
|
|
m_compiler( aUnitResolver ), |
|
|
|
m_ucode(), |
|
|
|
@ -429,20 +429,20 @@ PCB_EXPR_EVALUATOR::PCB_EXPR_EVALUATOR( LIBEVAL::UNIT_RESOLVER* aUnitResolver ) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
PCB_EXPR_EVALUATOR::~PCB_EXPR_EVALUATOR() |
|
|
|
PCBEXPR_EVALUATOR::~PCBEXPR_EVALUATOR() |
|
|
|
{ |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool PCB_EXPR_EVALUATOR::Evaluate( const wxString& aExpr ) |
|
|
|
bool PCBEXPR_EVALUATOR::Evaluate( const wxString& aExpr ) |
|
|
|
{ |
|
|
|
PCB_EXPR_UCODE ucode; |
|
|
|
PCB_EXPR_CONTEXT preflightContext( NULL_CONSTRAINT, F_Cu ); |
|
|
|
PCBEXPR_UCODE ucode; |
|
|
|
PCBEXPR_CONTEXT preflightContext( NULL_CONSTRAINT, F_Cu ); |
|
|
|
|
|
|
|
if( !m_compiler.Compile( aExpr.ToUTF8().data(), &ucode, &preflightContext ) ) |
|
|
|
return false; |
|
|
|
|
|
|
|
PCB_EXPR_CONTEXT evaluationContext( NULL_CONSTRAINT, F_Cu ); |
|
|
|
PCBEXPR_CONTEXT evaluationContext( NULL_CONSTRAINT, F_Cu ); |
|
|
|
LIBEVAL::VALUE* result = ucode.Run( &evaluationContext ); |
|
|
|
|
|
|
|
if( result->GetType() == LIBEVAL::VT_NUMERIC ) |