KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcbexpr_evaluator.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24
25#include <cstdio>
26#include <memory>
27#include <mutex>
28#include <board.h>
29#include <footprint.h>
30#include <lset.h>
32#include <pcbexpr_evaluator.h>
33#include <drc/drc_engine.h>
35
36/* --------------------------------------------------------------------------------------------
37 * Specialized Expression References
38 */
39
41{
42 wxASSERT( dynamic_cast<const PCBEXPR_CONTEXT*>( aCtx ) );
43
44 const PCBEXPR_CONTEXT* ctx = static_cast<const PCBEXPR_CONTEXT*>( aCtx );
45 BOARD_ITEM* item = ctx->GetItem( m_itemIndex );
46 return item;
47}
48
49
51{
52public:
54 LIBEVAL::VALUE( LayerName( aLayer ) ),
55 m_layer( aLayer )
56 {};
57
58 virtual bool EqualTo( LIBEVAL::CONTEXT* aCtx, const VALUE* b ) const override
59 {
60 // For boards with user-defined layer names there will be 2 entries for each layer
61 // in the ENUM_MAP: one for the canonical layer name and one for the user layer name.
62 // We need to check against both.
63
64 wxPGChoices& layerMap = ENUM_MAP<PCB_LAYER_ID>::Instance().Choices();
65 const wxString& layerName = b->AsString();
66 BOARD* board = static_cast<PCBEXPR_CONTEXT*>( aCtx )->GetBoard();
67
68 {
69 std::shared_lock<std::shared_mutex> readLock( board->m_CachesMutex );
70
71 auto i = board->m_LayerExpressionCache.find( layerName );
72
73 if( i != board->m_LayerExpressionCache.end() )
74 return i->second.Contains( m_layer );
75 }
76
77 LSET mask;
78
79 for( unsigned ii = 0; ii < layerMap.GetCount(); ++ii )
80 {
81 wxPGChoiceEntry& entry = layerMap[ii];
82
83 if( entry.GetText().Matches( layerName ) )
84 mask.set( ToLAYER_ID( entry.GetValue() ) );
85 }
86
87 {
88 std::unique_lock<std::shared_mutex> writeLock( board->m_CachesMutex );
89 board->m_LayerExpressionCache[ layerName ] = mask;
90 }
91
92 return mask.Contains( m_layer );
93 }
94
95protected:
97};
98
99
101{
102public:
103 PCBEXPR_PINTYPE_VALUE( const wxString& aPinTypeName ) :
104 LIBEVAL::VALUE( aPinTypeName )
105 {};
106
107 bool EqualTo( LIBEVAL::CONTEXT* aCtx, const VALUE* b ) const override
108 {
109 const wxString& thisStr = AsString();
110 const wxString& otherStr = b->AsString();
111
112 // Case insensitive
113 if( thisStr.IsSameAs( otherStr, false ) )
114 return true;
115
116 // Wildcards
117 if( thisStr.Matches( otherStr ) )
118 return true;
119
120 // Handle cases where the netlist token is different from the EEschema token
121 wxString altStr;
122
123 if( thisStr == wxT( "tri_state" ) )
124 altStr = wxT( "Tri-state" );
125 else if( thisStr == wxT( "power_in" ) )
126 altStr = wxT( "Power input" );
127 else if( thisStr == wxT( "power_out" ) )
128 altStr = wxT( "Power output" );
129 else if( thisStr == wxT( "no_connect" ) )
130 altStr = wxT( "Unconnected" );
131
132 if( !altStr.IsEmpty() )
133 {
134 // Case insensitive
135 if( altStr.IsSameAs( otherStr, false ) )
136 return true;
137
138 // Wildcards
139 if( altStr.Matches( otherStr ) )
140 return true;
141 }
142
143 return false;
144 }
145};
146
147
149{
150public:
152 LIBEVAL::VALUE( wxEmptyString ),
153 m_item( aItem )
154 {};
155
156 const wxString& AsString() const override
157 {
158 const_cast<PCBEXPR_NETCLASS_VALUE*>( this )->Set( m_item->GetEffectiveNetClass()->GetName() );
160 }
161
162 bool EqualTo( LIBEVAL::CONTEXT* aCtx, const VALUE* b ) const override
163 {
164 if( const PCBEXPR_NETCLASS_VALUE* bValue = dynamic_cast<const PCBEXPR_NETCLASS_VALUE*>( b ) )
165 return *( m_item->GetEffectiveNetClass() ) == *( bValue->m_item->GetEffectiveNetClass() );
166
167 if( b->GetType() == LIBEVAL::VT_STRING )
168 {
169 // Test constituent net class names. The effective net class name (e.g. CLASS1,CLASS2,OTHER_CLASS) is
170 // tested in the fallthrough condition.
171 for( const auto nc : m_item->GetEffectiveNetClass()->GetConstituentNetclasses() )
172 {
173 const wxString& ncName = nc->GetName();
174
175 if( b->StringIsWildcard() )
176 {
177 if( WildCompareString( b->AsString(), ncName, false ) )
178 return true;
179 }
180 else
181 {
182 if( ncName.IsSameAs( b->AsString(), false ) )
183 return true;
184 }
185 }
186 }
187
188 return LIBEVAL::VALUE::EqualTo( aCtx, b );
189 }
190
191 bool NotEqualTo( LIBEVAL::CONTEXT* aCtx, const LIBEVAL::VALUE* b ) const override
192 {
193 if( const PCBEXPR_NETCLASS_VALUE* bValue = dynamic_cast<const PCBEXPR_NETCLASS_VALUE*>( b ) )
194 return *( m_item->GetEffectiveNetClass() ) != *( bValue->m_item->GetEffectiveNetClass() );
195
196 if( b->GetType() == LIBEVAL::VT_STRING )
197 {
198 // Test constituent net class names
199 bool isInConstituents = false;
200
201 for( const auto nc : m_item->GetEffectiveNetClass()->GetConstituentNetclasses() )
202 {
203 const wxString& ncName = nc->GetName();
204
205 if( b->StringIsWildcard() )
206 {
207 if( WildCompareString( b->AsString(), ncName, false ) )
208 {
209 isInConstituents = true;
210 break;
211 }
212 }
213 else
214 {
215 if( ncName.IsSameAs( b->AsString(), false ) )
216 {
217 isInConstituents = true;
218 break;
219 }
220 }
221 }
222
223 // Test effective net class name
224 const bool isFullName = LIBEVAL::VALUE::EqualTo( aCtx, b );
225
226 return !isInConstituents && !isFullName;
227 }
228
229 return LIBEVAL::VALUE::NotEqualTo( aCtx, b );
230 }
231
232protected:
234};
235
236
238{
239public:
241 LIBEVAL::VALUE( wxEmptyString ),
242 m_item( dynamic_cast<FOOTPRINT*>( aItem ) )
243 {};
244
245 const wxString& AsString() const override
246 {
247 if( !m_item )
249
250 if( const COMPONENT_CLASS* compClass = m_item->GetComponentClass() )
251 const_cast<PCBEXPR_COMPONENT_CLASS_VALUE*>( this )->Set( compClass->GetName() );
252
254 }
255
256 bool EqualTo( LIBEVAL::CONTEXT* aCtx, const VALUE* b ) const override
257 {
258 if( const PCBEXPR_COMPONENT_CLASS_VALUE* bValue = dynamic_cast<const PCBEXPR_COMPONENT_CLASS_VALUE*>( b ) )
259 {
260 if( !m_item || !bValue->m_item )
261 return LIBEVAL::VALUE::EqualTo( aCtx, b );
262
263 const COMPONENT_CLASS* aClass = m_item->GetComponentClass();
264 const COMPONENT_CLASS* bClass = bValue->m_item->GetComponentClass();
265
266 return *aClass == *bClass;
267 }
268
269 if( b->GetType() == LIBEVAL::VT_STRING )
270 {
271 // Test constituent component class names. The effective component class name
272 // (e.g. CLASS1,CLASS2,OTHER_CLASS) is tested in the fallthrough condition.
273 for( const auto cc : m_item->GetComponentClass()->GetConstituentClasses() )
274 {
275 const wxString& ccName = cc->GetName();
276
277 if( b->StringIsWildcard() )
278 {
279 if( WildCompareString( b->AsString(), ccName, false ) )
280 return true;
281 }
282 else
283 {
284 if( ccName.IsSameAs( b->AsString(), false ) )
285 return true;
286 }
287 }
288 }
289
290 return LIBEVAL::VALUE::EqualTo( aCtx, b );
291 }
292
293 bool NotEqualTo( LIBEVAL::CONTEXT* aCtx, const LIBEVAL::VALUE* b ) const override
294 {
295 if( const PCBEXPR_COMPONENT_CLASS_VALUE* bValue = dynamic_cast<const PCBEXPR_COMPONENT_CLASS_VALUE*>( b ) )
296 {
297 if( !m_item || !bValue->m_item )
298 return LIBEVAL::VALUE::NotEqualTo( aCtx, b );
299
300 const COMPONENT_CLASS* aClass = m_item->GetComponentClass();
301 const COMPONENT_CLASS* bClass = bValue->m_item->GetComponentClass();
302
303 return *aClass != *bClass;
304 }
305
306 if( b->GetType() == LIBEVAL::VT_STRING )
307 {
308 // Test constituent component class names
309 bool isInConstituents = false;
310
311 for( const auto cc : m_item->GetComponentClass()->GetConstituentClasses() )
312 {
313 const wxString& ccName = cc->GetName();
314
315 if( b->StringIsWildcard() )
316 {
317 if( WildCompareString( b->AsString(), ccName, false ) )
318 {
319 isInConstituents = true;
320 break;
321 }
322 }
323 else
324 {
325 if( ccName.IsSameAs( b->AsString(), false ) )
326 {
327 isInConstituents = true;
328 break;
329 }
330 }
331 }
332
333 // Test effective component class name
334 const bool isFullName = LIBEVAL::VALUE::EqualTo( aCtx, b );
335
336 return !isInConstituents && !isFullName;
337 }
338
339 return LIBEVAL::VALUE::NotEqualTo( aCtx, b );
340 }
341
342protected:
344};
345
346
348{
349public:
351 LIBEVAL::VALUE( wxEmptyString ),
352 m_item( aItem )
353 {};
354
355 const wxString& AsString() const override
356 {
357 const_cast<PCBEXPR_NET_VALUE*>( this )->Set( m_item->GetNetname() );
359 }
360
361 bool EqualTo( LIBEVAL::CONTEXT* aCtx, const VALUE* b ) const override
362 {
363 if( const PCBEXPR_NET_VALUE* bValue = dynamic_cast<const PCBEXPR_NET_VALUE*>( b ) )
364 return m_item->GetNetCode() == bValue->m_item->GetNetCode();
365 else
366 return LIBEVAL::VALUE::EqualTo( aCtx, b );
367 }
368
369 bool NotEqualTo( LIBEVAL::CONTEXT* aCtx, const LIBEVAL::VALUE* b ) const override
370 {
371 if( const PCBEXPR_NET_VALUE* bValue = dynamic_cast<const PCBEXPR_NET_VALUE*>( b ) )
372 return m_item->GetNetCode() != bValue->m_item->GetNetCode();
373 else
374 return LIBEVAL::VALUE::NotEqualTo( aCtx, b );
375 }
376
377protected:
379};
380
381
383{
384 PCBEXPR_CONTEXT* context = static_cast<PCBEXPR_CONTEXT*>( aCtx );
385
386 if( m_type == LIBEVAL::VT_NULL )
388
389 if( m_itemIndex == 2 )
390 return new PCBEXPR_LAYER_VALUE( context->GetLayer() );
391
392 BOARD_ITEM* item = GetObject( aCtx );
393
394 if( !item )
395 return new LIBEVAL::VALUE();
396
397 auto it = m_matchingTypes.find( TYPE_HASH( *item ) );
398
399 if( it == m_matchingTypes.end() )
400 {
401 // Don't force user to type "A.Type == 'via' && A.Via_Type == 'buried'" when the
402 // simpler "A.Via_Type == 'buried'" is perfectly clear. Instead, return an undefined
403 // value when the property doesn't appear on a particular object.
404
405 return new LIBEVAL::VALUE();
406 }
407 else
408 {
410 {
411 if( m_isOptional )
412 {
413 auto val = item->Get<std::optional<int>>( it->second );
414
415 if( val.has_value() )
416 return new LIBEVAL::VALUE( static_cast<double>( val.value() ) );
417
419 }
420
421 return new LIBEVAL::VALUE( static_cast<double>( item->Get<int>( it->second ) ) );
422 }
424 {
425 if( m_isOptional )
426 {
427 auto val = item->Get<std::optional<double>>( it->second );
428
429 if( val.has_value() )
430 return new LIBEVAL::VALUE( val.value() );
431
433 }
434
435 return new LIBEVAL::VALUE( item->Get<double>( it->second ) );
436 }
437 else
438 {
439 wxString str;
440
441 if( !m_isEnum )
442 {
443 str = item->Get<wxString>( it->second );
444
445 if( it->second->Name() == wxT( "Pin Type" ) )
446 return new PCBEXPR_PINTYPE_VALUE( str );
447 else
448 return new LIBEVAL::VALUE( str );
449 }
450 else
451 {
452 const wxAny& any = item->Get( it->second );
453 PCB_LAYER_ID layer;
454
455 if( it->second->Name() == wxT( "Layer" )
456 || it->second->Name() == wxT( "Layer Top" )
457 || it->second->Name() == wxT( "Layer Bottom" ) )
458 {
459 if( any.GetAs<PCB_LAYER_ID>( &layer ) )
460 return new PCBEXPR_LAYER_VALUE( layer );
461 else if( any.GetAs<wxString>( &str ) )
462 return new PCBEXPR_LAYER_VALUE( context->GetBoard()->GetLayerID( str ) );
463 }
464 else
465 {
466 if( any.GetAs<wxString>( &str ) )
467 return new LIBEVAL::VALUE( str );
468 }
469 }
470
471 return new LIBEVAL::VALUE();
472 }
473 }
474}
475
476
478{
479 BOARD_CONNECTED_ITEM* item = dynamic_cast<BOARD_CONNECTED_ITEM*>( GetObject( aCtx ) );
480
481 if( !item )
482 return new LIBEVAL::VALUE();
483
484 return new PCBEXPR_NETCLASS_VALUE( item );
485}
486
487
489{
490 BOARD_ITEM* item = dynamic_cast<BOARD_ITEM*>( GetObject( aCtx ) );
491
492 if( !item || item->Type() != PCB_FOOTPRINT_T )
493 return new LIBEVAL::VALUE();
494
495 return new PCBEXPR_COMPONENT_CLASS_VALUE( item );
496}
497
498
500{
501 BOARD_CONNECTED_ITEM* item = dynamic_cast<BOARD_CONNECTED_ITEM*>( GetObject( aCtx ) );
502
503 if( !item )
504 return new LIBEVAL::VALUE();
505
506 return new PCBEXPR_NET_VALUE( item );
507}
508
509
511{
512 BOARD_ITEM* item = GetObject( aCtx );
513
514 if( !item )
515 return new LIBEVAL::VALUE();
516
517 return new LIBEVAL::VALUE( ENUM_MAP<KICAD_T>::Instance().ToString( item->Type() ) );
518}
519
520
522{
524
525 return registry.Get( aName.Lower() );
526}
527
528
529std::unique_ptr<LIBEVAL::VAR_REF> PCBEXPR_UCODE::CreateVarRef( const wxString& aVar,
530 const wxString& aField )
531{
533 std::unique_ptr<PCBEXPR_VAR_REF> vref;
534
535 if( aVar.IsSameAs( wxT( "null" ), false ) )
536 {
537 vref = std::make_unique<PCBEXPR_VAR_REF>( 0 );
538 vref->SetType( LIBEVAL::VT_NULL );
539 return vref;
540 }
541
542 // Check for a couple of very common cases and compile them straight to "object code".
543
544 if( aField.CmpNoCase( wxT( "NetClass" ) ) == 0 )
545 {
546 if( aVar == wxT( "A" ) )
547 return std::make_unique<PCBEXPR_NETCLASS_REF>( 0 );
548 else if( aVar == wxT( "B" ) )
549 return std::make_unique<PCBEXPR_NETCLASS_REF>( 1 );
550 else
551 return nullptr;
552 }
553 else if( aField.CmpNoCase( wxT( "ComponentClass" ) ) == 0 )
554 {
555 if( aVar == wxT( "A" ) )
556 return std::make_unique<PCBEXPR_COMPONENT_CLASS_REF>( 0 );
557 else if( aVar == wxT( "B" ) )
558 return std::make_unique<PCBEXPR_COMPONENT_CLASS_REF>( 1 );
559 else
560 return nullptr;
561 }
562 else if( aField.CmpNoCase( wxT( "NetName" ) ) == 0 )
563 {
564 if( aVar == wxT( "A" ) )
565 return std::make_unique<PCBEXPR_NETNAME_REF>( 0 );
566 else if( aVar == wxT( "B" ) )
567 return std::make_unique<PCBEXPR_NETNAME_REF>( 1 );
568 else
569 return nullptr;
570 }
571 else if( aField.CmpNoCase( wxT( "Type" ) ) == 0 )
572 {
573 if( aVar == wxT( "A" ) )
574 return std::make_unique<PCBEXPR_TYPE_REF>( 0 );
575 else if( aVar == wxT( "B" ) )
576 return std::make_unique<PCBEXPR_TYPE_REF>( 1 );
577 else
578 return nullptr;
579 }
580
581 if( aVar == wxT( "A" ) || aVar == wxT( "AB" ) )
582 vref = std::make_unique<PCBEXPR_VAR_REF>( 0 );
583 else if( aVar == wxT( "B" ) )
584 vref = std::make_unique<PCBEXPR_VAR_REF>( 1 );
585 else if( aVar == wxT( "L" ) )
586 vref = std::make_unique<PCBEXPR_VAR_REF>( 2 );
587 else
588 return nullptr;
589
590 if( aField.length() == 0 ) // return reference to base object
591 return vref;
592
593 wxString field( aField );
594 field.Replace( wxT( "_" ), wxT( " " ) );
595
596 for( const PROPERTY_MANAGER::CLASS_INFO& cls : propMgr.GetAllClasses() )
597 {
598 if( propMgr.IsOfType( cls.type, TYPE_HASH( BOARD_ITEM ) ) )
599 {
600 PROPERTY_BASE* prop = propMgr.GetProperty( cls.type, field );
601
602 if( prop )
603 {
604 vref->AddAllowedClass( cls.type, prop );
605
606 if( prop->TypeHash() == TYPE_HASH( int ) )
607 {
608 vref->SetType( LIBEVAL::VT_NUMERIC );
609 }
610 else if( prop->TypeHash() == TYPE_HASH( std::optional<int> ) )
611 {
612 vref->SetType( LIBEVAL::VT_NUMERIC );
613 vref->SetIsOptional();
614 }
615 else if( prop->TypeHash() == TYPE_HASH( double ) )
616 {
617 vref->SetType( LIBEVAL::VT_NUMERIC_DOUBLE );
618 }
619 else if( prop->TypeHash() == TYPE_HASH( std::optional<double> ) )
620 {
621 vref->SetType( LIBEVAL::VT_NUMERIC_DOUBLE );
622 vref->SetIsOptional();
623 }
624 else if( prop->TypeHash() == TYPE_HASH( bool ) )
625 {
626 vref->SetType( LIBEVAL::VT_NUMERIC );
627 }
628 else if( prop->TypeHash() == TYPE_HASH( wxString ) )
629 {
630 vref->SetType( LIBEVAL::VT_STRING );
631 }
632 else if ( prop->HasChoices() )
633 { // it's an enum, we treat it as string
634 vref->SetType( LIBEVAL::VT_STRING );
635 vref->SetIsEnum( true );
636 }
637 else
638 {
639 wxString msg = wxString::Format( wxT( "PCBEXPR_UCODE::createVarRef: Unknown "
640 "property type %s from %s." ),
641 cls.name,
642 field );
643 wxFAIL_MSG( msg );
644 }
645 }
646 }
647 }
648
649 if( vref->GetType() == LIBEVAL::VT_UNDEFINED )
650 vref->SetType( LIBEVAL::VT_PARSE_ERROR );
651
652 return vref;
653}
654
655
657{
658 if( m_items[0] )
659 return m_items[0]->GetBoard();
660
661 return nullptr;
662}
663
664
665/* --------------------------------------------------------------------------------------------
666 * Unit Resolvers
667 */
668
669const std::vector<wxString>& PCBEXPR_UNIT_RESOLVER::GetSupportedUnits() const
670{
671 static const std::vector<wxString> pcbUnits = { wxT( "mil" ), wxT( "mm" ), wxT( "in" ),
672 wxT( "deg" ), wxT( "fs" ), wxT( "ps" ) };
673
674
675 return pcbUnits;
676}
677
678
680{
681 return _( "must be mm, in, mil, deg, fs, or ps" );
682}
683
684
685const std::vector<EDA_UNITS>& PCBEXPR_UNIT_RESOLVER::GetSupportedUnitsTypes() const
686{
687 static const std::vector<EDA_UNITS> pcbUnits = { EDA_UNITS::MILS, EDA_UNITS::MM, EDA_UNITS::INCH,
688 EDA_UNITS::DEGREES, EDA_UNITS::FS, EDA_UNITS::PS };
689
690 return pcbUnits;
691}
692
693
694double PCBEXPR_UNIT_RESOLVER::Convert( const wxString& aString, int unitId ) const
695{
696 double v = wxAtof( aString );
697
698 switch( unitId )
699 {
700 case 0: return EDA_UNIT_UTILS::UI::DoubleValueFromString( pcbIUScale, EDA_UNITS::MILS, aString );
701 case 1: return EDA_UNIT_UTILS::UI::DoubleValueFromString( pcbIUScale, EDA_UNITS::MM, aString );
702 case 2: return EDA_UNIT_UTILS::UI::DoubleValueFromString( pcbIUScale, EDA_UNITS::INCH, aString );
703 case 3: return v;
704 case 4: return EDA_UNIT_UTILS::UI::DoubleValueFromString( pcbIUScale, EDA_UNITS::FS, aString );
705 case 5: return EDA_UNIT_UTILS::UI::DoubleValueFromString( pcbIUScale, EDA_UNITS::PS, aString );
706 default: return v;
707 }
708};
709
710
711const std::vector<wxString>& PCBEXPR_UNITLESS_RESOLVER::GetSupportedUnits() const
712{
713 static const std::vector<wxString> emptyUnits;
714
715 return emptyUnits;
716}
717
718
719const std::vector<EDA_UNITS>& PCBEXPR_UNITLESS_RESOLVER::GetSupportedUnitsTypes() const
720{
721 static const std::vector<EDA_UNITS> emptyUnits;
722
723 return emptyUnits;
724}
725
726
727double PCBEXPR_UNITLESS_RESOLVER::Convert( const wxString& aString, int unitId ) const
728{
729 return wxAtof( aString );
730};
731
732
734{
735 m_unitResolver.reset( aUnitResolver );
736}
737
738
739/* --------------------------------------------------------------------------------------------
740 * PCB Expression Evaluator
741 */
742
744 m_result( 0 ),
745 m_units( EDA_UNITS::MM ),
746 m_compiler( aUnitResolver ),
747 m_ucode(),
748 m_errorStatus()
749{
750}
751
752
754{
755}
756
757
758bool PCBEXPR_EVALUATOR::Evaluate( const wxString& aExpr )
759{
760 PCBEXPR_UCODE ucode;
761 PCBEXPR_CONTEXT preflightContext( NULL_CONSTRAINT, F_Cu );
762
763 if( !m_compiler.Compile( aExpr.ToUTF8().data(), &ucode, &preflightContext ) )
764 return false;
765
766 PCBEXPR_CONTEXT evaluationContext( NULL_CONSTRAINT, F_Cu );
767 LIBEVAL::VALUE* result = ucode.Run( &evaluationContext );
768
769 if( result->GetType() == LIBEVAL::VT_NUMERIC )
770 {
771 m_result = KiROUND( result->AsDouble() );
772 m_units = result->GetUnits();
773 }
774
775 return true;
776}
777
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:112
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition: box2.h:990
BASE_SET & set(size_t pos)
Definition: base_set.h:116
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
virtual NETCLASS * GetEffectiveNetClass() const
Return the NETCLASS for this item.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:79
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:79
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:317
PCB_LAYER_ID GetLayerID(const wxString &aLayerName) const
Return the ID of a layer.
Definition: board.cpp:594
std::unordered_map< wxString, LSET > m_LayerExpressionCache
Definition: board.h:1347
std::shared_mutex m_CachesMutex
Definition: board.h:1341
A lightweight representation of a component class.
const wxString & GetName() const
Fetches the full name of this component class.
const std::vector< COMPONENT_CLASS * > & GetConstituentClasses() const
Fetches a vector of the constituent classes for this (effective) class.
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:109
static ENUM_MAP< T > & Instance()
Definition: property.h:681
const COMPONENT_CLASS * GetComponentClass() const
Returns the component class for this footprint.
Definition: footprint.cpp:4059
wxAny Get(PROPERTY_BASE *aProperty) const
Definition: inspectable.h:100
std::unique_ptr< UNIT_RESOLVER > m_unitResolver
bool Compile(const wxString &aString, UCODE *aCode, CONTEXT *aPreflightContext)
VALUE * Run(CONTEXT *ctx)
void Set(double aValue)
virtual const wxString & AsString() const
bool StringIsWildcard() const
static VALUE * MakeNullValue()
virtual bool NotEqualTo(CONTEXT *aCtx, const VALUE *b) const
virtual double AsDouble() const
EDA_UNITS GetUnits() const
VAR_TYPE_T GetType() const
virtual bool EqualTo(CONTEXT *aCtx, const VALUE *b) const
LSET is a set of PCB_LAYER_IDs.
Definition: lset.h:37
bool Contains(PCB_LAYER_ID aLayer) const
See if the layer set contains a PCB layer.
Definition: lset.h:63
const wxString GetName() const
Gets the name of this (maybe aggregate) netclass in a format for internal usage or for export to exte...
Definition: netclass.cpp:322
const std::vector< NETCLASS * > & GetConstituentNetclasses() const
Gets the netclasses which make up this netclass.
Definition: netclass.cpp:266
LIBEVAL::FUNC_CALL_REF Get(const wxString &name)
static PCBEXPR_BUILTIN_FUNCTIONS & Instance()
PCBEXPR_COMPILER(LIBEVAL::UNIT_RESOLVER *aUnitResolver)
LIBEVAL::VALUE * GetValue(LIBEVAL::CONTEXT *aCtx) override
bool NotEqualTo(LIBEVAL::CONTEXT *aCtx, const LIBEVAL::VALUE *b) const override
const wxString & AsString() const override
PCBEXPR_COMPONENT_CLASS_VALUE(BOARD_ITEM *aItem)
bool EqualTo(LIBEVAL::CONTEXT *aCtx, const VALUE *b) const override
BOARD_ITEM * m_items[2]
BOARD * GetBoard() const
PCB_LAYER_ID GetLayer() const
BOARD_ITEM * GetItem(int index) const
PCBEXPR_EVALUATOR(LIBEVAL::UNIT_RESOLVER *aUnitResolver)
PCBEXPR_COMPILER m_compiler
bool Evaluate(const wxString &aExpr)
PCBEXPR_LAYER_VALUE(PCB_LAYER_ID aLayer)
virtual bool EqualTo(LIBEVAL::CONTEXT *aCtx, const VALUE *b) const override
LIBEVAL::VALUE * GetValue(LIBEVAL::CONTEXT *aCtx) override
bool EqualTo(LIBEVAL::CONTEXT *aCtx, const VALUE *b) const override
BOARD_CONNECTED_ITEM * m_item
PCBEXPR_NETCLASS_VALUE(BOARD_CONNECTED_ITEM *aItem)
const wxString & AsString() const override
bool NotEqualTo(LIBEVAL::CONTEXT *aCtx, const LIBEVAL::VALUE *b) const override
LIBEVAL::VALUE * GetValue(LIBEVAL::CONTEXT *aCtx) override
bool EqualTo(LIBEVAL::CONTEXT *aCtx, const VALUE *b) const override
BOARD_CONNECTED_ITEM * m_item
PCBEXPR_NET_VALUE(BOARD_CONNECTED_ITEM *aItem)
bool NotEqualTo(LIBEVAL::CONTEXT *aCtx, const LIBEVAL::VALUE *b) const override
const wxString & AsString() const override
bool EqualTo(LIBEVAL::CONTEXT *aCtx, const VALUE *b) const override
PCBEXPR_PINTYPE_VALUE(const wxString &aPinTypeName)
LIBEVAL::VALUE * GetValue(LIBEVAL::CONTEXT *aCtx) override
virtual std::unique_ptr< LIBEVAL::VAR_REF > CreateVarRef(const wxString &aVar, const wxString &aField) override
virtual LIBEVAL::FUNC_CALL_REF CreateFuncCall(const wxString &aName) override
const std::vector< wxString > & GetSupportedUnits() const override
const std::vector< EDA_UNITS > & GetSupportedUnitsTypes() const override
double Convert(const wxString &aString, int unitId) const override
double Convert(const wxString &aString, int unitId) const override
const std::vector< EDA_UNITS > & GetSupportedUnitsTypes() const override
wxString GetSupportedUnitsMessage() const override
const std::vector< wxString > & GetSupportedUnits() const override
std::unordered_map< TYPE_ID, PROPERTY_BASE * > m_matchingTypes
LIBEVAL::VALUE * GetValue(LIBEVAL::CONTEXT *aCtx) override
LIBEVAL::VAR_TYPE_T m_type
BOARD_ITEM * GetObject(const LIBEVAL::CONTEXT *aCtx) const
virtual size_t TypeHash() const =0
Return type-id of the property type.
virtual bool HasChoices() const
Return true if this PROPERTY has a limited set of possible values.
Definition: property.h:242
Provide class metadata.Helper macro to map type hashes to names.
Definition: property_mgr.h:85
CLASSES_INFO GetAllClasses()
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:87
PROPERTY_BASE * GetProperty(TYPE_ID aType, const wxString &aProperty) const
Return a property for a specific type.
bool IsOfType(TYPE_ID aDerived, TYPE_ID aBase) const
Return true if aDerived is inherited from aBase.
@ NULL_CONSTRAINT
Definition: drc_rule.h:48
#define _(s)
EDA_UNITS
Definition: eda_units.h:48
wxString LayerName(int aLayer)
Returns the default display name for a given layer.
Definition: layer_id.cpp:31
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ F_Cu
Definition: layer_ids.h:64
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:747
KICOMMON_API double DoubleValueFromString(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, const wxString &aTextValue, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Convert aTextValue to a double.
Definition: eda_units.cpp:559
std::function< void(CONTEXT *, void *)> FUNC_CALL_REF
BOARD * GetBoard()
#define TYPE_HASH(x)
Definition: property.h:72
bool WildCompareString(const wxString &pattern, const wxString &string_to_tst, bool case_sensitive)
Compare a string against wild card (* and ?) pattern using the usual rules.
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition: typeinfo.h:86