drc_proto: update file format, get the thing to compile again

This commit is contained in:
Tomasz Wlostowski 2020-08-12 00:17:43 +02:00
parent 8b716b2b5c
commit e0ffdc8fe7
17 changed files with 472 additions and 543 deletions

View File

@ -413,7 +413,7 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS
dummypad.SetLayerSet( all_cu | dummypad.GetLayerSet() ); dummypad.SetLayerSet( all_cu | dummypad.GetLayerSet() );
int minClearance; int minClearance;
DRC_RULE* rule = GetRule( aRefSeg, &dummypad, DRC_RULE_ID_CLEARANCE ); DRC_RULE* rule = GetRule( aRefSeg, &dummypad, DRC_CONSTRAINT_TYPE_CLEARANCE );
if( rule ) if( rule )
{ {

View File

@ -93,7 +93,7 @@ bool DRC_DRILLED_HOLE_TESTER::checkPad( D_PAD* aPad )
{ {
int minHole = bds.m_MinThroughDrill; int minHole = bds.m_MinThroughDrill;
wxString minHoleSource = _( "board minimum" ); wxString minHoleSource = _( "board minimum" );
DRC_RULE* rule = GetRule( aPad, nullptr, DRC_RULE_ID_HOLE_SIZE ); DRC_RULE* rule = GetRule( aPad, nullptr, DRC_CONSTRAINT_TYPE_HOLE_SIZE );
if( rule ) if( rule )
{ {
@ -136,7 +136,7 @@ bool DRC_DRILLED_HOLE_TESTER::checkVia( VIA* via )
{ {
int minHole = bds.m_MinThroughDrill; int minHole = bds.m_MinThroughDrill;
wxString minHoleSource = _( "board minimum" ); wxString minHoleSource = _( "board minimum" );
DRC_RULE* rule = GetRule( via, nullptr, DRC_RULE_ID_HOLE_SIZE ); DRC_RULE* rule = GetRule( via, nullptr, DRC_CONSTRAINT_TYPE_HOLE_SIZE );
if( rule ) if( rule )
{ {
@ -179,7 +179,7 @@ bool DRC_DRILLED_HOLE_TESTER::checkMicroVia( VIA* via )
{ {
int minHole = bds.m_MicroViasMinDrill; int minHole = bds.m_MicroViasMinDrill;
wxString minHoleSource = _( "board minimum" ); wxString minHoleSource = _( "board minimum" );
DRC_RULE* rule = GetRule( via, nullptr, DRC_RULE_ID_HOLE_SIZE ); DRC_RULE* rule = GetRule( via, nullptr, DRC_CONSTRAINT_TYPE_HOLE_SIZE );
if( rule ) if( rule )
{ {

View File

@ -85,7 +85,7 @@ bool test::DRC_ENGINE::LoadRules( wxFileName aPath )
try try
{ {
DRC_RULES_PARSER parser( m_board, fp, aPath.GetFullPath() ); DRC_RULES_PARSER parser( m_board, fp, aPath.GetFullPath() );
parser.Parse( m_ruleConditions, m_rules, &NULL_REPORTER::GetInstance() ); parser.Parse( m_rules, m_reporter );
} }
catch( PARSE_ERROR& pe ) catch( PARSE_ERROR& pe )
{ {
@ -126,47 +126,42 @@ bool test::DRC_ENGINE::CompileRules()
{ {
ReportAux( wxString::Format( "- Provider: '%s': ", provider->GetName() ) ); ReportAux( wxString::Format( "- Provider: '%s': ", provider->GetName() ) );
for ( auto id : provider->GetMatchingRuleIds() ) for ( auto id : provider->GetMatchingConstraintIds() )
{ {
if( m_ruleMap.find(id) == m_ruleMap.end() ) if( m_ruleMap.find(id) == m_ruleMap.end() )
m_ruleMap[id] = new RULE_SET; m_ruleMap[id] = new RULE_SET;
m_ruleMap[ id ]->provider = provider; m_ruleMap[ id ]->provider = provider;
m_ruleMap[ id ]->defaultRule = nullptr;
for( auto rule : m_rules ) for( auto rule : m_rules )
{ {
drc_dbg(10, "Scan provider %s rule %s", (const char*) rule->GetTestProviderName().c_str(), (const char *)provider->GetName().c_str( ) ); drc_dbg(10, "Scan provider %s rule %s", provider->GetName() );
if( rule->GetTestProviderName() == provider->GetName() )
{
ReportAux( wxString::Format( " |- Rule: '%s' ", rule->m_Name.c_str() ) );
if( rule->IsEnabled() ) if( ! rule->IsEnabled() )
continue;
for( auto& constraint : rule->Constraints() )
{ {
if( constraint.GetType() != id )
continue;
ReportAux( wxString::Format( " |- Rule: '%s' ", rule->m_Name ) );
auto rcons = new RULE_WITH_CONDITIONS; auto rcons = new RULE_WITH_CONDITIONS;
if( rule->GetPriority() == 0 ) if( rule->IsConditional() )
{
drc_dbg(1,"DefaultRule for %d = %p\n", id, rule );
m_ruleMap[ id ]->defaultRule = rule;
continue;
}
for( auto condition : m_ruleConditions )
{
if( condition->m_TargetRuleName == rule->GetName() )
{ {
test::DRC_RULE_CONDITION* condition = rule->Condition();
rcons->conditions.push_back( condition ); rcons->conditions.push_back( condition );
bool compileOk = condition->Compile(); bool compileOk = condition->Compile( nullptr, 0, 0 ); // fixme
ReportAux( wxString::Format( " |- condition: '%s' compile: %s", condition->m_TargetRuleName, compileOk ? "OK" : "ERROR") ); ReportAux( wxString::Format( " |- condition: '%s' compile: %s", condition->GetExpression(), compileOk ? "OK" : "ERROR") );
}
rcons->rule = rule; rcons->rule = rule;
m_ruleMap[ id ]->sortedRules.push_back( rcons ); m_ruleMap[ id ]->sortedRules.push_back( rcons );
}
}
}
} }
} }
} }
@ -197,7 +192,7 @@ void test::DRC_ENGINE::RunTests( )
{ {
bool skipProvider = false; bool skipProvider = false;
for( auto ruleID : provider->GetMatchingRuleIds() ) for( auto ruleID : provider->GetMatchingConstraintIds() )
{ {
if( !HasCorrectRulesForId( ruleID ) ) if( !HasCorrectRulesForId( ruleID ) )
{ {
@ -210,44 +205,41 @@ void test::DRC_ENGINE::RunTests( )
if( skipProvider ) if( skipProvider )
continue; continue;
drc_dbg(0, "Running test provider: '%s'\n", (const char *) provider->GetName().c_str() ); drc_dbg(0, "Running test provider: '%s'\n", provider->GetName() );
ReportAux( wxString::Format( "Run DRC provider: '%s'", provider->GetName() ) ); ReportAux( wxString::Format( "Run DRC provider: '%s'", provider->GetName() ) );
provider->Run(); provider->Run();
} }
} }
test::DRC_RULE* test::DRC_ENGINE::EvalRulesForItems( test::DRC_RULE_ID_T ruleID, BOARD_ITEM* a, BOARD_ITEM* b ) const test::DRC_CONSTRAINT& test::DRC_ENGINE::EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T aConstraintId, BOARD_ITEM* a, BOARD_ITEM* b, PCB_LAYER_ID aLayer )
{ {
test::DRC_RULE* rv; test::DRC_RULE* rv;
auto ruleset = m_ruleMap[ ruleID ]; auto ruleset = m_ruleMap[ aConstraintId ];
for( auto rcond : ruleset->sortedRules ) for( auto rcond : ruleset->sortedRules )
{ {
for( auto condition : rcond->conditions ) for( auto condition : rcond->conditions )
{ {
drc_dbg( 8, " -> check condition '%s'\n", drc_dbg( 8, " -> check condition '%s'\n",
(const char*) condition->m_Expression.c_str() ); condition->GetExpression() );
bool result = condition->EvaluateFor( a, b, F_Cu ); // FIXME: need the actual layer bool result = condition->EvaluateFor( a, b, aLayer ); // FIXME: need the actual layer
if( result ) if( result )
{ {
drc_dbg( 8, " -> rule '%s' matches, triggered by condition '%s'\n", drc_dbg( 8, " -> rule '%s' matches, triggered by condition '%s'\n",
(const char*) rcond->rule->m_Name.c_str(), rcond->rule->GetName(),
(const char*) condition->m_Expression.c_str() ); condition->GetExpression() );
return rcond->rule; for( const DRC_CONSTRAINT& c : rcond->rule->Constraints() )
}
}
}
if( ruleset->defaultRule )
{ {
drc_dbg(8, " -> default rule '%s' matches\n", (const char*) ruleset->defaultRule->m_Name.c_str() ); if( c.GetType() == aConstraintId )
return ruleset->defaultRule; return c;
}
}
}
} }
assert(false); // should never hapen assert(false); // should never hapen
return nullptr;
} }
@ -299,7 +291,7 @@ void test::DRC_ENGINE::ReportStage ( const wxString& aStageName, int index, int
} }
#if 0 #if 0
test::DRC_CONSTRAINT test::DRC_ENGINE::GetWorstGlobalConstraint( test::DRC_RULE_ID_T ruleID ) test::DRC_CONSTRAINT test::DRC_ENGINE::GetWorstGlobalConstraint( test::DRC_CONSTRAINT_TYPE_T ruleID )
{ {
DRC_CONSTRAINT rv; DRC_CONSTRAINT rv;
@ -318,48 +310,45 @@ test::DRC_CONSTRAINT test::DRC_ENGINE::GetWorstGlobalConstraint( test::DRC_RULE_
} }
#endif #endif
std::vector<test::DRC_RULE*> test::DRC_ENGINE::QueryRulesById( test::DRC_RULE_ID_T ruleID ) std::vector<test::DRC_CONSTRAINT> test::DRC_ENGINE::QueryConstraintsById( test::DRC_CONSTRAINT_TYPE_T constraintID )
{ {
std::vector<test::DRC_RULE*> rv; std::vector<test::DRC_CONSTRAINT> rv;
auto dr = m_ruleMap[ruleID]->defaultRule; for( auto rule : m_ruleMap[constraintID]->sortedRules )
assert( dr );
rv.push_back( dr );
for( auto rule : m_ruleMap[ruleID]->sortedRules )
{ {
assert( rule ); assert( rule );
assert( rule->rule ); assert( rule->rule );
rv.push_back(rule->rule);
for( const DRC_CONSTRAINT& c : rule->constraints )
if( c.GetType() == constraintID )
rv.push_back( c );
} }
return rv; return rv;
} }
bool test::DRC_ENGINE::HasCorrectRulesForId( test::DRC_RULE_ID_T ruleID ) bool test::DRC_ENGINE::HasCorrectRulesForId( test::DRC_CONSTRAINT_TYPE_T ruleID )
{ {
return m_ruleMap[ruleID]->defaultRule != nullptr; return m_ruleMap[ruleID]->sortedRules.size() != 0;
} }
bool test::DRC_ENGINE::QueryWorstConstraint( test::DRC_RULE_ID_T aRuleId, test::DRC_CONSTRAINT& aConstraint, test::DRC_CONSTRAINT_QUERY_T aQueryType ) bool test::DRC_ENGINE::QueryWorstConstraint( test::DRC_CONSTRAINT_TYPE_T aConstraintId, test::DRC_CONSTRAINT& aConstraint, test::DRC_CONSTRAINT_QUERY_T aQueryType )
{ {
if( aQueryType == DRCCQ_LARGEST_MINIMUM ) if( aQueryType == DRCCQ_LARGEST_MINIMUM )
{ {
int worst = 0; int worst = 0;
for( auto rule : QueryRulesById( test::DRC_RULE_ID_T::DRC_RULE_ID_EDGE_CLEARANCE ) ) for( const auto constraint : QueryConstraintsById( aConstraintId ) )
{ {
if( rule->GetConstraint().m_Value.HasMin() ) if( constraint.GetValue().HasMin() )
{ {
int current = rule->GetConstraint().m_Value.Min(); int current = constraint.GetValue().Min();
if( current > worst ) if( current > worst )
{ {
worst = current; worst = current;
aConstraint = rule->GetConstraint(); aConstraint = constraint;
} }
} }
} }

View File

@ -178,17 +178,18 @@ public:
{ {
return m_designSettings; return m_designSettings;
} }
BOARD* GetBoard() const BOARD* GetBoard() const
{ {
return m_board; return m_board;
} }
DRC_RULE* EvalRulesForItems( const DRC_CONSTRAINT& EvalRulesForItems(
DRC_RULE_ID_T ruleID, BOARD_ITEM* a, BOARD_ITEM* b = nullptr ); DRC_CONSTRAINT_TYPE_T ruleID, BOARD_ITEM* a, BOARD_ITEM* b = nullptr, PCB_LAYER_ID aLayer = UNDEFINED_LAYER );
std::vector<DRC_RULE*> QueryRulesById( test::DRC_RULE_ID_T ruleID ); std::vector<DRC_CONSTRAINT> QueryConstraintsById( test::DRC_CONSTRAINT_TYPE_T ruleID );
bool HasCorrectRulesForId( test::DRC_RULE_ID_T ruleID ); bool HasCorrectRulesForId( test::DRC_CONSTRAINT_TYPE_T ruleID );
EDA_UNITS UserUnits() const EDA_UNITS UserUnits() const
{ {
@ -204,7 +205,7 @@ public:
std::shared_ptr<DRC_REPORT> GetReport() const { return m_drcReport; } std::shared_ptr<DRC_REPORT> GetReport() const { return m_drcReport; }
bool QueryWorstConstraint( DRC_RULE_ID_T aRuleId, test::DRC_CONSTRAINT& aConstraint, DRC_CONSTRAINT_QUERY_T aQueryType ); bool QueryWorstConstraint( DRC_CONSTRAINT_TYPE_T aRuleId, test::DRC_CONSTRAINT& aConstraint, DRC_CONSTRAINT_QUERY_T aQueryType );
private: private:
@ -216,16 +217,16 @@ private:
{ {
std::vector<test::DRC_RULE_CONDITION*> conditions; std::vector<test::DRC_RULE_CONDITION*> conditions;
test::DRC_RULE* rule; test::DRC_RULE* rule;
std::vector<test::DRC_CONSTRAINT> constraints;
}; };
struct RULE_SET struct RULE_SET
{ {
std::vector<RULE_WITH_CONDITIONS*> sortedRules; std::vector<RULE_WITH_CONDITIONS*> sortedRules;
DRC_RULE* defaultRule;
DRC_TEST_PROVIDER* provider; DRC_TEST_PROVIDER* provider;
}; };
typedef std::unordered_map<test::DRC_RULE_ID_T, RULE_SET*> RULE_MAP; typedef std::unordered_map<test::DRC_CONSTRAINT_TYPE_T, RULE_SET*> RULE_MAP;
void inferImplicitRules(); void inferImplicitRules();

View File

@ -58,7 +58,7 @@ public:
virtual const wxString GetName() const; virtual const wxString GetName() const;
virtual const wxString GetDescription() const; virtual const wxString GetDescription() const;
virtual std::set<test::DRC_RULE_ID_T> GetMatchingRuleIds() const; virtual std::set<test::DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const;
/** /**
* Pass a given marker to the marker handler * Pass a given marker to the marker handler

View File

@ -33,9 +33,9 @@
test::DRC_RULE::DRC_RULE() : test::DRC_RULE::DRC_RULE() :
m_Unary( false ), m_Unary( false ),
m_Enabled( true ), m_Enabled( true ),
m_Conditional( false ),
m_Priority( 0 ), m_Priority( 0 ),
m_Severity( DRC_RULE_SEVERITY_T::DRC_SEVERITY_ERROR ) m_Severity( DRC_RULE_SEVERITY_T::DRC_SEVERITY_ERROR ),
m_condition( nullptr )
{ {
} }
@ -44,6 +44,10 @@ test::DRC_RULE::~DRC_RULE()
{ {
} }
void test::DRC_RULE::AddConstraint( const DRC_CONSTRAINT& aConstraint )
{
m_constraints.push_back( aConstraint );
}
test::DRC_RULE_CONDITION::DRC_RULE_CONDITION() test::DRC_RULE_CONDITION::DRC_RULE_CONDITION()
{ {
@ -53,7 +57,6 @@ test::DRC_RULE_CONDITION::DRC_RULE_CONDITION()
test::DRC_RULE_CONDITION::~DRC_RULE_CONDITION() test::DRC_RULE_CONDITION::~DRC_RULE_CONDITION()
{ {
delete m_ucode;
} }
@ -61,7 +64,7 @@ bool test::DRC_RULE_CONDITION::EvaluateFor( const BOARD_ITEM* aItemA, const BOAR
PCB_LAYER_ID aLayer ) PCB_LAYER_ID aLayer )
{ {
// An unconditional rule is always true // An unconditional rule is always true
if( m_Expression.IsEmpty() ) if( m_expression.IsEmpty() )
return true; return true;
// A rule which failed to compile is always false // A rule which failed to compile is always false
@ -77,16 +80,16 @@ bool test::DRC_RULE_CONDITION::EvaluateFor( const BOARD_ITEM* aItemA, const BOAR
} }
bool test::DRC_RULE_CONDITION::Compile( ) bool test::DRC_RULE_CONDITION::Compile( REPORTER* aReporter, int aSourceLine, int aSourceOffset )
{ {
PCB_EXPR_COMPILER compiler; PCB_EXPR_COMPILER compiler;
if (!m_ucode) if (!m_ucode)
m_ucode = new PCB_EXPR_UCODE; m_ucode.reset( new PCB_EXPR_UCODE );
PCB_EXPR_CONTEXT preflightContext( F_Cu ); PCB_EXPR_CONTEXT preflightContext( F_Cu );
bool ok = compiler.Compile( m_Expression.ToUTF8().data(), m_ucode, &preflightContext ); bool ok = compiler.Compile( m_expression, m_ucode.get(), &preflightContext );
return ok; return ok;
} }

View File

@ -42,18 +42,39 @@ class PCB_EXPR_UCODE;
namespace test namespace test
{ {
enum class DRC_RULE_ID_T class DRC_RULE;
class DRC_RULE_CONDITION;
enum DRC_CONSTRAINT_TYPE_T
{ {
DRC_RULE_ID_UNKNOWN = -1, DRC_CONSTRAINT_TYPE_UNKNOWN = -1,
DRC_RULE_ID_CLEARANCE = 0, DRC_CONSTRAINT_TYPE_CLEARANCE = 0,
DRC_RULE_ID_HOLE_CLEARANCE, DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE,
DRC_RULE_ID_EDGE_CLEARANCE, DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE,
DRC_RULE_ID_HOLE_SIZE, DRC_CONSTRAINT_TYPE_HOLE_SIZE,
DRC_RULE_ID_COURTYARD_CLEARANCE, DRC_CONSTRAINT_TYPE_COURTYARD_CLEARANCE,
DRC_RULE_ID_SILK_TO_PAD DRC_CONSTRAINT_TYPE_SILK_TO_PAD,
DRC_CONSTRAINT_TYPE_SILK_TO_SILK,
DRC_CONSTRAINT_TYPE_TRACK_WIDTH,
DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH,
DRC_CONSTRAINT_TYPE_DISALLOW
}; };
enum class DRC_RULE_SEVERITY_T enum DRC_DISALLOW_T
{
DRC_DISALLOW_VIAS = (1 << 0),
DRC_DISALLOW_MICRO_VIAS = (1 << 1),
DRC_DISALLOW_BB_VIAS = (1 << 2),
DRC_DISALLOW_TRACKS = (1 << 3),
DRC_DISALLOW_PADS = (1 << 4),
DRC_DISALLOW_ZONES = (1 << 5),
DRC_DISALLOW_TEXTS = (1 << 6),
DRC_DISALLOW_GRAPHICS = (1 << 7),
DRC_DISALLOW_HOLES = (1 << 8),
DRC_DISALLOW_FOOTPRINTS = (1 << 9)
};
enum DRC_RULE_SEVERITY_T
{ {
DRC_SEVERITY_IGNORE = 0, DRC_SEVERITY_IGNORE = 0,
DRC_SEVERITY_WARNING, DRC_SEVERITY_WARNING,
@ -89,21 +110,30 @@ class DRC_CONSTRAINT
{ {
public: public:
DRC_CONSTRAINT() : DRC_CONSTRAINT() :
m_Type( DRC_RULE_ID_T::DRC_RULE_ID_UNKNOWN ), m_Type( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_UNKNOWN ),
m_DisallowFlags( 0 ), m_DisallowFlags( 0 ),
m_LayerCondition( LSET::AllLayersMask() ) m_LayerCondition( LSET::AllLayersMask() ),
m_parentRule( nullptr ) // fixme
{ {
} }
const MINOPTMAX<int>& GetValue() const { return m_Value; } const MINOPTMAX<int>& GetValue() const { return m_Value; }
MINOPTMAX<int>& Value() { return m_Value; }
// fixme: needed?
bool Allowed() const { return m_Allow; } bool Allowed() const { return m_Allow; }
DRC_RULE* GetParentRule() const { return m_parentRule; }
DRC_CONSTRAINT_TYPE_T GetType() const { return m_Type; }
public: public:
DRC_RULE_ID_T m_Type; DRC_CONSTRAINT_TYPE_T m_Type;
MINOPTMAX<int> m_Value;
int m_DisallowFlags; int m_DisallowFlags;
LSET m_LayerCondition; LSET m_LayerCondition;
private:
DRC_RULE *m_parentRule;
MINOPTMAX<int> m_Value;
bool m_Allow; bool m_Allow;
}; };
@ -124,22 +154,44 @@ public:
DRC_RULE_SEVERITY_T GetSeverity() const { return m_Severity; } DRC_RULE_SEVERITY_T GetSeverity() const { return m_Severity; }
const wxString GetName() const { return m_Name; } const wxString GetName() const { return m_Name; }
const wxString GetTestProviderName() const { return m_TestProviderName; }
const DRC_CONSTRAINT& GetConstraint() const { return m_Constraint; } std::vector<DRC_CONSTRAINT>& Constraints()
{
return m_constraints;
}
void AddConstraint( const DRC_CONSTRAINT& aConstraint );
bool IsConditional() const
{
return m_condition != nullptr;
}
void SetCondition( test::DRC_RULE_CONDITION* aCondition )
{
m_condition = aCondition;
}
test::DRC_RULE_CONDITION* Condition()
{
return m_condition;
}
void SetLayerCondition( LSET aLayerCondition )
{
m_layerCondition = aLayerCondition;
}
public: public:
bool m_Unary; bool m_Unary;
wxString m_Name; wxString m_Name;
LSET m_LayerCondition; LSET m_layerCondition;
wxString m_TestProviderName; DRC_RULE_CONDITION* m_condition; // fixme: consider unique_ptr
DRC_RULE_CONDITION m_Condition; std::vector<DRC_CONSTRAINT> m_constraints;
std::vector<DRC_CONSTRAINT> m_Constraints;
DRC_RULE_SEVERITY_T m_Severity; DRC_RULE_SEVERITY_T m_Severity;
bool m_Enabled; bool m_Enabled;
bool m_Conditional;
int m_Priority; // 0 indicates automatic priority generation int m_Priority; // 0 indicates automatic priority generation
}; };
@ -150,16 +202,30 @@ public:
DRC_RULE_CONDITION(); DRC_RULE_CONDITION();
~DRC_RULE_CONDITION(); ~DRC_RULE_CONDITION();
bool EvaluateFor( const BOARD_ITEM* aItemA, const BOARD_ITEM* aItemB ); bool EvaluateFor( const BOARD_ITEM* aItemA, const BOARD_ITEM* aItemB,
PCB_LAYER_ID aLayer );
bool Compile( REPORTER* aReporter, int aSourceLine = 0, int aSourceOffset = 0 ); bool Compile( REPORTER* aReporter, int aSourceLine = 0, int aSourceOffset = 0 );
public: void SetLayerCondition( LSET aLayerCondition )
LSET m_LayerCondition; {
wxString m_Expression; m_layerCondition = aLayerCondition;
wxString m_TargetRuleName; }
void SetExpression( const wxString& aExpression )
{
m_expression = aExpression;
}
const wxString& GetExpression() const
{
return m_expression;
}
private: private:
PCB_EXPR_UCODE* m_ucode; LSET m_layerCondition;
wxString m_expression;
std::unique_ptr<PCB_EXPR_UCODE> m_ucode;
}; };

View File

@ -28,18 +28,30 @@
#include <drc_proto/drc_rule.h> #include <drc_proto/drc_rule.h>
#include <drc_proto/drc_rule_parser.h> #include <drc_proto/drc_rule_parser.h>
#include <drc_proto/drc_rules_lexer.h> #include <drc_rules_lexer.h>
#include <drc_proto/drc_engine.h> // drc_dbg #include <drc_proto/drc_engine.h> // drc_dbg
#include <pcb_expr_evaluator.h> #include <pcb_expr_evaluator.h>
#include <reporter.h> #include <reporter.h>
using namespace DRCRULEPROTO_T; using namespace DRCRULE_T;
test::DRC_RULES_PARSER::DRC_RULES_PARSER( BOARD* aBoard, FILE* aFile, const wxString& aFilename ) test::DRC_RULES_PARSER::DRC_RULES_PARSER( BOARD* aBoard, const wxString& aSource,
: DRC_RULES_PROTO_LEXER( aFile, aFilename ), const wxString& aSourceDescr ) :
DRC_RULES_LEXER( aSource.ToStdString(), aSourceDescr ),
m_board( aBoard ), m_board( aBoard ),
m_requiredVersion( 0 ), m_requiredVersion( 0 ),
m_tooRecent( false ) m_tooRecent( false ),
m_reporter( nullptr )
{
}
test::DRC_RULES_PARSER::DRC_RULES_PARSER( BOARD* aBoard, FILE* aFile, const wxString& aFilename ) :
DRC_RULES_LEXER( aFile, aFilename ),
m_board( aBoard ),
m_requiredVersion( 0 ),
m_tooRecent( false ),
m_reporter( nullptr )
{ {
} }
@ -76,9 +88,7 @@ void test::DRC_RULES_PARSER::parseUnknown()
} }
void test::DRC_RULES_PARSER::Parse( std::vector<test::DRC_RULE_CONDITION*>& aConditions, void test::DRC_RULES_PARSER::Parse( std::vector<DRC_RULE*>& aRules, REPORTER* aReporter )
std::vector<test::DRC_RULE*>& aRules,
REPORTER* aReporter )
{ {
bool haveVersion = false; bool haveVersion = false;
wxString msg; wxString msg;
@ -131,86 +141,36 @@ void test::DRC_RULES_PARSER::Parse( std::vector<test::DRC_RULE_CONDITION*>& aCon
break; break;
case T_condition:
aConditions.push_back( parseCONDITION() );
break;
case T_rule: case T_rule:
{ aRules.push_back( parseDRC_RULE() );
auto rule = parseRULE();
drc_dbg(0, "Parsed rule: '%s' type '%s'\n", (const char*) rule->GetName().c_str(), (const char*) rule->GetTestProviderName().c_str() );
aRules.push_back( rule );
break; break;
}
default: default:
msg.Printf( _( "Unrecognized item '%s'.| Expected 'rule', 'condition' or 'version'." ), msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ),
FromUTF8() ); FromUTF8(), "'rule', 'version'" );
reportError( msg ); reportError( msg );
parseUnknown(); parseUnknown();
} }
} }
if( !m_reporter->HasMessage() )
m_reporter->Report( _( "No errors found." ), RPT_SEVERITY_INFO );
m_reporter = nullptr;
} }
test::DRC_RULE_CONDITION* test::DRC_RULES_PARSER::parseCONDITION() test::DRC_RULE* test::DRC_RULES_PARSER::parseDRC_RULE()
{
test::DRC_RULE_CONDITION* cond = new test::DRC_RULE_CONDITION();
T token;
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
if( token != T_LEFT )
Expecting( T_LEFT );
token = NextTok();
//printf( "Do token xxx %d '%s'\n", token, (const char*) FromUTF8().c_str() );
// TODO: Needs updating to report errors through REPORTER
switch( token )
{
case T_expression:
NeedSYMBOL();
cond->m_Expression = FromUTF8();
break;
case T_rule:
NeedSYMBOL();
cond->m_TargetRuleName = FromUTF8();
break;
default:
Expecting( "rule or expression" );
break;
}
NeedRIGHT();
}
//NeedRIGHT()
return cond;
}
test::DRC_RULE* test::DRC_RULES_PARSER::parseRULE()
{ {
DRC_RULE* rule = new DRC_RULE(); DRC_RULE* rule = new DRC_RULE();
T token = NextTok(); T token = NextTok();
int value;
wxString msg; wxString msg;
if( !IsSymbol( token ) ) if( !IsSymbol( token ) )
reportError( _( "Missing rule name." ) ); reportError( _( "Missing rule name." ) );
rule->m_Priority = 0;
rule->m_Enabled = true;
rule->m_Name = FromUTF8(); rule->m_Name = FromUTF8();
printf("parseRule '%s'\n", (const char *) rule->m_Name.c_str() );
for( token = NextTok(); token != T_RIGHT; token = NextTok() ) for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{ {
if( token != T_LEFT ) if( token != T_LEFT )
@ -218,18 +178,139 @@ test::DRC_RULE* test::DRC_RULES_PARSER::parseRULE()
token = NextTok(); token = NextTok();
//printf( "Do token xxx %d '%s'\n", token, (const char*) FromUTF8().c_str() ); switch( token )
{
case T_constraint:
parseConstraint( rule );
break;
case T_condition:
token = NextTok();
if( (int) token == DSN_RIGHT )
{
reportError( _( "Missing condition expression." ) );
break;
}
if( IsSymbol( token ) )
{
auto condition = new DRC_RULE_CONDITION;
condition->SetExpression( FromUTF8() );
rule->SetCondition( condition );
}
else
{
msg.Printf( _( "Unrecognized item '%s'.| Expected quoted expression." ),
FromUTF8() );
reportError( msg );
}
if( (int) NextTok() != DSN_RIGHT )
{
reportError( wxString::Format( _( "Unrecognized item '%s'." ), FromUTF8() ) );
parseUnknown();
}
break;
case T_layer:
rule->SetLayerCondition( parseLayer() );
break;
default:
msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ),
FromUTF8(),
"'constraint', 'condition', 'disallow'" );
reportError( msg );
parseUnknown();
}
}
return rule;
}
void test::DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
{
DRC_CONSTRAINT constraint;
int value;
wxString msg;
T token = NextTok();
if( (int) token == DSN_RIGHT )
{
msg.Printf( _( "Missing constraint type.| Expected %s." ),
"'clearance', 'track_width', 'annulus_width', 'hole', 'disallow'" );
reportError( msg );
return;
}
switch( token ) switch( token )
{ {
case T_type: case T_clearance: constraint.m_Type = test::DRC_CONSTRAINT_TYPE_CLEARANCE; break;
// TODO: I assume this won't be in the final impl and so doesn't need converting case T_hole_clearance: constraint.m_Type = test::DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE; break;
// to new error reporting framework? case T_edge_clearance: constraint.m_Type = test::DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE; break;
NeedSYMBOL(); case T_hole: constraint.m_Type = test::DRC_CONSTRAINT_TYPE_HOLE_SIZE; break;
rule->m_TestProviderName = FromUTF8(); case T_courtyard_clearance: constraint.m_Type = test::DRC_CONSTRAINT_TYPE_COURTYARD_CLEARANCE; break;
NeedRIGHT(); case T_silk_to_pad: constraint.m_Type = test::DRC_CONSTRAINT_TYPE_SILK_TO_PAD; break;
break; case T_silk_to_silk: constraint.m_Type = test::DRC_CONSTRAINT_TYPE_SILK_TO_SILK; break;
case T_track_width: constraint.m_Type = test::DRC_CONSTRAINT_TYPE_TRACK_WIDTH; break;
case T_annulus_width: constraint.m_Type = test::DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH; break;
case T_disallow: constraint.m_Type = test::DRC_CONSTRAINT_TYPE_DISALLOW; break;
default:
msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ),
FromUTF8(),
"'clearance', 'track_width', 'annulus_width', 'hole', 'disallow'."
);
reportError( msg );
}
if( constraint.m_Type == DRC_CONSTRAINT_TYPE_DISALLOW )
{
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
if( (int) token == DSN_STRING )
token = GetCurStrAsToken();
switch( token )
{
case T_track: constraint.m_DisallowFlags |= DISALLOW_TRACKS; break;
case T_via: constraint.m_DisallowFlags |= DISALLOW_VIAS; break;
case T_micro_via: constraint.m_DisallowFlags |= DISALLOW_MICRO_VIAS; break;
case T_buried_via: constraint.m_DisallowFlags |= DISALLOW_BB_VIAS; break;
case T_pad: constraint.m_DisallowFlags |= DISALLOW_PADS; break;
case T_zone: constraint.m_DisallowFlags |= DISALLOW_ZONES; break;
case T_text: constraint.m_DisallowFlags |= DISALLOW_TEXTS; break;
case T_graphic: constraint.m_DisallowFlags |= DISALLOW_GRAPHICS; break;
case T_hole: constraint.m_DisallowFlags |= DISALLOW_HOLES; break;
case T_footprint: constraint.m_DisallowFlags |= DISALLOW_FOOTPRINTS; break;
default:
msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ),
FromUTF8(),
"'track', 'via', 'micro_via', "
"'blind_via', 'pad', 'zone', 'text', 'graphic', 'hole'."
);
reportError( msg );
parseUnknown();
}
}
return;
}
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
if( token != T_LEFT )
reportError( _( "Missing '('." ) );
token = NextTok();
switch( token )
{
case T_min: case T_min:
token = NextTok(); token = NextTok();
@ -240,27 +321,7 @@ test::DRC_RULE* test::DRC_RULES_PARSER::parseRULE()
} }
parseValueWithUnits( FromUTF8(), value ); parseValueWithUnits( FromUTF8(), value );
rule->m_Constraint.m_Value.SetMin( value ); constraint.Value().SetMin( value );
if( (int) NextTok() != DSN_RIGHT )
{
reportError( wxString::Format( _( "Unrecognized item '%s'." ), FromUTF8() ) );
parseUnknown();
}
break;
case T_opt:
token = NextTok();
if( (int) token == DSN_RIGHT )
{
reportError( _( "Missing opt value." ) );
break;
}
parseValueWithUnits( FromUTF8(), value );
rule->m_Constraint.m_Value.SetOpt( value );
if( (int) NextTok() != DSN_RIGHT ) if( (int) NextTok() != DSN_RIGHT )
{ {
@ -280,7 +341,7 @@ test::DRC_RULE* test::DRC_RULES_PARSER::parseRULE()
} }
parseValueWithUnits( FromUTF8(), value ); parseValueWithUnits( FromUTF8(), value );
rule->m_Constraint.m_Value.SetMax( value ); constraint.Value().SetMax( value );
if( (int) NextTok() != DSN_RIGHT ) if( (int) NextTok() != DSN_RIGHT )
{ {
@ -290,10 +351,27 @@ test::DRC_RULE* test::DRC_RULES_PARSER::parseRULE()
break; break;
case T_allow: case T_opt:
rule->m_Constraint.m_Allow = parseInt("allowed"); token = NextTok();
NeedRIGHT();
if( (int) token == DSN_RIGHT )
{
reportError( _( "Missing opt value." ) );
break; break;
}
parseValueWithUnits( FromUTF8(), value );
constraint.Value().SetOpt( value );
if( (int) NextTok() != DSN_RIGHT )
{
reportError( wxString::Format( _( "Unrecognized item '%s'." ), FromUTF8() ) );
parseUnknown();
}
break;
/* fixme: bring these back?
case T_enable: case T_enable:
rule->m_Enabled = parseInt("enabled"); rule->m_Enabled = parseInt("enabled");
@ -315,30 +393,17 @@ test::DRC_RULE* test::DRC_RULES_PARSER::parseRULE()
break; break;
*/
case T_priority:
rule->m_Priority = parseInt("priotity");
NeedRIGHT();
break;
default: default:
// TODO: reconcile msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ),
//Expecting( "type, min, opt, max, allow, enable, priority or severity" ); FromUTF8(), "'min', 'max', 'opt'" );
msg.Printf( _( "Unrecognized item '%s'.| Expected 'min', 'max' or 'opt'." ),
FromUTF8() );
reportError( msg ); reportError( msg );
parseUnknown(); parseUnknown();
break; }
}
} }
}
return rule;
}
void test::DRC_RULES_PARSER::parseValueWithUnits( const wxString& aExpr, int& aResult ) void test::DRC_RULES_PARSER::parseValueWithUnits( const wxString& aExpr, int& aResult )
{ {

View File

@ -28,7 +28,8 @@
#include <netclass.h> #include <netclass.h>
#include <layers_id_colors_and_visibility.h> #include <layers_id_colors_and_visibility.h>
#include <drc_proto/drc_rule.h> #include <drc_proto/drc_rule.h>
#include <drc_rules_proto_lexer.h> #include <drc_rules_lexer.h>
class BOARD_ITEM; class BOARD_ITEM;
@ -40,40 +41,25 @@ class DRC_RULE;
#define DRC_RULE_FILE_VERSION 20200610 #define DRC_RULE_FILE_VERSION 20200610
class DRC_RULES_PARSER : public DRC_RULES_PROTO_LEXER class DRC_RULES_PARSER : public DRC_RULES_LEXER
{ {
public: public:
DRC_RULES_PARSER( BOARD* aBoard, const wxString& aSource, const wxString& aSourceDescr );
DRC_RULES_PARSER( BOARD* aBoard, FILE* aFile, const wxString& aFilename ); DRC_RULES_PARSER( BOARD* aBoard, FILE* aFile, const wxString& aFilename );
void Parse( std::vector<DRC_RULE_CONDITION*>& aConditions, std::vector<DRC_RULE*>& aRules, void Parse( std::vector<DRC_RULE*>& aRules, REPORTER* aReporter );
REPORTER* aReporter );
private: private:
DRC_RULE_CONDITION* parseCONDITION(); DRC_RULE* parseDRC_RULE();
DRC_RULE* parseRULE();
void parseConstraint( DRC_RULE* aRule );
void parseValueWithUnits( const wxString& aExpr, int& aResult ); void parseValueWithUnits( const wxString& aExpr, int& aResult );
inline int parseInt()
{
return (int)strtol( CurText(), NULL, 10 );
}
inline int parseInt( const char* aExpected )
{
NeedNUMBER( aExpected );
return parseInt();
}
LSET parseLayer(); LSET parseLayer();
void parseUnknown(); void parseUnknown();
void reportError( const wxString& aMessage ); void reportError( const wxString& aMessage );
// void parseConstraint( DRC_RULE* aRule );
//int parseValue( DRCRULE_T::T aToken );
private: private:
BOARD* m_board; BOARD* m_board;
int m_requiredVersion; int m_requiredVersion;
bool m_tooRecent; bool m_tooRecent;

View File

@ -1,195 +0,0 @@
/* Do not modify this file it was automatically generated by the
* TokenList2DsnLexer CMake script.
*/
#ifndef DRC_RULES_LEXER_H_
#define DRC_RULES_LEXER_H_
#include <dsnlexer.h>
/**
* C++ does not put enum _values_ in separate namespaces unless the enum itself
* is in a separate namespace. All the token enums must be in separate namespaces
* otherwise the C++ compiler will eventually complain if it sees more than one
* DSNLEXER in the same compilation unit, say by mutliple header file inclusion.
* Plus this also enables re-use of the same enum name T. A typedef can always be used
* to clarify which enum T is in play should that ever be a problem. This is
* unlikely since Parse() functions will usually only be exposed to one header
* file like this one. But if there is a problem, then use:
* typedef DRCRULE_T::T T;
* within that problem area.
*/
namespace DRCRULE_T
{
/// enum T contains all this lexer's tokens.
enum T
{
// these first few are negative special ones for syntax, and are
// inherited from DSNLEXER.
T_NONE = DSN_NONE,
T_COMMENT = DSN_COMMENT,
T_STRING_QUOTE = DSN_STRING_QUOTE,
T_QUOTE_DEF = DSN_QUOTE_DEF,
T_DASH = DSN_DASH,
T_SYMBOL = DSN_SYMBOL,
T_NUMBER = DSN_NUMBER,
T_RIGHT = DSN_RIGHT, // right bracket: ')'
T_LEFT = DSN_LEFT, // left bracket: '('
T_STRING = DSN_STRING, // a quoted string, stripped of the quotes
T_EOF = DSN_EOF, // special case for end of file
T_allow = 0,
T_condition,
T_enable,
T_error,
T_expression,
T_ignore,
T_info,
T_max,
T_min,
T_name,
T_opt,
T_priority,
T_rule,
T_severity,
T_type,
T_version,
T_warning
};
} // namespace DRCRULE_T
/**
* Class DRC_RULES_LEXER
* is an automatically generated class using the TokenList2DnsLexer.cmake
* technology, based on keywords provided by file:
* /home/twl/Kicad-dev/kicad-git-dev/common/drc_rules.keywords
*/
class DRC_RULES_LEXER : public DSNLEXER
{
/// Auto generated lexer keywords table and length:
static const KEYWORD keywords[];
static const unsigned keyword_count;
public:
/**
* Constructor ( const std::string&, const wxString& )
* @param aSExpression is (utf8) text possibly from the clipboard that you want to parse.
* @param aSource is a description of the origin of @a aSExpression, such as a filename.
* If left empty, then _("clipboard") is used.
*/
DRC_RULES_LEXER( const std::string& aSExpression, const wxString& aSource = wxEmptyString ) :
DSNLEXER( keywords, keyword_count, aSExpression, aSource )
{
}
/**
* Constructor ( FILE* )
* takes @a aFile already opened for reading and @a aFilename as parameters.
* The opened file is assumed to be positioned at the beginning of the file
* for purposes of accurate line number reporting in error messages. The
* FILE is closed by this instance when its destructor is called.
* @param aFile is a FILE already opened for reading.
* @param aFilename is the name of the opened file, needed for error reporting.
*/
DRC_RULES_LEXER( FILE* aFile, const wxString& aFilename ) :
DSNLEXER( keywords, keyword_count, aFile, aFilename )
{
}
/**
* Constructor ( LINE_READER* )
* initializes a lexer and prepares to read from @a aLineReader which
* is assumed ready, and may be in use by other DSNLEXERs also. No ownership
* is taken of @a aLineReader. This enables it to be used by other lexers also.
* The transition between grammars in such a case, must happen on a text
* line boundary, not within the same line of text.
*
* @param aLineReader is any subclassed instance of LINE_READER, such as
* STRING_LINE_READER or FILE_LINE_READER. No ownership is taken of aLineReader.
*/
DRC_RULES_LEXER( LINE_READER* aLineReader ) :
DSNLEXER( keywords, keyword_count, aLineReader )
{
}
/**
* Function TokenName
* returns the name of the token in ASCII form.
*/
static const char* TokenName( DRCRULE_T::T aTok );
/**
* Function NextTok
* returns the next token found in the input file or T_EOF when reaching
* the end of file. Users should wrap this function to return an enum
* to aid in grammar debugging while running under a debugger, but leave
* this lower level function returning an int (so the enum does not collide
* with another usage).
* @return DRCRULE_T::T - the type of token found next.
* @throw IO_ERROR - only if the LINE_READER throws it.
*/
DRCRULE_T::T NextTok()
{
return (DRCRULE_T::T) DSNLEXER::NextTok();
}
/**
* Function NeedSYMBOL
* calls NextTok() and then verifies that the token read in
* satisfies bool IsSymbol().
* If not, an IO_ERROR is thrown.
* @return int - the actual token read in.
* @throw IO_ERROR, if the next token does not satisfy IsSymbol()
*/
DRCRULE_T::T NeedSYMBOL()
{
return (DRCRULE_T::T) DSNLEXER::NeedSYMBOL();
}
/**
* Function NeedSYMBOLorNUMBER
* calls NextTok() and then verifies that the token read in
* satisfies bool IsSymbol() or tok==T_NUMBER.
* If not, an IO_ERROR is thrown.
* @return int - the actual token read in.
* @throw IO_ERROR, if the next token does not satisfy the above test
*/
DRCRULE_T::T NeedSYMBOLorNUMBER()
{
return (DRCRULE_T::T) DSNLEXER::NeedSYMBOLorNUMBER();
}
/**
* Function CurTok
* returns whatever NextTok() returned the last time it was called.
*/
DRCRULE_T::T CurTok()
{
return (DRCRULE_T::T) DSNLEXER::CurTok();
}
/**
* Function PrevTok
* returns whatever NextTok() returned the 2nd to last time it was called.
*/
DRCRULE_T::T PrevTok()
{
return (DRCRULE_T::T) DSNLEXER::PrevTok();
}
};
// example usage
/**
* Class _PARSER
* holds data and functions pertinent to parsing a S-expression file .
*
class DRC_RULES_PARSER : public DRC_RULES_LEXER
{
};
*/
#endif // DRC_RULES_LEXER_H_

View File

@ -75,7 +75,7 @@ EDA_UNITS test::DRC_TEST_PROVIDER::userUnits() const
return m_drcEngine->UserUnits(); return m_drcEngine->UserUnits();
} }
void test::DRC_TEST_PROVIDER::accountCheck( test::DRC_RULE* ruleToTest ) void test::DRC_TEST_PROVIDER::accountCheck( const test::DRC_RULE* ruleToTest )
{ {
auto it = m_stats.find( ruleToTest ); auto it = m_stats.find( ruleToTest );
if( it == m_stats.end() ) if( it == m_stats.end() )
@ -84,6 +84,12 @@ void test::DRC_TEST_PROVIDER::accountCheck( test::DRC_RULE* ruleToTest )
it->second++; it->second++;
} }
void test::DRC_TEST_PROVIDER::accountCheck( const test::DRC_CONSTRAINT& constraintToTest )
{
accountCheck( constraintToTest.GetParentRule() );
}
void test::DRC_TEST_PROVIDER::reportRuleStatistics() void test::DRC_TEST_PROVIDER::reportRuleStatistics()
{ {
m_drcEngine->ReportAux("Rule hit statistics: "); m_drcEngine->ReportAux("Rule hit statistics: ");

View File

@ -104,19 +104,20 @@ public:
virtual void ReportProgress( double aProgress ); virtual void ReportProgress( double aProgress );
virtual void ReportStage ( const wxString& aStageName, int index, int total ); virtual void ReportStage ( const wxString& aStageName, int index, int total );
virtual std::set<test::DRC_RULE_ID_T> GetMatchingRuleIds() const = 0; virtual std::set<test::DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const = 0;
protected: protected:
int forEachGeometryItem( const std::vector<KICAD_T> aTypes, const LSET aLayers, std::function<int(BOARD_ITEM*)> aFunc ); int forEachGeometryItem( const std::vector<KICAD_T> aTypes, const LSET aLayers, std::function<int(BOARD_ITEM*)> aFunc );
virtual void reportRuleStatistics(); virtual void reportRuleStatistics();
virtual void accountCheck( test::DRC_RULE* ruleToTest ); virtual void accountCheck( const test::DRC_RULE* ruleToTest );
virtual void accountCheck( const test::DRC_CONSTRAINT& constraintToTest );
virtual bool isErrorLimitExceeded( int error_code ); virtual bool isErrorLimitExceeded( int error_code );
EDA_UNITS userUnits() const; EDA_UNITS userUnits() const;
DRC_ENGINE *m_drcEngine; DRC_ENGINE *m_drcEngine;
std::unordered_map<test::DRC_RULE*, int> m_stats; std::unordered_map<const test::DRC_RULE*, int> m_stats;
bool m_enable; bool m_enable;
}; };

View File

@ -76,7 +76,7 @@ public:
return "Tests copper item clearance"; return "Tests copper item clearance";
} }
virtual std::set<test::DRC_RULE_ID_T> GetMatchingRuleIds() const override; virtual std::set<test::DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
private: private:
void testPadClearances(); void testPadClearances();
@ -96,17 +96,16 @@ bool test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::Run()
{ {
auto bds = m_drcEngine->GetDesignSettings(); auto bds = m_drcEngine->GetDesignSettings();
m_board = m_drcEngine->GetBoard(); m_board = m_drcEngine->GetBoard();
DRC_CONSTRAINT worstClearanceConstraint;
m_largestClearance = 0; if( m_drcEngine->QueryWorstConstraint( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE, worstClearanceConstraint, DRCCQ_LARGEST_MINIMUM ) )
for( auto rule : m_drcEngine->QueryRulesById( test::DRC_RULE_ID_T::DRC_RULE_ID_CLEARANCE ) )
{ {
drc_dbg(1, "process rule %p\n", rule ); m_largestClearance = worstClearanceConstraint.GetValue().Min();
if( rule->GetConstraint().m_Value.HasMin() )
{
m_largestClearance = std::max( m_largestClearance, rule->GetConstraint().m_Value.Min() );
drc_dbg(1, "min-copper-clearance %d\n", rule->GetConstraint().m_Value.Min() );
} }
else
{
ReportAux("No Clearance constraints found...");
return false;
} }
ReportAux( "Worst clearance : %d nm", m_largestClearance ); ReportAux( "Worst clearance : %d nm", m_largestClearance );
@ -197,8 +196,8 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::testCopperDrawItem( BOARD_ITEM* a
if( !track->IsOnLayer( aItem->GetLayer() ) ) if( !track->IsOnLayer( aItem->GetLayer() ) )
continue; continue;
auto rule = m_drcEngine->EvalRulesForItems( test::DRC_RULE_ID_T::DRC_RULE_ID_CLEARANCE, aItem, track ); auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE, aItem, track, aItem->GetLayer() );
auto minClearance = rule->GetConstraint().GetValue().Min(); auto minClearance = constraint.GetValue().Min();
int actual = INT_MAX; int actual = INT_MAX;
wxPoint pos; wxPoint pos;
@ -220,13 +219,13 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::testCopperDrawItem( BOARD_ITEM* a
wxString msg; wxString msg;
msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ), msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ),
rule->GetName(), constraint.GetParentRule()->GetName(),
MessageTextFromValue( userUnits(), minClearance, true ), MessageTextFromValue( userUnits(), minClearance, true ),
MessageTextFromValue( userUnits(), actual, true ) ); MessageTextFromValue( userUnits(), actual, true ) );
drcItem->SetErrorMessage( msg ); drcItem->SetErrorMessage( msg );
drcItem->SetItems( track, aItem ); drcItem->SetItems( track, aItem );
drcItem->SetViolatingRule( rule ); drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, pos ); ReportWithMarker( drcItem, pos );
} }
@ -242,8 +241,8 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::testCopperDrawItem( BOARD_ITEM* a
if( drawItem && pad->GetParent() == drawItem->GetParent() ) if( drawItem && pad->GetParent() == drawItem->GetParent() )
continue; continue;
auto rule = m_drcEngine->EvalRulesForItems( test::DRC_RULE_ID_T::DRC_RULE_ID_CLEARANCE, aItem, pad ); auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE, aItem, pad );
auto minClearance = rule->GetConstraint().GetValue().Min(); auto minClearance = constraint.GetValue().Min();
int actual = INT_MAX; int actual = INT_MAX;
@ -265,13 +264,13 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::testCopperDrawItem( BOARD_ITEM* a
wxString msg; wxString msg;
msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ), msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ),
rule->GetName(), constraint.GetParentRule()->GetName(),
MessageTextFromValue( userUnits(), minClearance, true ), MessageTextFromValue( userUnits(), minClearance, true ),
MessageTextFromValue( userUnits(), actual, true ) ); MessageTextFromValue( userUnits(), actual, true ) );
drcItem->SetErrorMessage( msg ); drcItem->SetErrorMessage( msg );
drcItem->SetItems( pad, aItem ); drcItem->SetItems( pad, aItem );
drcItem->SetViolatingRule( rule ); drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, pad->GetPosition() ); ReportWithMarker( drcItem, pad->GetPosition() );
} }
@ -355,8 +354,8 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, TRACK
// fixme: hole to hole clearance moved elsewhere // fixme: hole to hole clearance moved elsewhere
auto rule = m_drcEngine->EvalRulesForItems( test::DRC_RULE_ID_T::DRC_RULE_ID_CLEARANCE, aRefSeg, pad ); auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE, aRefSeg, pad );
auto minClearance = rule->GetConstraint().GetValue().Min(); auto minClearance = constraint.GetValue().Min();
int clearanceAllowed = minClearance - bds.GetDRCEpsilon(); int clearanceAllowed = minClearance - bds.GetDRCEpsilon();
int actual; int actual;
@ -374,7 +373,7 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, TRACK
drcItem->SetErrorMessage( msg ); drcItem->SetErrorMessage( msg );
drcItem->SetItems( aRefSeg, pad ); drcItem->SetItems( aRefSeg, pad );
drcItem->SetViolatingRule( rule ); drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, pad->GetPosition() ); ReportWithMarker( drcItem, pad->GetPosition() );
@ -427,8 +426,8 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, TRACK
if( !trackBB.Intersects( refSegBB ) ) if( !trackBB.Intersects( refSegBB ) )
continue; continue;
auto rule = m_drcEngine->EvalRulesForItems( test::DRC_RULE_ID_T::DRC_RULE_ID_CLEARANCE, aRefSeg, track ); auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE, aRefSeg, track );
auto minClearance = rule->GetConstraint().GetValue().Min(); auto minClearance = constraint.GetValue().Min();
SHAPE_SEGMENT trackSeg( track->GetStart(), track->GetEnd(), track->GetWidth() ); SHAPE_SEGMENT trackSeg( track->GetStart(), track->GetEnd(), track->GetWidth() );
int actual; int actual;
@ -440,7 +439,7 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, TRACK
// fixme // fixme
drcItem->SetErrorMessage( "FIXME" ); drcItem->SetErrorMessage( "FIXME" );
drcItem->SetItems( aRefSeg, track ); drcItem->SetItems( aRefSeg, track );
drcItem->SetViolatingRule( rule ); drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, (wxPoint) intersection.get() ); ReportWithMarker( drcItem, (wxPoint) intersection.get() );
@ -461,7 +460,7 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, TRACK
drcItem->SetErrorMessage( msg ); drcItem->SetErrorMessage( msg );
drcItem->SetItems( aRefSeg, track ); drcItem->SetItems( aRefSeg, track );
drcItem->SetViolatingRule( rule ); drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, pos ); ReportWithMarker( drcItem, pos );
@ -493,8 +492,8 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, TRACK
// fixme: per-layer onLayer() property // fixme: per-layer onLayer() property
auto rule = m_drcEngine->EvalRulesForItems( test::DRC_RULE_ID_T::DRC_RULE_ID_CLEARANCE, aRefSeg, zone ); auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE, aRefSeg, zone );
auto minClearance = rule->GetConstraint().GetValue().Min(); auto minClearance = constraint.GetValue().Min();
int widths = refSegWidth / 2; int widths = refSegWidth / 2;
// to avoid false positive, due to rounding issues and approxiamtions // to avoid false positive, due to rounding issues and approxiamtions
@ -512,13 +511,13 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, TRACK
wxString msg; wxString msg;
msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ), msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ),
rule->GetName(), constraint.GetParentRule()->GetName(),
MessageTextFromValue( userUnits(), minClearance, true ), MessageTextFromValue( userUnits(), minClearance, true ),
MessageTextFromValue( userUnits(), actual, true ) ); MessageTextFromValue( userUnits(), actual, true ) );
drcItem->SetErrorMessage( msg ); drcItem->SetErrorMessage( msg );
drcItem->SetItems( aRefSeg, zone ); drcItem->SetItems( aRefSeg, zone );
drcItem->SetViolatingRule( rule ); drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, getLocation( aRefSeg, zone ) ); ReportWithMarker( drcItem, getLocation( aRefSeg, zone ) );
} }
@ -628,8 +627,8 @@ bool test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::doPadToPadsDrc( D_PAD* aRefPad, D
continue; continue;
} }
auto rule = m_drcEngine->EvalRulesForItems( test::DRC_RULE_ID_T::DRC_RULE_ID_CLEARANCE, aRefPad, pad ); auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE, aRefPad, pad );
auto minClearance = rule->GetConstraint().GetValue().Min(); auto minClearance = constraint.GetValue().Min();
drc_dbg(4, "pad %p vs %p constraint %d\n", aRefPad, pad, minClearance ); drc_dbg(4, "pad %p vs %p constraint %d\n", aRefPad, pad, minClearance );
@ -649,7 +648,7 @@ bool test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::doPadToPadsDrc( D_PAD* aRefPad, D
drcItem->SetErrorMessage( msg ); drcItem->SetErrorMessage( msg );
drcItem->SetItems( aRefPad, pad ); drcItem->SetItems( aRefPad, pad );
drcItem->SetViolatingRule( rule ); drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, aRefPad->GetPosition() ); ReportWithMarker( drcItem, aRefPad->GetPosition() );
return false; return false;
@ -711,8 +710,8 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZones()
// Examine a candidate zone: compare zoneToTest to zoneRef // Examine a candidate zone: compare zoneToTest to zoneRef
// Get clearance used in zone to zone test. // Get clearance used in zone to zone test.
auto rule = m_drcEngine->EvalRulesForItems( test::DRC_RULE_ID_T::DRC_RULE_ID_CLEARANCE, zoneRef, zoneToTest ); auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE, zoneRef, zoneToTest );
auto zone2zoneClearance = rule->GetConstraint().GetValue().Min(); auto zone2zoneClearance = constraint.GetValue().Min();
// Keepout areas have no clearance, so set zone2zoneClearance to 1 // Keepout areas have no clearance, so set zone2zoneClearance to 1
// ( zone2zoneClearance = 0 can create problems in test functions) // ( zone2zoneClearance = 0 can create problems in test functions)
@ -729,7 +728,7 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZones()
{ {
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ZONES_INTERSECT ); std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ZONES_INTERSECT );
drcItem->SetItems( zoneRef, zoneToTest ); drcItem->SetItems( zoneRef, zoneToTest );
drcItem->SetViolatingRule( rule ); drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, pt ); ReportWithMarker( drcItem, pt );
} }
@ -745,7 +744,7 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZones()
{ {
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ZONES_INTERSECT ); std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ZONES_INTERSECT );
drcItem->SetItems( zoneToTest, zoneRef ); drcItem->SetItems( zoneToTest, zoneRef );
drcItem->SetViolatingRule( rule ); drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, pt ); ReportWithMarker( drcItem, pt );
} }
@ -818,7 +817,7 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZones()
} }
drcItem->SetViolatingRule( rule ); drcItem->SetViolatingRule( constraint.GetParentRule() );
drcItem->SetItems( zoneRef, zoneToTest ); drcItem->SetItems( zoneRef, zoneToTest );
ReportWithMarker( drcItem, conflict.first ); ReportWithMarker( drcItem, conflict.first );
@ -828,9 +827,9 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZones()
} }
std::set<test::DRC_RULE_ID_T> test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::GetMatchingRuleIds() const std::set<test::DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::GetMatchingConstraintIds() const
{ {
return { DRC_RULE_ID_T::DRC_RULE_ID_CLEARANCE }; return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE };
} }

View File

@ -75,7 +75,7 @@ public:
return "Tests items vs board edge clearance"; return "Tests items vs board edge clearance";
} }
virtual std::set<test::DRC_RULE_ID_T> GetMatchingRuleIds() const override; virtual std::set<test::DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
private: private:
}; };
@ -88,11 +88,14 @@ bool test::DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run()
m_board = m_drcEngine->GetBoard(); m_board = m_drcEngine->GetBoard();
DRC_CONSTRAINT worstClearanceConstraint; DRC_CONSTRAINT worstClearanceConstraint;
m_largestClearance = 0; if( m_drcEngine->QueryWorstConstraint( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE, worstClearanceConstraint, DRCCQ_LARGEST_MINIMUM ) )
if( m_drcEngine->QueryWorstConstraint( test::DRC_RULE_ID_T::DRC_RULE_ID_EDGE_CLEARANCE, worstClearanceConstraint, DRCCQ_LARGEST_MINIMUM ) )
{ {
m_largestClearance = worstClearanceConstraint.m_Value.Min(); m_largestClearance = worstClearanceConstraint.GetValue().Min();
}
else
{
ReportAux("No Clearance constraints found...");
return false;
} }
ReportAux( "Worst clearance : %d nm", m_largestClearance ); ReportAux( "Worst clearance : %d nm", m_largestClearance );
@ -104,11 +107,13 @@ bool test::DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run()
auto queryBoardOutlineItems = [&] ( BOARD_ITEM *item ) -> int auto queryBoardOutlineItems = [&] ( BOARD_ITEM *item ) -> int
{ {
boardOutline.push_back( dyn_cast<DRAWSEGMENT*>( item ) ); boardOutline.push_back( dyn_cast<DRAWSEGMENT*>( item ) );
return 0;
}; };
auto queryBoardGeometryItems = [&] ( BOARD_ITEM *item ) -> int auto queryBoardGeometryItems = [&] ( BOARD_ITEM *item ) -> int
{ {
boardItems.push_back( item ); boardItems.push_back( item );
return 0;
}; };
@ -130,8 +135,8 @@ bool test::DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run()
auto shape = boardItem->GetEffectiveShape(); auto shape = boardItem->GetEffectiveShape();
test::DRC_RULE* rule = m_drcEngine->EvalRulesForItems( test::DRC_RULE_ID_T::DRC_RULE_ID_EDGE_CLEARANCE, outlineItem, boardItem ); test::DRC_CONSTRAINT constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE, outlineItem, boardItem );
int minClearance = rule->GetConstraint().GetValue().Min(); int minClearance = constraint.GetValue().Min();
int actual; int actual;
if( refShape->Collide( shape.get(), minClearance, &actual ) ) if( refShape->Collide( shape.get(), minClearance, &actual ) )
@ -140,13 +145,13 @@ bool test::DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run()
wxString msg; wxString msg;
msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ), msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ),
rule->GetName(), constraint.GetParentRule()->GetName(),
MessageTextFromValue( userUnits(), minClearance, true ), MessageTextFromValue( userUnits(), minClearance, true ),
MessageTextFromValue( userUnits(), actual, true ) ); MessageTextFromValue( userUnits(), actual, true ) );
drcItem->SetErrorMessage( msg ); drcItem->SetErrorMessage( msg );
drcItem->SetItems( outlineItem, boardItem ); drcItem->SetItems( outlineItem, boardItem );
drcItem->SetViolatingRule( rule ); drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, refShape->Centre() ); ReportWithMarker( drcItem, refShape->Centre() );
} }
@ -157,9 +162,9 @@ bool test::DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run()
} }
std::set<test::DRC_RULE_ID_T> test::DRC_TEST_PROVIDER_EDGE_CLEARANCE::GetMatchingRuleIds() const std::set<test::DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_EDGE_CLEARANCE::GetMatchingConstraintIds() const
{ {
return { DRC_RULE_ID_T::DRC_RULE_ID_EDGE_CLEARANCE }; return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE };
} }

View File

@ -75,7 +75,7 @@ public:
return "Tests clearance of holes (via/pad drills)"; return "Tests clearance of holes (via/pad drills)";
} }
virtual std::set<test::DRC_RULE_ID_T> GetMatchingRuleIds() const override; virtual std::set<test::DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
private: private:
void addHole( const VECTOR2I& aLocation, int aRadius, BOARD_ITEM* aOwner ); void addHole( const VECTOR2I& aLocation, int aRadius, BOARD_ITEM* aOwner );
@ -110,16 +110,19 @@ bool test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::Run()
m_largestClearance = 0; m_largestClearance = 0;
m_largestRadius = 0; m_largestRadius = 0;
for( auto rule : m_drcEngine->QueryRulesById( test::DRC_RULE_ID_T::DRC_RULE_ID_HOLE_CLEARANCE ) ) DRC_CONSTRAINT worstClearanceConstraint;
if( m_drcEngine->QueryWorstConstraint( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE, worstClearanceConstraint, DRCCQ_LARGEST_MINIMUM ) )
{ {
drc_dbg(1, "process rule %p\n", rule ); m_largestClearance = worstClearanceConstraint.GetValue().Min();
if( rule->GetConstraint().m_Value.HasMin() ) }
else
{ {
drc_dbg(1, "min-hole-clearance %d\n", rule->GetConstraint().m_Value.Min() ); ReportAux("No Clearance constraints found...");
m_largestClearance = std::max( m_largestClearance, rule->GetConstraint().m_Value.Min() ); return false;
}
} }
ReportAux( "Worst hole clearance : %d nm", m_largestClearance ); ReportAux( "Worst hole clearance : %d nm", m_largestClearance );
buildHoleList(); buildHoleList();
@ -268,13 +271,13 @@ bool test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::doPadToPadHoleDrc( D_PAD* aRefPad,
{ {
// pad under testing has a hole, test this hole against pad reference // pad under testing has a hole, test this hole against pad reference
auto rule = m_drcEngine->EvalRulesForItems( test::DRC_RULE_ID_T::DRC_RULE_ID_HOLE_CLEARANCE, aRefPad, pad ); auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE, aRefPad, pad );
auto minClearance = rule->GetConstraint().GetValue().Min(); auto minClearance = constraint.GetValue().Min();
int actual; int actual;
drc_dbg(1,"check pad %p rule '%s' cl %d\n", pad, (const char*) rule->GetName().c_str(), minClearance ); drc_dbg(1,"check pad %p rule '%s' cl %d\n", pad, constraint.GetParentRule()->GetName(), minClearance );
accountCheck( rule ); accountCheck( constraint.GetParentRule() );
auto refPadShape = aRefPad->GetEffectiveShape(); auto refPadShape = aRefPad->GetEffectiveShape();
// fixme: pad stacks... // fixme: pad stacks...
@ -291,7 +294,7 @@ bool test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::doPadToPadHoleDrc( D_PAD* aRefPad,
drcItem->SetErrorMessage( msg ); drcItem->SetErrorMessage( msg );
drcItem->SetItems( pad, aRefPad ); drcItem->SetItems( pad, aRefPad );
drcItem->SetViolatingRule( rule ); drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, pad->GetPosition() ); ReportWithMarker( drcItem, pad->GetPosition() );
return false; return false;
@ -301,13 +304,13 @@ bool test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::doPadToPadHoleDrc( D_PAD* aRefPad,
if( aRefPad->GetDrillSize().x ) // pad reference has a hole if( aRefPad->GetDrillSize().x ) // pad reference has a hole
{ {
auto rule = m_drcEngine->EvalRulesForItems( test::DRC_RULE_ID_T::DRC_RULE_ID_HOLE_CLEARANCE, aRefPad, pad ); auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE, aRefPad, pad );
auto minClearance = rule->GetConstraint().GetValue().Min(); auto minClearance = constraint.GetValue().Min();
int actual; int actual;
accountCheck( rule ); accountCheck( constraint.GetParentRule() );
drc_dbg(1,"check pad %p rule '%s' cl %d\n", aRefPad, (const char*) rule->GetName().c_str(), minClearance ); drc_dbg(1,"check pad %p rule '%s' cl %d\n", constraint.GetParentRule()->GetName(), minClearance );
auto padShape = pad->GetEffectiveShape(); auto padShape = pad->GetEffectiveShape();
if( padShape->Collide( aRefPad->GetEffectiveHoleShape(), minClearance, &actual ) ) if( padShape->Collide( aRefPad->GetEffectiveHoleShape(), minClearance, &actual ) )
@ -322,7 +325,7 @@ bool test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::doPadToPadHoleDrc( D_PAD* aRefPad,
drcItem->SetErrorMessage( msg ); drcItem->SetErrorMessage( msg );
drcItem->SetItems( aRefPad, pad ); drcItem->SetItems( aRefPad, pad );
drcItem->SetViolatingRule( rule ); drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, pad->GetPosition() ); ReportWithMarker( drcItem, pad->GetPosition() );
return false; return false;
@ -386,10 +389,10 @@ void test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::testHoles2Holes()
int actual = ( checkHole.m_location - refHole.m_location ).EuclideanNorm(); int actual = ( checkHole.m_location - refHole.m_location ).EuclideanNorm();
actual = std::max( 0, actual - checkHole.m_drillRadius - refHole.m_drillRadius ); actual = std::max( 0, actual - checkHole.m_drillRadius - refHole.m_drillRadius );
DRC_RULE* rule = m_drcEngine->EvalRulesForItems( test::DRC_RULE_ID_T::DRC_RULE_ID_HOLE_CLEARANCE, refHole.m_owner, checkHole.m_owner ); DRC_CONSTRAINT constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE, refHole.m_owner, checkHole.m_owner );
int minClearance = rule->GetConstraint().GetValue().Min(); int minClearance = constraint.GetValue().Min();
accountCheck( rule ); accountCheck( constraint.GetParentRule() );
if( actual < minClearance ) if( actual < minClearance )
{ {
@ -400,7 +403,7 @@ void test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::testHoles2Holes()
MessageTextFromValue( userUnits(), minClearance, true ), MessageTextFromValue( userUnits(), minClearance, true ),
MessageTextFromValue( userUnits(), actual, true ) ); MessageTextFromValue( userUnits(), actual, true ) );
drcItem->SetViolatingRule( rule ); drcItem->SetViolatingRule( constraint.GetParentRule() );
drcItem->SetErrorMessage( msg ); drcItem->SetErrorMessage( msg );
drcItem->SetItems( refHole.m_owner, checkHole.m_owner ); drcItem->SetItems( refHole.m_owner, checkHole.m_owner );
@ -414,9 +417,9 @@ void test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::testHoles2Holes()
} }
std::set<test::DRC_RULE_ID_T> test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::GetMatchingRuleIds() const std::set<test::DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::GetMatchingConstraintIds() const
{ {
return { DRC_RULE_ID_T::DRC_RULE_ID_HOLE_CLEARANCE }; return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE };
} }

View File

@ -76,7 +76,7 @@ public:
return "Tests sizes of drilled holes (via/pad drills)"; return "Tests sizes of drilled holes (via/pad drills)";
} }
virtual std::set<test::DRC_RULE_ID_T> GetMatchingRuleIds() const override; virtual std::set<test::DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
private: private:
bool checkVia( VIA* via ); bool checkVia( VIA* via );
@ -133,10 +133,10 @@ bool test::DRC_TEST_PROVIDER_HOLE_SIZE::checkPad( D_PAD* aPad )
if( holeSize == 0 ) if( holeSize == 0 )
return true; return true;
auto rule = m_drcEngine->EvalRulesForItems( test::DRC_RULE_ID_T::DRC_RULE_ID_HOLE_SIZE, aPad ); auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_SIZE, aPad );
auto minHole = rule->GetConstraint().GetValue().Min(); auto minHole = constraint.GetValue().Min();
accountCheck( rule ); accountCheck( constraint );
if( holeSize < minHole ) if( holeSize < minHole )
{ {
@ -147,7 +147,7 @@ bool test::DRC_TEST_PROVIDER_HOLE_SIZE::checkPad( D_PAD* aPad )
MessageTextFromValue( userUnits(), minHole, true ), MessageTextFromValue( userUnits(), minHole, true ),
MessageTextFromValue( userUnits(), holeSize, true ) ); MessageTextFromValue( userUnits(), holeSize, true ) );
drcItem->SetViolatingRule( rule ); drcItem->SetViolatingRule( constraint.GetParentRule() );
drcItem->SetErrorMessage( msg ); drcItem->SetErrorMessage( msg );
drcItem->SetItems( aPad ); drcItem->SetItems( aPad );
@ -162,10 +162,10 @@ bool test::DRC_TEST_PROVIDER_HOLE_SIZE::checkPad( D_PAD* aPad )
bool test::DRC_TEST_PROVIDER_HOLE_SIZE::checkVia( VIA* via ) bool test::DRC_TEST_PROVIDER_HOLE_SIZE::checkVia( VIA* via )
{ {
auto rule = m_drcEngine->EvalRulesForItems( test::DRC_RULE_ID_T::DRC_RULE_ID_HOLE_SIZE, via ); auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_SIZE, via );
auto minHole = rule->GetConstraint().GetValue().Min(); auto minHole = constraint.GetValue().Min();
accountCheck( rule ); accountCheck( constraint );
if( via->GetDrillValue() < minHole ) if( via->GetDrillValue() < minHole )
{ {
@ -179,7 +179,7 @@ bool test::DRC_TEST_PROVIDER_HOLE_SIZE::checkVia( VIA* via )
MessageTextFromValue( userUnits(), minHole, true ), MessageTextFromValue( userUnits(), minHole, true ),
MessageTextFromValue( userUnits(), via->GetDrillValue(), true ) ); MessageTextFromValue( userUnits(), via->GetDrillValue(), true ) );
drcItem->SetViolatingRule( rule ); drcItem->SetViolatingRule( constraint.GetParentRule() );
drcItem->SetErrorMessage( msg ); drcItem->SetErrorMessage( msg );
drcItem->SetItems( via ); drcItem->SetItems( via );
@ -192,9 +192,9 @@ bool test::DRC_TEST_PROVIDER_HOLE_SIZE::checkVia( VIA* via )
} }
std::set<test::DRC_RULE_ID_T> test::DRC_TEST_PROVIDER_HOLE_SIZE::GetMatchingRuleIds() const std::set<test::DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_HOLE_SIZE::GetMatchingConstraintIds() const
{ {
return { DRC_RULE_ID_T::DRC_RULE_ID_HOLE_SIZE }; return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_SIZE };
} }

View File

@ -75,7 +75,7 @@ public:
return "Tests sizes of drilled holes (via/pad drills)"; return "Tests sizes of drilled holes (via/pad drills)";
} }
virtual std::set<test::DRC_RULE_ID_T> GetMatchingRuleIds() const override; virtual std::set<test::DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
private: private:
bool checkVia( VIA* via ); bool checkVia( VIA* via );
@ -132,7 +132,7 @@ bool test::DRC_TEST_PROVIDER_HOLE_SIZE::checkPad( D_PAD* aPad )
if( holeSize == 0 ) if( holeSize == 0 )
return true; return true;
auto rule = m_drcEngine->EvalRulesForItems( test::DRC_RULE_ID_T::DRC_RULE_ID_HOLE_SIZE, aPad ); auto rule = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_SIZE, aPad );
auto minHole = rule->GetConstraint().GetValue().Min(); auto minHole = rule->GetConstraint().GetValue().Min();
accountCheck( rule ); accountCheck( rule );
@ -161,7 +161,7 @@ bool test::DRC_TEST_PROVIDER_HOLE_SIZE::checkPad( D_PAD* aPad )
bool test::DRC_TEST_PROVIDER_HOLE_SIZE::checkVia( VIA* via ) bool test::DRC_TEST_PROVIDER_HOLE_SIZE::checkVia( VIA* via )
{ {
auto rule = m_drcEngine->EvalRulesForItems( test::DRC_RULE_ID_T::DRC_RULE_ID_HOLE_SIZE, via ); auto rule = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_SIZE, via );
auto minHole = rule->GetConstraint().GetValue().Min(); auto minHole = rule->GetConstraint().GetValue().Min();
accountCheck( rule ); accountCheck( rule );
@ -191,9 +191,9 @@ bool test::DRC_TEST_PROVIDER_HOLE_SIZE::checkVia( VIA* via )
} }
std::set<test::DRC_RULE_ID_T> test::DRC_TEST_PROVIDER_HOLE_SIZE::GetMatchingRuleIds() const std::set<test::DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_HOLE_SIZE::GetMatchingConstraintIds() const
{ {
return { DRC_RULE_ID_T::DRC_RULE_ID_HOLE_SIZE }; return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_SIZE };
} }