Support for 'L' in DRC expression language.

Also make layer testing work again against both canonical names and
user names.
This commit is contained in:
Jeff Young 2020-09-27 19:43:44 +01:00
parent a2d9acb647
commit 09ab269770
5 changed files with 56 additions and 9 deletions

View File

@ -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; };

View File

@ -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<int>( aValue ) );
m_reverseMap[ aName ] = aValue;
return *this;

View File

@ -499,6 +499,7 @@ LSET DRC_RULES_PARSER::parseLayer()
{
reportError( wxString::Format( _( "Unrecognized layer '%s'." ),
layerName ) );
retVal.set( UNDEFINED_LAYER );
}
}

View File

@ -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();

View File

@ -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<PCB_LAYER_ID>::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<PCB_EXPR_CONTEXT*>( aCtx );
return PCB_LAYER_VALUE( context->GetLayer() );
}
BOARD_ITEM* item = const_cast<BOARD_ITEM*>( GetObject( aCtx ) );
auto it = m_matchingTypes.find( TYPE_HASH( *item ) );
@ -413,7 +448,7 @@ std::unique_ptr<LIBEVAL::VAR_REF> PCB_EXPR_UCODE::CreateVarRef( const wxString&
const wxString& aField )
{
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
std::unique_ptr<PCB_EXPR_VAR_REF> vref;;
std::unique_ptr<PCB_EXPR_VAR_REF> vref;
if( aVar == "A" )
{
@ -423,6 +458,10 @@ std::unique_ptr<LIBEVAL::VAR_REF> 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;