Cleanup.
This commit is contained in:
parent
5d9301d394
commit
8420fcc33b
|
@ -511,6 +511,7 @@ set( PCB_COMMON_SRCS
|
|||
${CMAKE_SOURCE_DIR}/pcbnew/convert_drawsegment_list_to_polygon.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/drc/drc_item.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/drc/drc_rule.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/drc/drc_rule_condition.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/eagle_plugin.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/footprint_editor_settings.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/gpcb_plugin.cpp
|
||||
|
|
|
@ -111,7 +111,7 @@ int BOARD_CONNECTED_ITEM::GetClearance( PCB_LAYER_ID aLayer, BOARD_ITEM* aItem,
|
|||
|
||||
// LEVEL 2: Rules
|
||||
//
|
||||
if( GetRuleClearance( aItem, aLayer, &clearance, aSource, aReporter ) )
|
||||
if( GetRuleClearance( aItem, aLayer, &clearance, aSource ) )
|
||||
return clearance;
|
||||
|
||||
// LEVEL 3: Accumulated local settings, netclass settings, & board design settings
|
||||
|
@ -153,11 +153,10 @@ int BOARD_CONNECTED_ITEM::GetClearance( PCB_LAYER_ID aLayer, BOARD_ITEM* aItem,
|
|||
|
||||
|
||||
bool BOARD_CONNECTED_ITEM::GetRuleClearance( BOARD_ITEM* aItem, PCB_LAYER_ID aLayer,
|
||||
int* aClearance, wxString* aSource,
|
||||
REPORTER* aReporter ) const
|
||||
int* aClearance, wxString* aSource ) const
|
||||
{
|
||||
const DRC_CONSTRAINT* constraint = GetConstraint( this, aItem, DRC_CONSTRAINT_TYPE_CLEARANCE,
|
||||
aLayer, aSource, aReporter );
|
||||
aLayer, aSource );
|
||||
|
||||
if( constraint )
|
||||
{
|
||||
|
@ -166,12 +165,6 @@ bool BOARD_CONNECTED_ITEM::GetRuleClearance( BOARD_ITEM* aItem, PCB_LAYER_ID aLa
|
|||
|
||||
*aClearance = constraint->m_Value.Min();
|
||||
|
||||
if( aReporter )
|
||||
{
|
||||
wxString clearance = StringFromValue( aReporter->GetUnits(), *aClearance, true );
|
||||
aReporter->Report( wxString::Format( _( "Clearance: %s." ), clearance ) );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -179,7 +179,7 @@ public:
|
|||
* @return true if a rule was fired
|
||||
*/
|
||||
virtual bool GetRuleClearance( BOARD_ITEM* aItem, PCB_LAYER_ID aLayer, int* aClearance,
|
||||
wxString* aSource, REPORTER* aReporter = nullptr ) const;
|
||||
wxString* aSource ) const;
|
||||
|
||||
/**
|
||||
* Function GetLocalClearanceOverrides
|
||||
|
|
|
@ -23,19 +23,15 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
// fixme - way too much includes
|
||||
#include <fctsys.h>
|
||||
#include <pcbnew.h>
|
||||
|
||||
#include <reporter.h>
|
||||
#include <widgets/progress_reporter.h>
|
||||
|
||||
#include <drc/drc_engine.h>
|
||||
#include <drc/drc_rule_parser.h>
|
||||
#include <drc/drc_rule.h>
|
||||
#include <drc/drc_item.h>
|
||||
#include <drc/drc_rule_condition.h>
|
||||
#include <drc/drc_test_provider.h>
|
||||
#include "drc.h"
|
||||
#include <drc/drc.h>
|
||||
|
||||
void drcPrintDebugMessage( int level, wxString msg, const char *function, int line )
|
||||
{
|
||||
|
@ -297,6 +293,45 @@ static wxString formatConstraint( const DRC_CONSTRAINT& constraint )
|
|||
}
|
||||
|
||||
|
||||
bool DRC_ENGINE::LoadRules( wxFileName aPath )
|
||||
{
|
||||
NULL_REPORTER nullReporter;
|
||||
REPORTER* reporter = m_reporter ? m_reporter : &nullReporter;
|
||||
|
||||
if( aPath.FileExists() )
|
||||
{
|
||||
m_ruleConditions.clear();
|
||||
m_rules.clear();
|
||||
|
||||
FILE* fp = wxFopen( aPath.GetFullPath(), wxT( "rt" ) );
|
||||
|
||||
if( fp )
|
||||
{
|
||||
try
|
||||
{
|
||||
DRC_RULES_PARSER parser( m_board, fp, aPath.GetFullPath() );
|
||||
parser.Parse( m_rules, reporter );
|
||||
}
|
||||
catch( PARSE_ERROR& pe )
|
||||
{
|
||||
// Don't leave possibly malformed stuff around for us to trip over
|
||||
m_ruleConditions.clear();
|
||||
m_rules.clear();
|
||||
|
||||
// JEY TODO
|
||||
//wxSafeYield( m_editFrame );
|
||||
//m_editFrame->ShowBoardSetupDialog( _( "Rules" ), pe.What(), ID_RULES_EDITOR,
|
||||
// pe.lineNumber, pe.byteIndex );
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool DRC_ENGINE::CompileRules()
|
||||
{
|
||||
ReportAux( wxString::Format( "Compiling Rules (%d rules, %d conditions): ",
|
||||
|
@ -375,45 +410,6 @@ bool DRC_ENGINE::CompileRules()
|
|||
}
|
||||
|
||||
|
||||
bool DRC_ENGINE::LoadRules( wxFileName aPath )
|
||||
{
|
||||
NULL_REPORTER nullReporter;
|
||||
REPORTER* reporter = m_reporter ? m_reporter : &nullReporter;
|
||||
|
||||
if( aPath.FileExists() )
|
||||
{
|
||||
m_ruleConditions.clear();
|
||||
m_rules.clear();
|
||||
|
||||
FILE* fp = wxFopen( aPath.GetFullPath(), wxT( "rt" ) );
|
||||
|
||||
if( fp )
|
||||
{
|
||||
try
|
||||
{
|
||||
DRC_RULES_PARSER parser( m_board, fp, aPath.GetFullPath() );
|
||||
parser.Parse( m_rules, reporter );
|
||||
}
|
||||
catch( PARSE_ERROR& pe )
|
||||
{
|
||||
// Don't leave possibly malformed stuff around for us to trip over
|
||||
m_ruleConditions.clear();
|
||||
m_rules.clear();
|
||||
|
||||
// JEY TODO
|
||||
//wxSafeYield( m_editFrame );
|
||||
//m_editFrame->ShowBoardSetupDialog( _( "Rules" ), pe.What(), ID_RULES_EDITOR,
|
||||
// pe.lineNumber, pe.byteIndex );
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void DRC_ENGINE::InitEngine( wxFileName aRulePath )
|
||||
{
|
||||
m_testProviders = DRC_TEST_PROVIDER_REGISTRY::Instance().GetTestProviders();
|
||||
|
@ -570,10 +566,12 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRulesForItems( DRC_CONSTRAINT_TYPE_T aConstraintI
|
|||
nullConstraint.m_DisallowFlags = 0;
|
||||
|
||||
return nullConstraint;
|
||||
|
||||
#undef REPORT
|
||||
}
|
||||
|
||||
|
||||
void DRC_ENGINE::Report( std::shared_ptr<DRC_ITEM> aItem, MARKER_PCB *aMarker )
|
||||
void DRC_ENGINE::Report( const std::shared_ptr<DRC_ITEM>& aItem, MARKER_PCB *aMarker )
|
||||
{
|
||||
m_drcReport->AddItem( aItem, aMarker );
|
||||
|
||||
|
@ -584,7 +582,7 @@ void DRC_ENGINE::Report( std::shared_ptr<DRC_ITEM> aItem, MARKER_PCB *aMarker )
|
|||
aItem->GetErrorMessage(),
|
||||
aItem->GetErrorCode() );
|
||||
|
||||
auto rule = aItem->GetViolatingRule();
|
||||
DRC_RULE* rule = aItem->GetViolatingRule();
|
||||
|
||||
if( rule )
|
||||
msg += wxString::Format( ", violating rule: '%s'", rule->m_Name );
|
||||
|
@ -655,8 +653,10 @@ DRC_CONSTRAINT DRC_ENGINE::GetWorstGlobalConstraint( DRC_CONSTRAINT_TYPE_T ruleI
|
|||
std::vector<DRC_CONSTRAINT> DRC_ENGINE::QueryConstraintsById( DRC_CONSTRAINT_TYPE_T constraintID )
|
||||
{
|
||||
std::vector<DRC_CONSTRAINT> rv;
|
||||
for ( auto c : m_constraintMap[constraintID]->sortedConstraints )
|
||||
|
||||
for ( CONSTRAINT_WITH_CONDITIONS* c : m_constraintMap[constraintID]->sortedConstraints )
|
||||
rv.push_back(c->constraint);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -676,7 +676,7 @@ bool DRC_ENGINE::QueryWorstConstraint( DRC_CONSTRAINT_TYPE_T aConstraintId,
|
|||
{
|
||||
int worst = 0;
|
||||
|
||||
for( const auto constraint : QueryConstraintsById( aConstraintId ) )
|
||||
for( const DRC_CONSTRAINT& constraint : QueryConstraintsById( aConstraintId ) )
|
||||
{
|
||||
if( constraint.GetValue().HasMin() )
|
||||
{
|
||||
|
|
|
@ -173,7 +173,7 @@ public:
|
|||
|
||||
bool CompileRules();
|
||||
|
||||
void Report( std::shared_ptr<DRC_ITEM> aItem, MARKER_PCB *Marker );
|
||||
void Report( const std::shared_ptr<DRC_ITEM>& aItem, MARKER_PCB *Marker );
|
||||
void ReportProgress( double aProgress );
|
||||
void ReportStage ( const wxString& aStageName, int index, int total );
|
||||
void ReportAux( const wxString& aStr );
|
||||
|
|
|
@ -23,17 +23,13 @@
|
|||
|
||||
|
||||
#include <fctsys.h>
|
||||
#include <class_board.h>
|
||||
#include <class_board_item.h>
|
||||
#include <reporter.h>
|
||||
#include <drc/drc_rule.h>
|
||||
#include <drc/drc_rule_condition.h>
|
||||
#include <drc/drc_engine.h>
|
||||
#include <pcb_expr_evaluator.h>
|
||||
|
||||
|
||||
const DRC_CONSTRAINT* GetConstraint( const BOARD_ITEM* aItem, const BOARD_ITEM* bItem,
|
||||
int aConstraint, PCB_LAYER_ID aLayer, wxString* aRuleName,
|
||||
REPORTER* aReporter )
|
||||
int aConstraint, PCB_LAYER_ID aLayer, wxString* aRuleName )
|
||||
{
|
||||
BOARD* board = aItem->GetBoard();
|
||||
|
||||
|
@ -42,23 +38,8 @@ const DRC_CONSTRAINT* GetConstraint( const BOARD_ITEM* aItem, const BOARD_ITEM*
|
|||
|
||||
for( DRC_RULE* rule : board->GetDesignSettings().m_DRCRules )
|
||||
{
|
||||
if( aReporter )
|
||||
{
|
||||
aReporter->Report( wxString::Format( _( "Checking rule \"%s\"." ),
|
||||
rule->m_Name ) );
|
||||
}
|
||||
|
||||
if( !rule->m_LayerCondition.test( aLayer ) )
|
||||
{
|
||||
if( aReporter )
|
||||
{
|
||||
aReporter->Report( wxString::Format( _( "Rule layer \"%s\" not matched." ),
|
||||
rule->m_LayerSource ) );
|
||||
aReporter->Report( "Rule not applied." );
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
const DRC_CONSTRAINT* constraint = nullptr;
|
||||
|
||||
|
@ -71,32 +52,10 @@ const DRC_CONSTRAINT* GetConstraint( const BOARD_ITEM* aItem, const BOARD_ITEM*
|
|||
}
|
||||
}
|
||||
|
||||
if( aReporter && !constraint )
|
||||
if( constraint )
|
||||
{
|
||||
aReporter->Report( _( "Rule contains no applicable constraints." ) );
|
||||
aReporter->Report( _( "Rule not applied." ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !rule->m_Condition )
|
||||
{
|
||||
if( aReporter )
|
||||
aReporter->Report( _( "No condition found; rule not applied." ) );
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if( aReporter )
|
||||
{
|
||||
aReporter->Report( wxString::Format( _( "Checking rule condition \"%s\"." ),
|
||||
rule->m_Condition->GetExpression() ) );
|
||||
}
|
||||
|
||||
if( rule->m_Condition->EvaluateFor( aItem, bItem, aLayer ) )
|
||||
{
|
||||
if( aReporter )
|
||||
aReporter->Report( "Rule applied." );
|
||||
|
||||
if( aRuleName )
|
||||
*aRuleName = rule->m_Name;
|
||||
|
||||
|
@ -105,42 +64,23 @@ const DRC_CONSTRAINT* GetConstraint( const BOARD_ITEM* aItem, const BOARD_ITEM*
|
|||
|
||||
if( bItem && rule->m_Condition->EvaluateFor( bItem, aItem, aLayer ) )
|
||||
{
|
||||
if( aReporter )
|
||||
aReporter->Report( "Rule applied." );
|
||||
|
||||
if( aRuleName )
|
||||
*aRuleName = rule->m_Name;
|
||||
|
||||
return constraint;
|
||||
}
|
||||
|
||||
if( aReporter )
|
||||
aReporter->Report( "Condition not satisfied; rule not applied." );
|
||||
}
|
||||
|
||||
if( aReporter )
|
||||
aReporter->Report( "" );
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
wxString DRC_CONSTRAINT::GetName() const
|
||||
{
|
||||
if( m_parentRule )
|
||||
return wxString::Format( _( "rule %s" ), m_parentRule->m_Name );
|
||||
else
|
||||
return m_name;
|
||||
}
|
||||
|
||||
|
||||
DRC_RULE::DRC_RULE() :
|
||||
m_Unary( false ),
|
||||
m_LayerCondition( LSET::AllLayersMask() ),
|
||||
m_Condition( nullptr ),
|
||||
m_Priority( 0 ),
|
||||
m_Severity( SEVERITY::RPT_SEVERITY_ERROR )
|
||||
m_Priority( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -158,77 +98,3 @@ void DRC_RULE::AddConstraint( DRC_CONSTRAINT& aConstraint )
|
|||
}
|
||||
|
||||
|
||||
DRC_RULE_CONDITION::DRC_RULE_CONDITION( const wxString& aExpression ) :
|
||||
m_expression( aExpression ),
|
||||
m_ucode ( nullptr )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DRC_RULE_CONDITION::~DRC_RULE_CONDITION()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool DRC_RULE_CONDITION::EvaluateFor( const BOARD_ITEM* aItemA, const BOARD_ITEM* aItemB,
|
||||
PCB_LAYER_ID aLayer, REPORTER* aReporter )
|
||||
{
|
||||
#define REPORT( s ) { if( aReporter ) { aReporter->Report( s ); } }
|
||||
|
||||
if( GetExpression().IsEmpty() )
|
||||
{
|
||||
REPORT( _( "Unconditional constraint." ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
REPORT( _( "Checking rule condition \"" + GetExpression() + "\"." ) );
|
||||
|
||||
if( !m_ucode )
|
||||
{
|
||||
REPORT( _( "ERROR in expression." ) );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
BOARD_ITEM* a = const_cast<BOARD_ITEM*>( aItemA );
|
||||
BOARD_ITEM* b = aItemB ? const_cast<BOARD_ITEM*>( aItemB ) : DELETED_BOARD_ITEM::GetInstance();
|
||||
|
||||
PCB_EXPR_CONTEXT ctx( aLayer );
|
||||
ctx.SetItems( a, b );
|
||||
ctx.SetErrorCallback( [&]( const wxString& aMessage, int aOffset )
|
||||
{
|
||||
REPORT( _( "ERROR: " ) + aMessage );
|
||||
} );
|
||||
|
||||
return m_ucode->Run( &ctx )->AsDouble() != 0.0;
|
||||
}
|
||||
|
||||
|
||||
bool DRC_RULE_CONDITION::Compile( REPORTER* aReporter, int aSourceLine, int aSourceOffset )
|
||||
{
|
||||
auto errorHandler = [&]( const wxString& aMessage, int aOffset )
|
||||
{
|
||||
wxString rest;
|
||||
wxString first = aMessage.BeforeFirst( '|', &rest );
|
||||
wxString msg = wxString::Format( _( "ERROR: <a href='%d:%d'>%s</a>%s" ),
|
||||
aSourceLine,
|
||||
aSourceOffset + aOffset,
|
||||
first,
|
||||
rest );
|
||||
|
||||
aReporter->Report( msg, RPT_SEVERITY_ERROR );
|
||||
};
|
||||
|
||||
PCB_EXPR_COMPILER compiler;
|
||||
compiler.SetErrorCallback( errorHandler );
|
||||
|
||||
m_ucode = std::make_unique<PCB_EXPR_UCODE>();
|
||||
|
||||
PCB_EXPR_CONTEXT preflightContext( F_Cu );
|
||||
|
||||
bool ok = compiler.Compile( GetExpression().ToUTF8().data(), m_ucode.get(), &preflightContext );
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -30,12 +30,11 @@
|
|||
#include <libeval_compiler/libeval_compiler.h>
|
||||
|
||||
class BOARD_ITEM;
|
||||
|
||||
class PCB_EXPR_UCODE;
|
||||
|
||||
class DRC_RULE;
|
||||
class DRC_CONSTRAINT;
|
||||
class DRC_RULE_CONDITION;
|
||||
|
||||
|
||||
enum DRC_CONSTRAINT_TYPE_T
|
||||
{
|
||||
DRC_CONSTRAINT_TYPE_UNKNOWN = -1,
|
||||
|
@ -49,11 +48,10 @@ enum DRC_CONSTRAINT_TYPE_T
|
|||
DRC_CONSTRAINT_TYPE_TRACK_WIDTH,
|
||||
DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH,
|
||||
DRC_CONSTRAINT_TYPE_DISALLOW,
|
||||
DRC_CONSTRAINT_TYPE_VIA_DIAMETER,
|
||||
|
||||
DRC_CONSTRAINT_TYPE_COUNT
|
||||
DRC_CONSTRAINT_TYPE_VIA_DIAMETER
|
||||
};
|
||||
|
||||
|
||||
enum DRC_DISALLOW_T
|
||||
{
|
||||
DRC_DISALLOW_VIAS = (1 << 0),
|
||||
|
@ -95,57 +93,6 @@ private:
|
|||
};
|
||||
|
||||
|
||||
class DRC_CONSTRAINT
|
||||
{
|
||||
public:
|
||||
DRC_CONSTRAINT( DRC_CONSTRAINT_TYPE_T aType = DRC_CONSTRAINT_TYPE_UNKNOWN,
|
||||
const wxString& aName = wxEmptyString ) :
|
||||
m_Type( aType ),
|
||||
m_DisallowFlags( 0 ),
|
||||
m_name( aName ),
|
||||
m_parentRule( nullptr )
|
||||
{
|
||||
}
|
||||
|
||||
const MINOPTMAX<int>& GetValue() const { return m_Value; }
|
||||
MINOPTMAX<int>& Value() { return m_Value; }
|
||||
|
||||
void SetParentRule( DRC_RULE *aParentRule ) { m_parentRule = aParentRule; }
|
||||
DRC_RULE* GetParentRule() const { return m_parentRule; }
|
||||
|
||||
wxString GetName() const;
|
||||
|
||||
public:
|
||||
DRC_CONSTRAINT_TYPE_T m_Type;
|
||||
MINOPTMAX<int> m_Value;
|
||||
int m_DisallowFlags;
|
||||
|
||||
private:
|
||||
wxString m_name; // For just-in-time constraints
|
||||
DRC_RULE* m_parentRule; // For constraints found in rules
|
||||
};
|
||||
|
||||
|
||||
class DRC_RULE_CONDITION
|
||||
{
|
||||
public:
|
||||
DRC_RULE_CONDITION( const wxString& aExpression = "" );
|
||||
~DRC_RULE_CONDITION();
|
||||
|
||||
bool EvaluateFor( const BOARD_ITEM* aItemA, const BOARD_ITEM* aItemB, PCB_LAYER_ID aLayer,
|
||||
REPORTER* aReporter = nullptr );
|
||||
|
||||
bool Compile( REPORTER* aReporter, int aSourceLine = 0, int aSourceOffset = 0 );
|
||||
|
||||
void SetExpression( const wxString& aExpression ) { m_expression = aExpression; }
|
||||
wxString GetExpression() const { return m_expression; }
|
||||
|
||||
private:
|
||||
wxString m_expression;
|
||||
std::unique_ptr<PCB_EXPR_UCODE> m_ucode;
|
||||
};
|
||||
|
||||
|
||||
class DRC_RULE
|
||||
{
|
||||
public:
|
||||
|
@ -167,7 +114,7 @@ public:
|
|||
return false;
|
||||
};
|
||||
|
||||
virtual void FillSpecificItemSet( std::set<BOARD_ITEM*> specificItems )
|
||||
virtual void FillSpecificItemSet( const std::set<BOARD_ITEM*>& specificItems )
|
||||
{
|
||||
};
|
||||
|
||||
|
@ -185,14 +132,49 @@ public:
|
|||
std::vector<DRC_CONSTRAINT> m_Constraints;
|
||||
|
||||
int m_Priority; // 0 indicates automatic priority generation fixme: use enum
|
||||
SEVERITY m_Severity;
|
||||
};
|
||||
|
||||
|
||||
class DRC_CONSTRAINT
|
||||
{
|
||||
public:
|
||||
DRC_CONSTRAINT( DRC_CONSTRAINT_TYPE_T aType = DRC_CONSTRAINT_TYPE_UNKNOWN,
|
||||
const wxString& aName = wxEmptyString ) :
|
||||
m_Type( aType ),
|
||||
m_DisallowFlags( 0 ),
|
||||
m_name( aName ),
|
||||
m_parentRule( nullptr )
|
||||
{
|
||||
}
|
||||
|
||||
const MINOPTMAX<int>& GetValue() const { return m_Value; }
|
||||
MINOPTMAX<int>& Value() { return m_Value; }
|
||||
|
||||
void SetParentRule( DRC_RULE *aParentRule ) { m_parentRule = aParentRule; }
|
||||
DRC_RULE* GetParentRule() const { return m_parentRule; }
|
||||
|
||||
wxString GetName() const
|
||||
{
|
||||
if( m_parentRule )
|
||||
return wxString::Format( _( "rule %s" ), m_parentRule->m_Name );
|
||||
else
|
||||
return m_name;
|
||||
}
|
||||
|
||||
public:
|
||||
DRC_CONSTRAINT_TYPE_T m_Type;
|
||||
MINOPTMAX<int> m_Value;
|
||||
int m_DisallowFlags;
|
||||
|
||||
private:
|
||||
wxString m_name; // For just-in-time constraints
|
||||
DRC_RULE* m_parentRule; // For constraints found in rules
|
||||
};
|
||||
|
||||
|
||||
const DRC_CONSTRAINT* GetConstraint( const BOARD_ITEM* aItem, const BOARD_ITEM* bItem,
|
||||
int aConstraint, PCB_LAYER_ID aLayer,
|
||||
wxString* aRuleName = nullptr,
|
||||
REPORTER* aReporter = nullptr );
|
||||
wxString* aRuleName = nullptr );
|
||||
|
||||
|
||||
#endif // DRC_RULE_H
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2020 KiCad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
#include <fctsys.h>
|
||||
#include <class_board_item.h>
|
||||
#include <reporter.h>
|
||||
#include <drc/drc_rule_condition.h>
|
||||
#include <pcb_expr_evaluator.h>
|
||||
|
||||
|
||||
DRC_RULE_CONDITION::DRC_RULE_CONDITION( const wxString& aExpression ) :
|
||||
m_expression( aExpression ),
|
||||
m_ucode ( nullptr )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DRC_RULE_CONDITION::~DRC_RULE_CONDITION()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool DRC_RULE_CONDITION::EvaluateFor( const BOARD_ITEM* aItemA, const BOARD_ITEM* aItemB,
|
||||
PCB_LAYER_ID aLayer, REPORTER* aReporter )
|
||||
{
|
||||
#define REPORT( s ) { if( aReporter ) { aReporter->Report( s ); } }
|
||||
|
||||
if( GetExpression().IsEmpty() )
|
||||
{
|
||||
REPORT( _( "Unconditional constraint." ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
REPORT( _( "Checking rule condition \"" + GetExpression() + "\"." ) );
|
||||
|
||||
if( !m_ucode )
|
||||
{
|
||||
REPORT( _( "ERROR in expression." ) );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
BOARD_ITEM* a = const_cast<BOARD_ITEM*>( aItemA );
|
||||
BOARD_ITEM* b = aItemB ? const_cast<BOARD_ITEM*>( aItemB ) : DELETED_BOARD_ITEM::GetInstance();
|
||||
|
||||
PCB_EXPR_CONTEXT ctx( aLayer );
|
||||
ctx.SetItems( a, b );
|
||||
ctx.SetErrorCallback( [&]( const wxString& aMessage, int aOffset )
|
||||
{
|
||||
REPORT( _( "ERROR: " ) + aMessage );
|
||||
} );
|
||||
|
||||
return m_ucode->Run( &ctx )->AsDouble() != 0.0;
|
||||
|
||||
#undef REPORT
|
||||
}
|
||||
|
||||
|
||||
bool DRC_RULE_CONDITION::Compile( REPORTER* aReporter, int aSourceLine, int aSourceOffset )
|
||||
{
|
||||
auto errorHandler = [&]( const wxString& aMessage, int aOffset )
|
||||
{
|
||||
wxString rest;
|
||||
wxString first = aMessage.BeforeFirst( '|', &rest );
|
||||
wxString msg = wxString::Format( _( "ERROR: <a href='%d:%d'>%s</a>%s" ),
|
||||
aSourceLine,
|
||||
aSourceOffset + aOffset,
|
||||
first,
|
||||
rest );
|
||||
|
||||
aReporter->Report( msg, RPT_SEVERITY_ERROR );
|
||||
};
|
||||
|
||||
PCB_EXPR_COMPILER compiler;
|
||||
compiler.SetErrorCallback( errorHandler );
|
||||
|
||||
m_ucode = std::make_unique<PCB_EXPR_UCODE>();
|
||||
|
||||
PCB_EXPR_CONTEXT preflightContext( F_Cu );
|
||||
|
||||
bool ok = compiler.Compile( GetExpression().ToUTF8().data(), m_ucode.get(), &preflightContext );
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2020 KiCad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef DRC_RULE_CONDITION_H
|
||||
#define DRC_RULE_CONDITION_H
|
||||
|
||||
#include <common.h>
|
||||
#include <core/typeinfo.h>
|
||||
#include <layers_id_colors_and_visibility.h>
|
||||
|
||||
class BOARD_ITEM;
|
||||
class PCB_EXPR_UCODE;
|
||||
class REPORTER;
|
||||
|
||||
|
||||
class DRC_RULE_CONDITION
|
||||
{
|
||||
public:
|
||||
DRC_RULE_CONDITION( const wxString& aExpression = "" );
|
||||
~DRC_RULE_CONDITION();
|
||||
|
||||
bool EvaluateFor( const BOARD_ITEM* aItemA, const BOARD_ITEM* aItemB, PCB_LAYER_ID aLayer,
|
||||
REPORTER* aReporter = nullptr );
|
||||
|
||||
bool Compile( REPORTER* aReporter, int aSourceLine = 0, int aSourceOffset = 0 );
|
||||
|
||||
void SetExpression( const wxString& aExpression ) { m_expression = aExpression; }
|
||||
wxString GetExpression() const { return m_expression; }
|
||||
|
||||
private:
|
||||
wxString m_expression;
|
||||
std::unique_ptr<PCB_EXPR_UCODE> m_ucode;
|
||||
};
|
||||
|
||||
|
||||
#endif // DRC_RULE_CONDITION_H
|
|
@ -24,9 +24,8 @@
|
|||
|
||||
#include <fctsys.h>
|
||||
#include <class_board.h>
|
||||
#include <class_board_item.h>
|
||||
|
||||
#include <drc/drc_rule_parser.h>
|
||||
#include <drc/drc_rule_condition.h>
|
||||
#include <drc_rules_lexer.h>
|
||||
#include <pcb_expr_evaluator.h>
|
||||
#include <reporter.h>
|
||||
|
|
|
@ -36,6 +36,7 @@ endif()
|
|||
add_executable( drc_proto
|
||||
drc_proto_test.cpp
|
||||
../../pcbnew/drc/drc_rule.cpp
|
||||
../../pcbnew/drc/drc_rule_condition.cpp
|
||||
../../pcbnew/drc/drc_rule_parser.cpp
|
||||
../../pcbnew/drc/drc_test_provider.cpp
|
||||
../../pcbnew/drc/drc_test_provider_clearance_base.cpp
|
||||
|
|
Loading…
Reference in New Issue