diff --git a/include/libeval_compiler/libeval_compiler.h b/include/libeval_compiler/libeval_compiler.h index ea0576386d..134028671d 100644 --- a/include/libeval_compiler/libeval_compiler.h +++ b/include/libeval_compiler/libeval_compiler.h @@ -178,8 +178,8 @@ public: class VALUE { public: - VALUE(): - m_type(VT_UNDEFINED), + VALUE() : + m_type( VT_UNDEFINED ), m_valueDbl( 0 ), m_stringIsWildcard( false ) {}; @@ -197,17 +197,20 @@ public: m_stringIsWildcard( false ) {}; - double AsDouble() const + virtual ~VALUE() + {}; + + virtual double AsDouble() const { return m_valueDbl; } - const wxString& AsString() const + virtual const wxString& AsString() const { return m_valueStr; } - bool EqualTo( const VALUE* b ) const; + virtual bool EqualTo( const VALUE* b ) const; VAR_TYPE_T GetType() const { return m_type; }; diff --git a/include/property.h b/include/property.h index cfa1f72196..c51f1bb1da 100644 --- a/include/property.h +++ b/include/property.h @@ -522,7 +522,6 @@ public: ENUM_MAP& Map( T aValue, const wxString& aName ) { - wxASSERT_MSG( m_choices.Index( aName ) == wxNOT_FOUND, "Redefined string for a value in ENUM_MAP" ); m_choices.Add( aName, static_cast( aValue ) ); m_reverseMap[ aName ] = aValue; return *this; diff --git a/pcbnew/drc/drc_rule_parser.cpp b/pcbnew/drc/drc_rule_parser.cpp index ca669d23c8..5daf1ccc27 100644 --- a/pcbnew/drc/drc_rule_parser.cpp +++ b/pcbnew/drc/drc_rule_parser.cpp @@ -499,6 +499,7 @@ LSET DRC_RULES_PARSER::parseLayer() { reportError( wxString::Format( _( "Unrecognized layer '%s'." ), layerName ) ); + retVal.set( UNDEFINED_LAYER ); } } diff --git a/pcbnew/pcb_edit_frame.cpp b/pcbnew/pcb_edit_frame.cpp index 6af2368c20..2a2d29df83 100644 --- a/pcbnew/pcb_edit_frame.cpp +++ b/pcbnew/pcb_edit_frame.cpp @@ -1203,7 +1203,12 @@ void PCB_EDIT_FRAME::UpdateUserInterface() layerEnum.Undefined( UNDEFINED_LAYER ); for( LSEQ seq = LSET::AllLayersMask().Seq(); seq; ++seq ) + { + // Canonical name + layerEnum.Map( *seq, LSET::Name( *seq ) ); + // User name layerEnum.Map( *seq, GetBoard()->GetLayerName( *seq ) ); + } // Sync visibility with canvas KIGFX::VIEW* view = GetCanvas()->GetView(); diff --git a/pcbnew/pcb_expr_evaluator.cpp b/pcbnew/pcb_expr_evaluator.cpp index 0f23cf4ef7..9eb6712e19 100644 --- a/pcbnew/pcb_expr_evaluator.cpp +++ b/pcbnew/pcb_expr_evaluator.cpp @@ -340,9 +340,9 @@ PCB_EXPR_BUILTIN_FUNCTIONS::PCB_EXPR_BUILTIN_FUNCTIONS() void PCB_EXPR_BUILTIN_FUNCTIONS::RegisterAllFunctions() - { +{ m_funcs.clear(); - registerFunc( "existsOnLayer('x')", existsOnLayer ); + RegisterFunc( "existsOnLayer('x')", existsOnLayer ); RegisterFunc( "isPlated()", isPlated ); RegisterFunc( "insideCourtyard('x')", insideCourtyard ); RegisterFunc( "insideArea('x')", insideArea ); @@ -364,8 +364,43 @@ BOARD_ITEM* PCB_EXPR_VAR_REF::GetObject( LIBEVAL::CONTEXT* aCtx ) const } +class PCB_LAYER_VALUE : public LIBEVAL::VALUE +{ +public: + PCB_LAYER_VALUE( PCB_LAYER_ID aLayer ) : + LIBEVAL::VALUE( double( aLayer ) ) + {}; + + virtual bool EqualTo( const VALUE* b ) const override + { + // For boards with user-defined layer names there will be 2 entries for each layer + // in the ENUM_MAP: one for the canonical layer name and one for the user layer name. + // We need to check against both. + + wxPGChoices& layerMap = ENUM_MAP::Instance().Choices(); + PCB_LAYER_ID layerId = ToLAYER_ID( (int) AsDouble() ); + + for( unsigned ii = 0; ii < layerMap.GetCount(); ++ii ) + { + wxPGChoiceEntry& entry = layerMap[ii]; + + if( entry.GetValue() == layerId && entry.GetText().Matches( b->AsString() ) ) + return true; + } + + return false; + } +}; + + LIBEVAL::VALUE PCB_EXPR_VAR_REF::GetValue( LIBEVAL::CONTEXT* aCtx ) { + if( m_itemIndex == 2 ) + { + PCB_EXPR_CONTEXT* context = static_cast( aCtx ); + return PCB_LAYER_VALUE( context->GetLayer() ); + } + BOARD_ITEM* item = const_cast( GetObject( aCtx ) ); auto it = m_matchingTypes.find( TYPE_HASH( *item ) ); @@ -413,7 +448,7 @@ std::unique_ptr PCB_EXPR_UCODE::CreateVarRef( const wxString& const wxString& aField ) { PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance(); - std::unique_ptr vref;; + std::unique_ptr vref; if( aVar == "A" ) { @@ -423,6 +458,10 @@ std::unique_ptr PCB_EXPR_UCODE::CreateVarRef( const wxString& { vref.reset( new PCB_EXPR_VAR_REF( 1 ) ); } + else if( aVar == "L" ) + { + vref.reset( new PCB_EXPR_VAR_REF( 2 ) ); + } else { return nullptr;