7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-11 10:40:13 +00:00

Add a null type for libeval / std::optional support

Fixes https://gitlab.com/kicad/code/kicad/-/issues/19158
This commit is contained in:
Jon Evans 2024-12-02 16:29:41 -05:00
parent 81b1200747
commit ecdc7ee08f
6 changed files with 47 additions and 6 deletions

View File

@ -115,6 +115,9 @@ bool VALUE::EqualTo( CONTEXT* aCtx, const VALUE* b ) const
if( m_type == VT_UNDEFINED || b->m_type == VT_UNDEFINED )
return false;
if( m_type == VT_NULL && b->m_type == VT_NULL )
return true;
if( m_type == VT_NUMERIC && b->m_type == VT_NUMERIC )
{
return AsDouble() == b->AsDouble();

View File

@ -85,7 +85,8 @@ enum VAR_TYPE_T
VT_STRING = 1,
VT_NUMERIC,
VT_UNDEFINED,
VT_PARSE_ERROR
VT_PARSE_ERROR,
VT_NULL
};
enum TOKEN_TYPE_T
@ -210,6 +211,13 @@ public:
m_isDeferredStr( false )
{};
static VALUE* MakeNullValue()
{
VALUE* v = new VALUE();
v->m_type = VT_NULL;
return v;
}
virtual ~VALUE()
{};

View File

@ -94,7 +94,7 @@ _HKI( "### More Examples\n"
"\n"
" # Disallow solder mask margin overrides\n"
" (rule \"disallow solder mask margin overrides\"\n"
" (constraint assertion \"A.Soldermask_Margin_Override == 0mm\")\n"
" (constraint assertion \"A.Soldermask_Margin_Override == null\")\n"
" (condition \"A.Type == 'Pad'\"))\n"
"\n"
"\n"

View File

@ -93,7 +93,7 @@
# Disallow solder mask margin overrides
(rule "disallow solder mask margin overrides"
(constraint assertion "A.Soldermask_Margin_Override == 0mm")
(constraint assertion "A.Soldermask_Margin_Override == null")
(condition "A.Type == 'Pad'"))

View File

@ -272,6 +272,9 @@ LIBEVAL::VALUE* PCBEXPR_VAR_REF::GetValue( LIBEVAL::CONTEXT* aCtx )
{
PCBEXPR_CONTEXT* context = static_cast<PCBEXPR_CONTEXT*>( aCtx );
if( m_type == LIBEVAL::VT_NULL )
return LIBEVAL::VALUE::MakeNullValue();
if( m_itemIndex == 2 )
return new PCBEXPR_LAYER_VALUE( context->GetLayer() );
@ -294,7 +297,17 @@ LIBEVAL::VALUE* PCBEXPR_VAR_REF::GetValue( LIBEVAL::CONTEXT* aCtx )
{
if( m_type == LIBEVAL::VT_NUMERIC )
{
return new LIBEVAL::VALUE( (double) item->Get<int>( it->second ) );
if( m_isOptional )
{
auto val = item->Get<std::optional<int>>( it->second );
if( val.has_value() )
return new LIBEVAL::VALUE( static_cast<double>( val.value() ) );
return LIBEVAL::VALUE::MakeNullValue();
}
return new LIBEVAL::VALUE( static_cast<double>( item->Get<int>( it->second ) ) );
}
else
{
@ -394,6 +407,13 @@ std::unique_ptr<LIBEVAL::VAR_REF> PCBEXPR_UCODE::CreateVarRef( const wxString& a
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
std::unique_ptr<PCBEXPR_VAR_REF> vref;
if( aVar.IsSameAs( wxT( "null" ), false ) )
{
vref = std::make_unique<PCBEXPR_VAR_REF>( 0 );
vref->SetType( LIBEVAL::VT_NULL );
return vref;
}
// Check for a couple of very common cases and compile them straight to "object code".
if( aField.CmpNoCase( wxT( "NetClass" ) ) == 0 )
@ -464,6 +484,11 @@ std::unique_ptr<LIBEVAL::VAR_REF> PCBEXPR_UCODE::CreateVarRef( const wxString& a
{
vref->SetType( LIBEVAL::VT_NUMERIC );
}
if( prop->TypeHash() == TYPE_HASH( std::optional<int> ) )
{
vref->SetType( LIBEVAL::VT_NUMERIC );
vref->SetIsOptional();
}
else if( prop->TypeHash() == TYPE_HASH( bool ) )
{
vref->SetType( LIBEVAL::VT_NUMERIC );
@ -475,7 +500,7 @@ std::unique_ptr<LIBEVAL::VAR_REF> PCBEXPR_UCODE::CreateVarRef( const wxString& a
else if ( prop->HasChoices() )
{ // it's an enum, we treat it as string
vref->SetType( LIBEVAL::VT_STRING );
vref->SetIsEnum ( true );
vref->SetIsEnum( true );
}
else
{

View File

@ -85,7 +85,8 @@ public:
PCBEXPR_VAR_REF( int aItemIndex ) :
m_itemIndex( aItemIndex ),
m_type( LIBEVAL::VT_UNDEFINED ),
m_isEnum( false )
m_isEnum( false ),
m_isOptional( false )
{}
~PCBEXPR_VAR_REF() {};
@ -93,6 +94,9 @@ public:
void SetIsEnum( bool s ) { m_isEnum = s; }
bool IsEnum() const { return m_isEnum; }
void SetIsOptional( bool s = true ) { m_isOptional = s; }
bool IsOptional() const { return m_isOptional; }
void SetType( LIBEVAL::VAR_TYPE_T type ) { m_type = type; }
LIBEVAL::VAR_TYPE_T GetType() const override { return m_type; }
@ -110,6 +114,7 @@ private:
int m_itemIndex;
LIBEVAL::VAR_TYPE_T m_type;
bool m_isEnum;
bool m_isOptional;
};