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/convert_drawsegment_list_to_polygon.cpp
|
||||||
${CMAKE_SOURCE_DIR}/pcbnew/drc/drc_item.cpp
|
${CMAKE_SOURCE_DIR}/pcbnew/drc/drc_item.cpp
|
||||||
${CMAKE_SOURCE_DIR}/pcbnew/drc/drc_rule.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/eagle_plugin.cpp
|
||||||
${CMAKE_SOURCE_DIR}/pcbnew/footprint_editor_settings.cpp
|
${CMAKE_SOURCE_DIR}/pcbnew/footprint_editor_settings.cpp
|
||||||
${CMAKE_SOURCE_DIR}/pcbnew/gpcb_plugin.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
|
// LEVEL 2: Rules
|
||||||
//
|
//
|
||||||
if( GetRuleClearance( aItem, aLayer, &clearance, aSource, aReporter ) )
|
if( GetRuleClearance( aItem, aLayer, &clearance, aSource ) )
|
||||||
return clearance;
|
return clearance;
|
||||||
|
|
||||||
// LEVEL 3: Accumulated local settings, netclass settings, & board design settings
|
// 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,
|
bool BOARD_CONNECTED_ITEM::GetRuleClearance( BOARD_ITEM* aItem, PCB_LAYER_ID aLayer,
|
||||||
int* aClearance, wxString* aSource,
|
int* aClearance, wxString* aSource ) const
|
||||||
REPORTER* aReporter ) const
|
|
||||||
{
|
{
|
||||||
const DRC_CONSTRAINT* constraint = GetConstraint( this, aItem, DRC_CONSTRAINT_TYPE_CLEARANCE,
|
const DRC_CONSTRAINT* constraint = GetConstraint( this, aItem, DRC_CONSTRAINT_TYPE_CLEARANCE,
|
||||||
aLayer, aSource, aReporter );
|
aLayer, aSource );
|
||||||
|
|
||||||
if( constraint )
|
if( constraint )
|
||||||
{
|
{
|
||||||
|
@ -166,12 +165,6 @@ bool BOARD_CONNECTED_ITEM::GetRuleClearance( BOARD_ITEM* aItem, PCB_LAYER_ID aLa
|
||||||
|
|
||||||
*aClearance = constraint->m_Value.Min();
|
*aClearance = constraint->m_Value.Min();
|
||||||
|
|
||||||
if( aReporter )
|
|
||||||
{
|
|
||||||
wxString clearance = StringFromValue( aReporter->GetUnits(), *aClearance, true );
|
|
||||||
aReporter->Report( wxString::Format( _( "Clearance: %s." ), clearance ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -179,7 +179,7 @@ public:
|
||||||
* @return true if a rule was fired
|
* @return true if a rule was fired
|
||||||
*/
|
*/
|
||||||
virtual bool GetRuleClearance( BOARD_ITEM* aItem, PCB_LAYER_ID aLayer, int* aClearance,
|
virtual bool GetRuleClearance( BOARD_ITEM* aItem, PCB_LAYER_ID aLayer, int* aClearance,
|
||||||
wxString* aSource, REPORTER* aReporter = nullptr ) const;
|
wxString* aSource ) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetLocalClearanceOverrides
|
* Function GetLocalClearanceOverrides
|
||||||
|
|
|
@ -23,19 +23,15 @@
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// fixme - way too much includes
|
|
||||||
#include <fctsys.h>
|
#include <fctsys.h>
|
||||||
#include <pcbnew.h>
|
|
||||||
|
|
||||||
#include <reporter.h>
|
#include <reporter.h>
|
||||||
#include <widgets/progress_reporter.h>
|
#include <widgets/progress_reporter.h>
|
||||||
|
|
||||||
#include <drc/drc_engine.h>
|
#include <drc/drc_engine.h>
|
||||||
#include <drc/drc_rule_parser.h>
|
#include <drc/drc_rule_parser.h>
|
||||||
#include <drc/drc_rule.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/drc_test_provider.h>
|
||||||
#include "drc.h"
|
#include <drc/drc.h>
|
||||||
|
|
||||||
void drcPrintDebugMessage( int level, wxString msg, const char *function, int line )
|
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()
|
bool DRC_ENGINE::CompileRules()
|
||||||
{
|
{
|
||||||
ReportAux( wxString::Format( "Compiling Rules (%d rules, %d conditions): ",
|
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 )
|
void DRC_ENGINE::InitEngine( wxFileName aRulePath )
|
||||||
{
|
{
|
||||||
m_testProviders = DRC_TEST_PROVIDER_REGISTRY::Instance().GetTestProviders();
|
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;
|
nullConstraint.m_DisallowFlags = 0;
|
||||||
|
|
||||||
return nullConstraint;
|
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 );
|
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->GetErrorMessage(),
|
||||||
aItem->GetErrorCode() );
|
aItem->GetErrorCode() );
|
||||||
|
|
||||||
auto rule = aItem->GetViolatingRule();
|
DRC_RULE* rule = aItem->GetViolatingRule();
|
||||||
|
|
||||||
if( rule )
|
if( rule )
|
||||||
msg += wxString::Format( ", violating rule: '%s'", rule->m_Name );
|
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> DRC_ENGINE::QueryConstraintsById( DRC_CONSTRAINT_TYPE_T constraintID )
|
||||||
{
|
{
|
||||||
std::vector<DRC_CONSTRAINT> rv;
|
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);
|
rv.push_back(c->constraint);
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -676,7 +676,7 @@ bool DRC_ENGINE::QueryWorstConstraint( DRC_CONSTRAINT_TYPE_T aConstraintId,
|
||||||
{
|
{
|
||||||
int worst = 0;
|
int worst = 0;
|
||||||
|
|
||||||
for( const auto constraint : QueryConstraintsById( aConstraintId ) )
|
for( const DRC_CONSTRAINT& constraint : QueryConstraintsById( aConstraintId ) )
|
||||||
{
|
{
|
||||||
if( constraint.GetValue().HasMin() )
|
if( constraint.GetValue().HasMin() )
|
||||||
{
|
{
|
||||||
|
|
|
@ -173,7 +173,7 @@ public:
|
||||||
|
|
||||||
bool CompileRules();
|
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 ReportProgress( double aProgress );
|
||||||
void ReportStage ( const wxString& aStageName, int index, int total );
|
void ReportStage ( const wxString& aStageName, int index, int total );
|
||||||
void ReportAux( const wxString& aStr );
|
void ReportAux( const wxString& aStr );
|
||||||
|
|
|
@ -23,17 +23,13 @@
|
||||||
|
|
||||||
|
|
||||||
#include <fctsys.h>
|
#include <fctsys.h>
|
||||||
#include <class_board.h>
|
|
||||||
#include <class_board_item.h>
|
|
||||||
#include <reporter.h>
|
|
||||||
#include <drc/drc_rule.h>
|
#include <drc/drc_rule.h>
|
||||||
|
#include <drc/drc_rule_condition.h>
|
||||||
#include <drc/drc_engine.h>
|
#include <drc/drc_engine.h>
|
||||||
#include <pcb_expr_evaluator.h>
|
|
||||||
|
|
||||||
|
|
||||||
const DRC_CONSTRAINT* GetConstraint( const BOARD_ITEM* aItem, const BOARD_ITEM* bItem,
|
const DRC_CONSTRAINT* GetConstraint( const BOARD_ITEM* aItem, const BOARD_ITEM* bItem,
|
||||||
int aConstraint, PCB_LAYER_ID aLayer, wxString* aRuleName,
|
int aConstraint, PCB_LAYER_ID aLayer, wxString* aRuleName )
|
||||||
REPORTER* aReporter )
|
|
||||||
{
|
{
|
||||||
BOARD* board = aItem->GetBoard();
|
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 )
|
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( !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;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
const DRC_CONSTRAINT* constraint = nullptr;
|
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( rule->m_Condition->EvaluateFor( aItem, bItem, aLayer ) )
|
||||||
{
|
{
|
||||||
if( aReporter )
|
|
||||||
aReporter->Report( "Rule applied." );
|
|
||||||
|
|
||||||
if( aRuleName )
|
if( aRuleName )
|
||||||
*aRuleName = rule->m_Name;
|
*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( bItem && rule->m_Condition->EvaluateFor( bItem, aItem, aLayer ) )
|
||||||
{
|
{
|
||||||
if( aReporter )
|
|
||||||
aReporter->Report( "Rule applied." );
|
|
||||||
|
|
||||||
if( aRuleName )
|
if( aRuleName )
|
||||||
*aRuleName = rule->m_Name;
|
*aRuleName = rule->m_Name;
|
||||||
|
|
||||||
return constraint;
|
return constraint;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( aReporter )
|
|
||||||
aReporter->Report( "Condition not satisfied; rule not applied." );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( aReporter )
|
|
||||||
aReporter->Report( "" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
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() :
|
DRC_RULE::DRC_RULE() :
|
||||||
m_Unary( false ),
|
m_Unary( false ),
|
||||||
m_LayerCondition( LSET::AllLayersMask() ),
|
m_LayerCondition( LSET::AllLayersMask() ),
|
||||||
m_Condition( nullptr ),
|
m_Condition( nullptr ),
|
||||||
m_Priority( 0 ),
|
m_Priority( 0 )
|
||||||
m_Severity( SEVERITY::RPT_SEVERITY_ERROR )
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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>
|
#include <libeval_compiler/libeval_compiler.h>
|
||||||
|
|
||||||
class BOARD_ITEM;
|
class BOARD_ITEM;
|
||||||
|
|
||||||
class PCB_EXPR_UCODE;
|
class PCB_EXPR_UCODE;
|
||||||
|
class DRC_CONSTRAINT;
|
||||||
class DRC_RULE;
|
|
||||||
class DRC_RULE_CONDITION;
|
class DRC_RULE_CONDITION;
|
||||||
|
|
||||||
|
|
||||||
enum DRC_CONSTRAINT_TYPE_T
|
enum DRC_CONSTRAINT_TYPE_T
|
||||||
{
|
{
|
||||||
DRC_CONSTRAINT_TYPE_UNKNOWN = -1,
|
DRC_CONSTRAINT_TYPE_UNKNOWN = -1,
|
||||||
|
@ -49,11 +48,10 @@ enum DRC_CONSTRAINT_TYPE_T
|
||||||
DRC_CONSTRAINT_TYPE_TRACK_WIDTH,
|
DRC_CONSTRAINT_TYPE_TRACK_WIDTH,
|
||||||
DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH,
|
DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH,
|
||||||
DRC_CONSTRAINT_TYPE_DISALLOW,
|
DRC_CONSTRAINT_TYPE_DISALLOW,
|
||||||
DRC_CONSTRAINT_TYPE_VIA_DIAMETER,
|
DRC_CONSTRAINT_TYPE_VIA_DIAMETER
|
||||||
|
|
||||||
DRC_CONSTRAINT_TYPE_COUNT
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
enum DRC_DISALLOW_T
|
enum DRC_DISALLOW_T
|
||||||
{
|
{
|
||||||
DRC_DISALLOW_VIAS = (1 << 0),
|
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
|
class DRC_RULE
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -167,7 +114,7 @@ public:
|
||||||
return false;
|
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;
|
std::vector<DRC_CONSTRAINT> m_Constraints;
|
||||||
|
|
||||||
int m_Priority; // 0 indicates automatic priority generation fixme: use enum
|
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,
|
const DRC_CONSTRAINT* GetConstraint( const BOARD_ITEM* aItem, const BOARD_ITEM* bItem,
|
||||||
int aConstraint, PCB_LAYER_ID aLayer,
|
int aConstraint, PCB_LAYER_ID aLayer,
|
||||||
wxString* aRuleName = nullptr,
|
wxString* aRuleName = nullptr );
|
||||||
REPORTER* aReporter = nullptr );
|
|
||||||
|
|
||||||
|
|
||||||
#endif // DRC_RULE_H
|
#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 <fctsys.h>
|
||||||
#include <class_board.h>
|
#include <class_board.h>
|
||||||
#include <class_board_item.h>
|
|
||||||
|
|
||||||
#include <drc/drc_rule_parser.h>
|
#include <drc/drc_rule_parser.h>
|
||||||
|
#include <drc/drc_rule_condition.h>
|
||||||
#include <drc_rules_lexer.h>
|
#include <drc_rules_lexer.h>
|
||||||
#include <pcb_expr_evaluator.h>
|
#include <pcb_expr_evaluator.h>
|
||||||
#include <reporter.h>
|
#include <reporter.h>
|
||||||
|
|
|
@ -36,6 +36,7 @@ endif()
|
||||||
add_executable( drc_proto
|
add_executable( drc_proto
|
||||||
drc_proto_test.cpp
|
drc_proto_test.cpp
|
||||||
../../pcbnew/drc/drc_rule.cpp
|
../../pcbnew/drc/drc_rule.cpp
|
||||||
|
../../pcbnew/drc/drc_rule_condition.cpp
|
||||||
../../pcbnew/drc/drc_rule_parser.cpp
|
../../pcbnew/drc/drc_rule_parser.cpp
|
||||||
../../pcbnew/drc/drc_test_provider.cpp
|
../../pcbnew/drc/drc_test_provider.cpp
|
||||||
../../pcbnew/drc/drc_test_provider_clearance_base.cpp
|
../../pcbnew/drc/drc_test_provider_clearance_base.cpp
|
||||||
|
|
Loading…
Reference in New Issue