diff --git a/common/libeval_compiler/libeval_compiler.cpp b/common/libeval_compiler/libeval_compiler.cpp index 7e9911bca4..32b957241e 100644 --- a/common/libeval_compiler/libeval_compiler.cpp +++ b/common/libeval_compiler/libeval_compiler.cpp @@ -109,7 +109,7 @@ static const wxString formatOpName( int op ) } -bool VALUE::EqualTo( const VALUE* b ) const +bool VALUE::EqualTo( CONTEXT* aCtx, const VALUE* b ) const { if( m_type == VT_UNDEFINED || b->m_type == VT_UNDEFINED ) return false; @@ -130,12 +130,12 @@ bool VALUE::EqualTo( const VALUE* b ) const } -bool VALUE::NotEqualTo( const VALUE* b ) const +bool VALUE::NotEqualTo( CONTEXT* aCtx, const VALUE* b ) const { if( m_type == VT_UNDEFINED || b->m_type == VT_UNDEFINED ) return false; - return !EqualTo( b ); + return !EqualTo( aCtx, b ); } @@ -1162,10 +1162,10 @@ void UOP::Exec( CONTEXT* ctx ) result = arg1Value > arg2Value ? 1 : 0; break; case TR_OP_EQUAL: - result = arg1 && arg2 && arg1->EqualTo( arg2 ) ? 1 : 0; + result = arg1 && arg2 && arg1->EqualTo( ctx, arg2 ) ? 1 : 0; break; case TR_OP_NOT_EQUAL: - result = arg1 && arg2 && arg1->NotEqualTo( arg2 ) ? 1 : 0; + result = arg1 && arg2 && arg1->NotEqualTo( ctx, arg2 ) ? 1 : 0; break; case TR_OP_BOOL_AND: result = arg1Value != 0.0 && arg2Value != 0.0 ? 1 : 0; diff --git a/include/board_item.h b/include/board_item.h index e98db960e3..8065788c98 100644 --- a/include/board_item.h +++ b/include/board_item.h @@ -309,7 +309,8 @@ public: /** * Return the #BOARD in which this #BOARD_ITEM resides, or NULL if none. */ - virtual BOARD* GetBoard() const; + virtual const BOARD* GetBoard() const; + virtual BOARD* GetBoard(); /** * Return the name of the PCB layer on which the item resides. diff --git a/include/libeval_compiler/libeval_compiler.h b/include/libeval_compiler/libeval_compiler.h index 73913cfabc..3c341fbe3a 100644 --- a/include/libeval_compiler/libeval_compiler.h +++ b/include/libeval_compiler/libeval_compiler.h @@ -216,10 +216,10 @@ public: return m_valueStr; } - virtual bool EqualTo( const VALUE* b ) const; + virtual bool EqualTo( CONTEXT* aCtx, const VALUE* b ) const; // NB: this is not an inverse of EqualTo as they both return false for undefined values. - virtual bool NotEqualTo( const VALUE* b ) const; + virtual bool NotEqualTo( CONTEXT* aCtx, const VALUE* b ) const; VAR_TYPE_T GetType() const { return m_type; }; @@ -274,15 +274,12 @@ public: virtual ~CONTEXT() { - for( VALUE* value : m_ownedValues ) - delete value; } VALUE* AllocValue() { - VALUE* value = new VALUE(); - m_ownedValues.push_back( value ); - return value; + m_ownedValues.emplace_back(); + return &m_ownedValues.back(); } void Push( VALUE* v ) @@ -316,7 +313,7 @@ public: void ReportError( const wxString& aErrorMsg ); private: - std::vector m_ownedValues; + std::vector m_ownedValues; VALUE* m_stack[100]; // std::stack not performant enough int m_stackPtr; diff --git a/pcbnew/board.h b/pcbnew/board.h index 87520c4473..bcc4389fca 100644 --- a/pcbnew/board.h +++ b/pcbnew/board.h @@ -211,7 +211,7 @@ public: void IncrementTimeStamp(); - int GetTimeStamp() { return m_timeStamp; } + int GetTimeStamp() const { return m_timeStamp; } /** * Find out if the board is being used to hold a single footprint for editing/viewing. diff --git a/pcbnew/board_item.cpp b/pcbnew/board_item.cpp index 2dd964a2fd..878d61e1ec 100644 --- a/pcbnew/board_item.cpp +++ b/pcbnew/board_item.cpp @@ -47,10 +47,24 @@ wxString BOARD_ITEM::ShowShape( SHAPE_T aShape ) } -BOARD* BOARD_ITEM::GetBoard() const +const BOARD* BOARD_ITEM::GetBoard() const { if( Type() == PCB_T ) - return (BOARD*) this; + return static_cast( this ); + + BOARD_ITEM* parent = GetParent(); + + if( parent ) + return parent->GetBoard(); + + return nullptr; +} + + +BOARD* BOARD_ITEM::GetBoard() +{ + if( Type() == PCB_T ) + return static_cast( this ); BOARD_ITEM* parent = GetParent(); @@ -72,7 +86,7 @@ bool BOARD_ITEM::IsLocked() const wxString BOARD_ITEM::GetLayerName() const { - BOARD* board = GetBoard(); + const BOARD* board = GetBoard(); if( board ) return board->GetLayerName( m_layer ); @@ -84,8 +98,8 @@ wxString BOARD_ITEM::GetLayerName() const wxString BOARD_ITEM::layerMaskDescribe() const { - BOARD* board = GetBoard(); - LSET layers = GetLayerSet(); + const BOARD* board = GetBoard(); + LSET layers = GetLayerSet(); // Try to be smart and useful. Check all copper first. if( layers[F_Cu] && layers[B_Cu] ) diff --git a/pcbnew/drc/drc_rule.cpp b/pcbnew/drc/drc_rule.cpp index 0938ab0c1f..b132f2d41a 100644 --- a/pcbnew/drc/drc_rule.cpp +++ b/pcbnew/drc/drc_rule.cpp @@ -49,11 +49,14 @@ void DRC_RULE::AddConstraint( DRC_CONSTRAINT& aConstraint ) m_Constraints.push_back( aConstraint ); } + OPT DRC_RULE::FindConstraint( DRC_CONSTRAINT_T aType ) { - for( auto &c : m_Constraints) + for( DRC_CONSTRAINT& c : m_Constraints) + { if( c.m_Type == aType ) return c; + } return OPT(); } \ No newline at end of file diff --git a/pcbnew/drc/drc_rule_parser.cpp b/pcbnew/drc/drc_rule_parser.cpp index 19dc3e9f58..fce3bd547d 100644 --- a/pcbnew/drc/drc_rule_parser.cpp +++ b/pcbnew/drc/drc_rule_parser.cpp @@ -231,7 +231,7 @@ DRC_RULE* DRC_RULES_PARSER::parseDRC_RULE() default: msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ), FromUTF8(), - "'constraint', 'condition', 'disallow'" ); + "constraint, condition or disallow" ); reportError( msg ); parseUnknown(); } @@ -246,51 +246,55 @@ DRC_RULE* DRC_RULES_PARSER::parseDRC_RULE() void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule ) { - DRC_CONSTRAINT constraint; - - int value; - wxString msg; + DRC_CONSTRAINT c; + int value; + wxString msg; T token = NextTok(); if( (int) token == DSN_RIGHT || token == T_EOF ) { msg.Printf( _( "Missing constraint type.| Expected %s." ), - "'clearance', 'hole_clearance', 'edge_clearance', 'hole', 'hole_to_hole', " - "'courtyard_clearance', 'silk_clearance', 'track_width', 'annular_width', " - "'disallow', 'length', 'skew', 'via_count', 'diff_pair_gap' or " - "'diff_pair_uncoupled'" ); + "clearance, hole_clearance, edge_clearance, hole, hole_to_hole, " + "courtyard_clearance, silk_clearance, track_width, annular_width, " + "disallow, length, skew, via_count, diff_pair_gap or diff_pair_uncoupled" ); reportError( msg ); return; } switch( token ) { - case T_clearance: constraint.m_Type = CLEARANCE_CONSTRAINT; break; - case T_hole_clearance: constraint.m_Type = HOLE_CLEARANCE_CONSTRAINT; break; - case T_edge_clearance: constraint.m_Type = EDGE_CLEARANCE_CONSTRAINT; break; + case T_clearance: c.m_Type = CLEARANCE_CONSTRAINT; break; + case T_hole_clearance: c.m_Type = HOLE_CLEARANCE_CONSTRAINT; break; + case T_edge_clearance: c.m_Type = EDGE_CLEARANCE_CONSTRAINT; break; case T_hole: // legacy token - case T_hole_size: constraint.m_Type = HOLE_SIZE_CONSTRAINT; break; - case T_hole_to_hole: constraint.m_Type = HOLE_TO_HOLE_CONSTRAINT; break; - case T_courtyard_clearance: constraint.m_Type = COURTYARD_CLEARANCE_CONSTRAINT; break; - case T_silk_clearance: constraint.m_Type = SILK_CLEARANCE_CONSTRAINT; break; - case T_track_width: constraint.m_Type = TRACK_WIDTH_CONSTRAINT; break; - case T_annular_width: constraint.m_Type = ANNULAR_WIDTH_CONSTRAINT; break; - case T_disallow: constraint.m_Type = DISALLOW_CONSTRAINT; break; - case T_length: constraint.m_Type = LENGTH_CONSTRAINT; break; - case T_skew: constraint.m_Type = SKEW_CONSTRAINT; break; - case T_via_count: constraint.m_Type = VIA_COUNT_CONSTRAINT; break; - case T_diff_pair_gap: constraint.m_Type = DIFF_PAIR_GAP_CONSTRAINT; break; - case T_diff_pair_uncoupled: constraint.m_Type = DIFF_PAIR_MAX_UNCOUPLED_CONSTRAINT; break; + case T_hole_size: c.m_Type = HOLE_SIZE_CONSTRAINT; break; + case T_hole_to_hole: c.m_Type = HOLE_TO_HOLE_CONSTRAINT; break; + case T_courtyard_clearance: c.m_Type = COURTYARD_CLEARANCE_CONSTRAINT; break; + case T_silk_clearance: c.m_Type = SILK_CLEARANCE_CONSTRAINT; break; + case T_track_width: c.m_Type = TRACK_WIDTH_CONSTRAINT; break; + case T_annular_width: c.m_Type = ANNULAR_WIDTH_CONSTRAINT; break; + case T_disallow: c.m_Type = DISALLOW_CONSTRAINT; break; + case T_length: c.m_Type = LENGTH_CONSTRAINT; break; + case T_skew: c.m_Type = SKEW_CONSTRAINT; break; + case T_via_count: c.m_Type = VIA_COUNT_CONSTRAINT; break; + case T_diff_pair_gap: c.m_Type = DIFF_PAIR_GAP_CONSTRAINT; break; + case T_diff_pair_uncoupled: c.m_Type = DIFF_PAIR_MAX_UNCOUPLED_CONSTRAINT; break; default: msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ), FromUTF8(), - "'clearance', 'hole_clearance', 'edge_clearance', 'hole_size', hole_to_hole'," - "'courtyard_clearance', 'silk_clearance', 'track_width', 'annular_width', " - "'disallow', 'length', 'skew', 'diff_pair_gap' or 'diff_pair_uncoupled'." ); + "clearance, hole_clearance, edge_clearance, hole_size, hole_to_hole, " + "courtyard_clearance, silk_clearance, track_width, annular_width, " + "disallow, length, skew, diff_pair_gap or diff_pair_uncoupled." ); reportError( msg ); } - if( constraint.m_Type == DISALLOW_CONSTRAINT ) + if( aRule->FindConstraint( c.m_Type ) ) + { + msg.Printf( _( "Rule already has a '%s' constraint." ), FromUTF8() ); + reportError( msg ); + } + + if( c.m_Type == DISALLOW_CONSTRAINT ) { for( token = NextTok(); token != T_RIGHT; token = NextTok() ) { @@ -299,16 +303,16 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule ) switch( token ) { - case T_track: constraint.m_DisallowFlags |= DRC_DISALLOW_TRACKS; break; - case T_via: constraint.m_DisallowFlags |= DRC_DISALLOW_VIAS; break; - case T_micro_via: constraint.m_DisallowFlags |= DRC_DISALLOW_MICRO_VIAS; break; - case T_buried_via: constraint.m_DisallowFlags |= DRC_DISALLOW_BB_VIAS; break; - case T_pad: constraint.m_DisallowFlags |= DRC_DISALLOW_PADS; break; - case T_zone: constraint.m_DisallowFlags |= DRC_DISALLOW_ZONES; break; - case T_text: constraint.m_DisallowFlags |= DRC_DISALLOW_TEXTS; break; - case T_graphic: constraint.m_DisallowFlags |= DRC_DISALLOW_GRAPHICS; break; - case T_hole: constraint.m_DisallowFlags |= DRC_DISALLOW_HOLES; break; - case T_footprint: constraint.m_DisallowFlags |= DRC_DISALLOW_FOOTPRINTS; break; + case T_track: c.m_DisallowFlags |= DRC_DISALLOW_TRACKS; break; + case T_via: c.m_DisallowFlags |= DRC_DISALLOW_VIAS; break; + case T_micro_via: c.m_DisallowFlags |= DRC_DISALLOW_MICRO_VIAS; break; + case T_buried_via: c.m_DisallowFlags |= DRC_DISALLOW_BB_VIAS; break; + case T_pad: c.m_DisallowFlags |= DRC_DISALLOW_PADS; break; + case T_zone: c.m_DisallowFlags |= DRC_DISALLOW_ZONES; break; + case T_text: c.m_DisallowFlags |= DRC_DISALLOW_TEXTS; break; + case T_graphic: c.m_DisallowFlags |= DRC_DISALLOW_GRAPHICS; break; + case T_hole: c.m_DisallowFlags |= DRC_DISALLOW_HOLES; break; + case T_footprint: c.m_DisallowFlags |= DRC_DISALLOW_FOOTPRINTS; break; case T_EOF: reportError( _( "Missing ')'." ) ); @@ -316,8 +320,8 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule ) default: msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ), FromUTF8(), - "'track', 'via', 'micro_via', 'buried_via', 'pad', 'zone', 'text', " - "'graphic', 'hole' or 'footprint'." ); + "track, via, micro_via, buried_via, pad, zone, text, graphic, hole " + "or footprint." ); reportError( msg ); break; } @@ -326,7 +330,7 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule ) if( (int) CurTok() != DSN_RIGHT ) reportError( _( "Missing ')'." ) ); - aRule->AddConstraint( constraint ); + aRule->AddConstraint( c ); return; } @@ -349,12 +353,11 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule ) } parseValueWithUnits( FromUTF8(), value ); - constraint.m_Value.SetMin( value ); + c.m_Value.SetMin( value ); if( (int) NextTok() != DSN_RIGHT ) { - reportError( wxString::Format( _( "Unrecognized item '%s'." ), - FromUTF8() ) ); + reportError( wxString::Format( _( "Unrecognized item '%s'." ), FromUTF8() ) ); parseUnknown(); } @@ -370,12 +373,11 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule ) } parseValueWithUnits( FromUTF8(), value ); - constraint.m_Value.SetMax( value ); + c.m_Value.SetMax( value ); if( (int) NextTok() != DSN_RIGHT ) { - reportError( wxString::Format( _( "Unrecognized item '%s'." ), - FromUTF8() ) ); + reportError( wxString::Format( _( "Unrecognized item '%s'." ), FromUTF8() ) ); parseUnknown(); } @@ -391,12 +393,11 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule ) } parseValueWithUnits( FromUTF8(), value ); - constraint.m_Value.SetOpt( value ); + c.m_Value.SetOpt( value ); if( (int) NextTok() != DSN_RIGHT ) { - reportError( wxString::Format( _( "Unrecognized item '%s'." ), - FromUTF8() ) ); + reportError( wxString::Format( _( "Unrecognized item '%s'." ), FromUTF8() ) ); parseUnknown(); } @@ -409,7 +410,7 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule ) default: msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ), FromUTF8(), - "'min', 'max', 'opt'" ); + "min, max or opt" ); reportError( msg ); parseUnknown(); } @@ -418,7 +419,7 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule ) if( (int) CurTok() != DSN_RIGHT ) reportError( _( "Missing ')'." ) ); - aRule->AddConstraint( constraint ); + aRule->AddConstraint( c ); } @@ -486,8 +487,7 @@ LSET DRC_RULES_PARSER::parseLayer() if( !retVal.any() ) { - reportError( wxString::Format( _( "Unrecognized layer '%s'." ), - layerName ) ); + reportError( wxString::Format( _( "Unrecognized layer '%s'." ), layerName ) ); retVal.set( Rescue ); } } diff --git a/pcbnew/footprint.cpp b/pcbnew/footprint.cpp index 8f30eb5b61..374319280d 100644 --- a/pcbnew/footprint.cpp +++ b/pcbnew/footprint.cpp @@ -681,7 +681,7 @@ const EDA_RECT FOOTPRINT::GetBoundingBox() const const EDA_RECT FOOTPRINT::GetBoundingBox( bool aIncludeText, bool aIncludeInvisibleText ) const { - BOARD* board = GetBoard(); + const BOARD* board = GetBoard(); if( board ) { @@ -786,7 +786,7 @@ const EDA_RECT FOOTPRINT::GetBoundingBox( bool aIncludeText, bool aIncludeInvisi SHAPE_POLY_SET FOOTPRINT::GetBoundingHull() const { - BOARD* board = GetBoard(); + const BOARD* board = GetBoard(); if( board ) { @@ -1349,7 +1349,7 @@ const BOX2I FOOTPRINT::ViewBBox() const // Add the Clearance shape size: (shape around the pads when the clearance is shown. Not // optimized, but the draw cost is small (perhaps smaller than optimization). - BOARD* board = GetBoard(); + const BOARD* board = GetBoard(); if( board ) { diff --git a/pcbnew/pad.cpp b/pcbnew/pad.cpp index 3153473b7e..1fd46b4d7c 100644 --- a/pcbnew/pad.cpp +++ b/pcbnew/pad.cpp @@ -215,7 +215,7 @@ bool PAD::FlashLayer( int aLayer ) const if( aLayer == UNDEFINED_LAYER ) return true; - BOARD* board = GetBoard(); + const BOARD* board = GetBoard(); if( !board ) return false; @@ -316,8 +316,8 @@ void PAD::BuildEffectiveShapes( PCB_LAYER_ID aLayer ) const if( !m_shapesDirty ) return; - BOARD* board = GetBoard(); - int maxError = board ? board->GetDesignSettings().m_MaxError : ARC_HIGH_DEF; + const BOARD* board = GetBoard(); + int maxError = board ? board->GetDesignSettings().m_MaxError : ARC_HIGH_DEF; m_effectiveShape = std::make_shared(); m_effectiveHoleShape = nullptr; @@ -489,8 +489,8 @@ void PAD::BuildEffectivePolygon() const if( !m_polyDirty ) return; - BOARD* board = GetBoard(); - int maxError = board ? board->GetDesignSettings().m_MaxError : ARC_HIGH_DEF; + const BOARD* board = GetBoard(); + int maxError = board ? board->GetDesignSettings().m_MaxError : ARC_HIGH_DEF; // Polygon m_effectivePolygon = std::make_shared(); @@ -719,7 +719,7 @@ int PAD::GetSolderMaskMargin() const if( margin == 0 ) { - BOARD* brd = GetBoard(); + const BOARD* brd = GetBoard(); if( brd ) margin = brd->GetDesignSettings().m_SolderMaskMargin; @@ -1234,7 +1234,7 @@ double PAD::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const PCB_PAINTER* painter = static_cast( aView->GetPainter() ); PCB_RENDER_SETTINGS* renderSettings = painter->GetSettings(); - BOARD* board = GetBoard(); + const BOARD* board = GetBoard(); LSET visible = LSET::AllLayersMask(); // Meta control for hiding all pads diff --git a/pcbnew/pad_custom_shape_functions.cpp b/pcbnew/pad_custom_shape_functions.cpp index 37282df917..888b4eeb7d 100644 --- a/pcbnew/pad_custom_shape_functions.cpp +++ b/pcbnew/pad_custom_shape_functions.cpp @@ -206,8 +206,8 @@ void PAD::addPadPrimitivesToPolygon( SHAPE_POLY_SET* aMergedPolygon, PCB_LAYER_I void PAD::MergePrimitivesAsPolygon( SHAPE_POLY_SET* aMergedPolygon, PCB_LAYER_ID aLayer, ERROR_LOC aErrorLoc ) const { - BOARD* board = GetBoard(); - int maxError = board ? board->GetDesignSettings().m_MaxError: ARC_HIGH_DEF; + const BOARD* board = GetBoard(); + int maxError = board ? board->GetDesignSettings().m_MaxError : ARC_HIGH_DEF; aMergedPolygon->RemoveAllContours(); diff --git a/pcbnew/pcb_expr_evaluator.cpp b/pcbnew/pcb_expr_evaluator.cpp index 2189f9e9ff..31a9f35fef 100644 --- a/pcbnew/pcb_expr_evaluator.cpp +++ b/pcbnew/pcb_expr_evaluator.cpp @@ -98,8 +98,8 @@ static void existsOnLayer( LIBEVAL::CONTEXT* aCtx, void *self ) return; } - wxString layerName = arg->AsString(); - wxPGChoices& layerMap = ENUM_MAP::Instance().Choices(); + const wxString& layerName = arg->AsString(); + wxPGChoices& layerMap = ENUM_MAP::Instance().Choices(); if( aCtx->HasErrorCallback() ) { @@ -881,24 +881,39 @@ public: LIBEVAL::VALUE( double( aLayer ) ) {}; - virtual bool EqualTo( const VALUE* b ) const override + virtual bool EqualTo( LIBEVAL::CONTEXT* aCtx, 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() ); + wxPGChoices& layerMap = ENUM_MAP::Instance().Choices(); + const wxString& layerName = b->AsString(); + BOARD* board = static_cast( aCtx )->GetBoard(); + std::unique_lock cacheLock( board->m_CachesMutex ); + auto i = board->m_LayerExpressionCache.find( layerName ); + LSET mask; - for( unsigned ii = 0; ii < layerMap.GetCount(); ++ii ) + if( i == board->m_LayerExpressionCache.end() ) { - wxPGChoiceEntry& entry = layerMap[ii]; + for( unsigned ii = 0; ii < layerMap.GetCount(); ++ii ) + { + wxPGChoiceEntry& entry = layerMap[ii]; - if( entry.GetValue() == layerId && entry.GetText().Matches( b->AsString() ) ) - return true; + if( entry.GetText().Matches( layerName ) ) + mask.set( ToLAYER_ID( entry.GetValue() ) ); + } + + board->m_LayerExpressionCache[ layerName ] = mask; + } + else + { + mask = i->second; } - return false; + PCB_LAYER_ID layerId = ToLAYER_ID( (int) AsDouble() ); + + return mask.test( layerId ); } }; @@ -982,6 +997,17 @@ LIBEVAL::VALUE PCB_EXPR_NETNAME_REF::GetValue( LIBEVAL::CONTEXT* aCtx ) } +LIBEVAL::VALUE PCB_EXPR_TYPE_REF::GetValue( LIBEVAL::CONTEXT* aCtx ) +{ + BOARD_ITEM* item = GetObject( aCtx ); + + if( !item ) + return LIBEVAL::VALUE(); + + return LIBEVAL::VALUE( ENUM_MAP::Instance().ToString( item->Type() ) ); +} + + LIBEVAL::FUNC_CALL_REF PCB_EXPR_UCODE::CreateFuncCall( const wxString& aName ) { PCB_EXPR_BUILTIN_FUNCTIONS& registry = PCB_EXPR_BUILTIN_FUNCTIONS::Instance(); @@ -1016,6 +1042,15 @@ std::unique_ptr PCB_EXPR_UCODE::CreateVarRef( const wxString& else return nullptr; } + else if( aField.CmpNoCase( "Type" ) == 0 ) + { + if( aVar == "A" ) + return std::make_unique( 0 ); + else if( aVar == "B" ) + return std::make_unique( 1 ); + else + return nullptr; + } if( aVar == "A" || aVar == "AB" ) vref = std::make_unique( 0 ); @@ -1072,6 +1107,15 @@ std::unique_ptr PCB_EXPR_UCODE::CreateVarRef( const wxString& } +BOARD* PCB_EXPR_CONTEXT::GetBoard() const +{ + if( m_items[0] ) + return m_items[0]->GetBoard(); + + return nullptr; +} + + class PCB_UNIT_RESOLVER : public LIBEVAL::UNIT_RESOLVER { public: diff --git a/pcbnew/pcb_expr_evaluator.h b/pcbnew/pcb_expr_evaluator.h index fe288a679d..222738ee43 100644 --- a/pcbnew/pcb_expr_evaluator.h +++ b/pcbnew/pcb_expr_evaluator.h @@ -32,7 +32,7 @@ #include - +class BOARD; class BOARD_ITEM; class PCB_EXPR_VAR_REF; @@ -65,6 +65,8 @@ public: m_items[1] = b; } + BOARD* GetBoard() const; + BOARD_ITEM* GetItem( int index ) const { return m_items[index]; @@ -147,6 +149,20 @@ public: }; +class PCB_EXPR_TYPE_REF : public PCB_EXPR_VAR_REF +{ +public: + PCB_EXPR_TYPE_REF( int aItemIndex ) : + PCB_EXPR_VAR_REF( aItemIndex ) + { + SetType( LIBEVAL::VT_STRING ); + //printf("*** CreateVarRef %p %d\n", this, aItemIndex ); + } + + LIBEVAL::VALUE GetValue( LIBEVAL::CONTEXT* aCtx ) override; +}; + + class PCB_EXPR_BUILTIN_FUNCTIONS { public: diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index 6d0e15080b..dbf5848151 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -742,7 +742,7 @@ void PCB_PAINTER::draw( const PCB_ARC* aArc, int aLayer ) void PCB_PAINTER::draw( const PCB_VIA* aVia, int aLayer ) { - BOARD* board = aVia->GetBoard(); + const BOARD* board = aVia->GetBoard(); BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings(); COLOR4D color = m_pcbSettings.GetColor( aVia, aLayer ); VECTOR2D center( aVia->GetStart() ); @@ -897,7 +897,7 @@ void PCB_PAINTER::draw( const PCB_VIA* aVia, int aLayer ) void PCB_PAINTER::draw( const PAD* aPad, int aLayer ) { - BOARD* board = aPad->GetBoard(); + const BOARD* board = aPad->GetBoard(); BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings(); COLOR4D color = m_pcbSettings.GetColor( aPad, aLayer ); diff --git a/pcbnew/pcb_track.cpp b/pcbnew/pcb_track.cpp index 01751da2bc..7982f13559 100644 --- a/pcbnew/pcb_track.cpp +++ b/pcbnew/pcb_track.cpp @@ -526,7 +526,7 @@ bool PCB_VIA::FlashLayer( int aLayer ) const if( aLayer == UNDEFINED_LAYER ) return true; - BOARD* board = GetBoard(); + const BOARD* board = GetBoard(); if( !board ) return false; @@ -583,9 +583,8 @@ double PCB_TRACK::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const const BOX2I PCB_TRACK::ViewBBox() const { - BOX2I bbox = GetBoundingBox(); - - BOARD* board = GetBoard(); + BOX2I bbox = GetBoundingBox(); + const BOARD* board = GetBoard(); if( board ) bbox.Inflate( 2 * board->GetDesignSettings().GetBiggestClearanceValue() ); @@ -619,7 +618,7 @@ double PCB_VIA::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const PCB_PAINTER* painter = static_cast( aView->GetPainter() ); PCB_RENDER_SETTINGS* renderSettings = painter->GetSettings(); - BOARD* board = GetBoard(); + const BOARD* board = GetBoard(); LSET visible = LSET::AllLayersMask(); // Meta control for hiding all vias @@ -813,7 +812,7 @@ void PCB_TRACK::GetMsgPanelInfoBase_Common( EDA_DRAW_FRAME* aFrame, wxString PCB_VIA::layerMaskDescribe() const { - BOARD* board = GetBoard(); + const BOARD* board = GetBoard(); PCB_LAYER_ID top_layer; PCB_LAYER_ID bottom_layer; diff --git a/pcbnew/zone.cpp b/pcbnew/zone.cpp index bec57e8983..74d2171636 100644 --- a/pcbnew/zone.cpp +++ b/pcbnew/zone.cpp @@ -1181,9 +1181,9 @@ bool ZONE::BuildSmoothedPoly( SHAPE_POLY_SET& aSmoothedPoly, PCB_LAYER_ID aLayer return true; } - BOARD* board = GetBoard(); - int maxError = ARC_HIGH_DEF; - bool keepExternalFillets = false; + const BOARD* board = GetBoard(); + int maxError = ARC_HIGH_DEF; + bool keepExternalFillets = false; if( board ) { @@ -1294,8 +1294,8 @@ void ZONE::TransformSmoothedOutlineToPolygon( SHAPE_POLY_SET& aCornerBuffer, int // holes are linked to the main outline, so only one polygon is created. if( aClearance ) { - BOARD* board = GetBoard(); - int maxError = ARC_HIGH_DEF; + const BOARD* board = GetBoard(); + int maxError = ARC_HIGH_DEF; if( board ) maxError = board->GetDesignSettings().m_MaxError; diff --git a/qa/pcbnew/test_libeval_compiler.cpp b/qa/pcbnew/test_libeval_compiler.cpp index 4f5aa23391..047d74dc7a 100644 --- a/qa/pcbnew/test_libeval_compiler.cpp +++ b/qa/pcbnew/test_libeval_compiler.cpp @@ -119,7 +119,7 @@ static bool testEvalExpr( const wxString& expr, LIBEVAL::VALUE expectedResult, if( ok ) { result = *ucode.Run( &context ); - ok = ( result.EqualTo( &expectedResult ) ); + ok = ( result.EqualTo( &context, &expectedResult ) ); }