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() );
int minClearance;
DRC_RULE* rule = GetRule( aRefSeg, &dummypad, DRC_RULE_ID_CLEARANCE );
DRC_RULE* rule = GetRule( aRefSeg, &dummypad, DRC_CONSTRAINT_TYPE_CLEARANCE );
if( rule )
{

View File

@ -93,7 +93,7 @@ bool DRC_DRILLED_HOLE_TESTER::checkPad( D_PAD* aPad )
{
int minHole = bds.m_MinThroughDrill;
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 )
{
@ -136,7 +136,7 @@ bool DRC_DRILLED_HOLE_TESTER::checkVia( VIA* via )
{
int minHole = bds.m_MinThroughDrill;
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 )
{
@ -179,7 +179,7 @@ bool DRC_DRILLED_HOLE_TESTER::checkMicroVia( VIA* via )
{
int minHole = bds.m_MicroViasMinDrill;
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 )
{

View File

@ -85,7 +85,7 @@ bool test::DRC_ENGINE::LoadRules( wxFileName aPath )
try
{
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 )
{
@ -126,47 +126,42 @@ bool test::DRC_ENGINE::CompileRules()
{
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() )
m_ruleMap[id] = new RULE_SET;
m_ruleMap[ id ]->provider = provider;
m_ruleMap[ id ]->defaultRule = nullptr;
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( ) );
if( rule->GetTestProviderName() == provider->GetName() )
{
ReportAux( wxString::Format( " |- Rule: '%s' ", rule->m_Name.c_str() ) );
drc_dbg(10, "Scan provider %s rule %s", provider->GetName() );
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;
if( rule->GetPriority() == 0 )
{
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() )
if( rule->IsConditional() )
{
test::DRC_RULE_CONDITION* condition = rule->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;
m_ruleMap[ id ]->sortedRules.push_back( rcons );
}
}
}
}
}
}
@ -197,7 +192,7 @@ void test::DRC_ENGINE::RunTests( )
{
bool skipProvider = false;
for( auto ruleID : provider->GetMatchingRuleIds() )
for( auto ruleID : provider->GetMatchingConstraintIds() )
{
if( !HasCorrectRulesForId( ruleID ) )
{
@ -210,44 +205,41 @@ void test::DRC_ENGINE::RunTests( )
if( skipProvider )
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() ) );
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;
auto ruleset = m_ruleMap[ ruleID ];
auto ruleset = m_ruleMap[ aConstraintId ];
for( auto rcond : ruleset->sortedRules )
{
for( auto condition : rcond->conditions )
{
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 )
{
drc_dbg( 8, " -> rule '%s' matches, triggered by condition '%s'\n",
(const char*) rcond->rule->m_Name.c_str(),
(const char*) condition->m_Expression.c_str() );
return rcond->rule;
}
}
}
if( ruleset->defaultRule )
rcond->rule->GetName(),
condition->GetExpression() );
for( const DRC_CONSTRAINT& c : rcond->rule->Constraints() )
{
drc_dbg(8, " -> default rule '%s' matches\n", (const char*) ruleset->defaultRule->m_Name.c_str() );
return ruleset->defaultRule;
if( c.GetType() == aConstraintId )
return c;
}
}
}
}
assert(false); // should never hapen
return nullptr;
}
@ -299,7 +291,7 @@ void test::DRC_ENGINE::ReportStage ( const wxString& aStageName, int index, int
}
#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;
@ -318,48 +310,45 @@ test::DRC_CONSTRAINT test::DRC_ENGINE::GetWorstGlobalConstraint( test::DRC_RULE_
}
#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;
assert( dr );
rv.push_back( dr );
for( auto rule : m_ruleMap[ruleID]->sortedRules )
for( auto rule : m_ruleMap[constraintID]->sortedRules )
{
assert( 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;
}
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 )
{
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 )
{
worst = current;
aConstraint = rule->GetConstraint();
aConstraint = constraint;
}
}
}

View File

@ -178,17 +178,18 @@ public:
{
return m_designSettings;
}
BOARD* GetBoard() const
{
return m_board;
}
DRC_RULE* EvalRulesForItems(
DRC_RULE_ID_T ruleID, BOARD_ITEM* a, BOARD_ITEM* b = nullptr );
const DRC_CONSTRAINT& EvalRulesForItems(
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
{
@ -204,7 +205,7 @@ public:
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:
@ -216,16 +217,16 @@ private:
{
std::vector<test::DRC_RULE_CONDITION*> conditions;
test::DRC_RULE* rule;
std::vector<test::DRC_CONSTRAINT> constraints;
};
struct RULE_SET
{
std::vector<RULE_WITH_CONDITIONS*> sortedRules;
DRC_RULE* defaultRule;
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();

View File

@ -58,7 +58,7 @@ public:
virtual const wxString GetName() 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

View File

@ -33,9 +33,9 @@
test::DRC_RULE::DRC_RULE() :
m_Unary( false ),
m_Enabled( true ),
m_Conditional( false ),
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()
{
@ -53,7 +57,6 @@ 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 )
{
// An unconditional rule is always true
if( m_Expression.IsEmpty() )
if( m_expression.IsEmpty() )
return true;
// 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;
if (!m_ucode)
m_ucode = new PCB_EXPR_UCODE;
m_ucode.reset( new PCB_EXPR_UCODE );
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;
}

View File

@ -42,18 +42,39 @@ class PCB_EXPR_UCODE;
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_RULE_ID_CLEARANCE = 0,
DRC_RULE_ID_HOLE_CLEARANCE,
DRC_RULE_ID_EDGE_CLEARANCE,
DRC_RULE_ID_HOLE_SIZE,
DRC_RULE_ID_COURTYARD_CLEARANCE,
DRC_RULE_ID_SILK_TO_PAD
DRC_CONSTRAINT_TYPE_UNKNOWN = -1,
DRC_CONSTRAINT_TYPE_CLEARANCE = 0,
DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE,
DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE,
DRC_CONSTRAINT_TYPE_HOLE_SIZE,
DRC_CONSTRAINT_TYPE_COURTYARD_CLEARANCE,
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_WARNING,
@ -89,21 +110,30 @@ class DRC_CONSTRAINT
{
public:
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_LayerCondition( LSET::AllLayersMask() )
m_LayerCondition( LSET::AllLayersMask() ),
m_parentRule( nullptr ) // fixme
{
}
const MINOPTMAX<int>& GetValue() const { return m_Value; }
MINOPTMAX<int>& Value() { return m_Value; }
// fixme: needed?
bool Allowed() const { return m_Allow; }
DRC_RULE* GetParentRule() const { return m_parentRule; }
DRC_CONSTRAINT_TYPE_T GetType() const { return m_Type; }
public:
DRC_RULE_ID_T m_Type;
MINOPTMAX<int> m_Value;
DRC_CONSTRAINT_TYPE_T m_Type;
int m_DisallowFlags;
LSET m_LayerCondition;
private:
DRC_RULE *m_parentRule;
MINOPTMAX<int> m_Value;
bool m_Allow;
};
@ -124,22 +154,44 @@ public:
DRC_RULE_SEVERITY_T GetSeverity() const { return m_Severity; }
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:
bool m_Unary;
wxString m_Name;
LSET m_LayerCondition;
wxString m_TestProviderName;
DRC_RULE_CONDITION m_Condition;
std::vector<DRC_CONSTRAINT> m_Constraints;
LSET m_layerCondition;
DRC_RULE_CONDITION* m_condition; // fixme: consider unique_ptr
std::vector<DRC_CONSTRAINT> m_constraints;
DRC_RULE_SEVERITY_T m_Severity;
bool m_Enabled;
bool m_Conditional;
int m_Priority; // 0 indicates automatic priority generation
};
@ -150,16 +202,30 @@ public:
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 );
public:
LSET m_LayerCondition;
wxString m_Expression;
wxString m_TargetRuleName;
void SetLayerCondition( LSET aLayerCondition )
{
m_layerCondition = aLayerCondition;
}
void SetExpression( const wxString& aExpression )
{
m_expression = aExpression;
}
const wxString& GetExpression() const
{
return m_expression;
}
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_parser.h>
#include <drc_proto/drc_rules_lexer.h>
#include <drc_rules_lexer.h>
#include <drc_proto/drc_engine.h> // drc_dbg
#include <pcb_expr_evaluator.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 )
: DRC_RULES_PROTO_LEXER( aFile, aFilename ),
test::DRC_RULES_PARSER::DRC_RULES_PARSER( BOARD* aBoard, const wxString& aSource,
const wxString& aSourceDescr ) :
DRC_RULES_LEXER( aSource.ToStdString(), aSourceDescr ),
m_board( aBoard ),
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,
std::vector<test::DRC_RULE*>& aRules,
REPORTER* aReporter )
void test::DRC_RULES_PARSER::Parse( std::vector<DRC_RULE*>& aRules, REPORTER* aReporter )
{
bool haveVersion = false;
wxString msg;
@ -131,86 +141,36 @@ void test::DRC_RULES_PARSER::Parse( std::vector<test::DRC_RULE_CONDITION*>& aCon
break;
case T_condition:
aConditions.push_back( parseCONDITION() );
break;
case T_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 );
aRules.push_back( parseDRC_RULE() );
break;
}
default:
msg.Printf( _( "Unrecognized item '%s'.| Expected 'rule', 'condition' or 'version'." ),
FromUTF8() );
msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ),
FromUTF8(), "'rule', 'version'" );
reportError( msg );
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_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()
test::DRC_RULE* test::DRC_RULES_PARSER::parseDRC_RULE()
{
DRC_RULE* rule = new DRC_RULE();
T token = NextTok();
int value;
wxString msg;
if( !IsSymbol( token ) )
reportError( _( "Missing rule name." ) );
rule->m_Priority = 0;
rule->m_Enabled = true;
rule->m_Name = FromUTF8();
printf("parseRule '%s'\n", (const char *) rule->m_Name.c_str() );
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
if( token != T_LEFT )
@ -218,18 +178,139 @@ test::DRC_RULE* test::DRC_RULES_PARSER::parseRULE()
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 )
{
case T_type:
// TODO: I assume this won't be in the final impl and so doesn't need converting
// to new error reporting framework?
NeedSYMBOL();
rule->m_TestProviderName = FromUTF8();
NeedRIGHT();
break;
case T_clearance: constraint.m_Type = test::DRC_CONSTRAINT_TYPE_CLEARANCE; break;
case T_hole_clearance: constraint.m_Type = test::DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE; break;
case T_edge_clearance: constraint.m_Type = test::DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE; break;
case T_hole: constraint.m_Type = test::DRC_CONSTRAINT_TYPE_HOLE_SIZE; break;
case T_courtyard_clearance: constraint.m_Type = test::DRC_CONSTRAINT_TYPE_COURTYARD_CLEARANCE; break;
case T_silk_to_pad: constraint.m_Type = test::DRC_CONSTRAINT_TYPE_SILK_TO_PAD; 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:
token = NextTok();
@ -240,27 +321,7 @@ test::DRC_RULE* test::DRC_RULES_PARSER::parseRULE()
}
parseValueWithUnits( FromUTF8(), value );
rule->m_Constraint.m_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 );
constraint.Value().SetMin( value );
if( (int) NextTok() != DSN_RIGHT )
{
@ -280,7 +341,7 @@ test::DRC_RULE* test::DRC_RULES_PARSER::parseRULE()
}
parseValueWithUnits( FromUTF8(), value );
rule->m_Constraint.m_Value.SetMax( value );
constraint.Value().SetMax( value );
if( (int) NextTok() != DSN_RIGHT )
{
@ -290,10 +351,27 @@ test::DRC_RULE* test::DRC_RULES_PARSER::parseRULE()
break;
case T_allow:
rule->m_Constraint.m_Allow = parseInt("allowed");
NeedRIGHT();
case T_opt:
token = NextTok();
if( (int) token == DSN_RIGHT )
{
reportError( _( "Missing opt value." ) );
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:
rule->m_Enabled = parseInt("enabled");
@ -315,30 +393,17 @@ test::DRC_RULE* test::DRC_RULES_PARSER::parseRULE()
break;
case T_priority:
rule->m_Priority = parseInt("priotity");
NeedRIGHT();
break;
*/
default:
// TODO: reconcile
//Expecting( "type, min, opt, max, allow, enable, priority or severity" );
msg.Printf( _( "Unrecognized item '%s'.| Expected 'min', 'max' or 'opt'." ),
FromUTF8() );
msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ),
FromUTF8(), "'min', 'max', 'opt'" );
reportError( msg );
parseUnknown();
break;
}
}
}
}
return rule;
}
void test::DRC_RULES_PARSER::parseValueWithUnits( const wxString& aExpr, int& aResult )
{

View File

@ -28,7 +28,8 @@
#include <netclass.h>
#include <layers_id_colors_and_visibility.h>
#include <drc_proto/drc_rule.h>
#include <drc_rules_proto_lexer.h>
#include <drc_rules_lexer.h>
class BOARD_ITEM;
@ -40,40 +41,25 @@ class DRC_RULE;
#define DRC_RULE_FILE_VERSION 20200610
class DRC_RULES_PARSER : public DRC_RULES_PROTO_LEXER
class DRC_RULES_PARSER : public DRC_RULES_LEXER
{
public:
DRC_RULES_PARSER( BOARD* aBoard, const wxString& aSource, const wxString& aSourceDescr );
DRC_RULES_PARSER( BOARD* aBoard, FILE* aFile, const wxString& aFilename );
void Parse( std::vector<DRC_RULE_CONDITION*>& aConditions, std::vector<DRC_RULE*>& aRules,
REPORTER* aReporter );
void Parse( std::vector<DRC_RULE*>& aRules, REPORTER* aReporter );
private:
DRC_RULE_CONDITION* parseCONDITION();
DRC_RULE* parseRULE();
DRC_RULE* parseDRC_RULE();
void parseConstraint( DRC_RULE* aRule );
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();
void parseUnknown();
void reportError( const wxString& aMessage );
// void parseConstraint( DRC_RULE* aRule );
//int parseValue( DRCRULE_T::T aToken );
private:
BOARD* m_board;
int m_requiredVersion;
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();
}
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 );
if( it == m_stats.end() )
@ -84,6 +84,12 @@ void test::DRC_TEST_PROVIDER::accountCheck( test::DRC_RULE* ruleToTest )
it->second++;
}
void test::DRC_TEST_PROVIDER::accountCheck( const test::DRC_CONSTRAINT& constraintToTest )
{
accountCheck( constraintToTest.GetParentRule() );
}
void test::DRC_TEST_PROVIDER::reportRuleStatistics()
{
m_drcEngine->ReportAux("Rule hit statistics: ");

View File

@ -104,19 +104,20 @@ public:
virtual void ReportProgress( double aProgress );
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:
int forEachGeometryItem( const std::vector<KICAD_T> aTypes, const LSET aLayers, std::function<int(BOARD_ITEM*)> aFunc );
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 );
EDA_UNITS userUnits() const;
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;
};

View File

@ -76,7 +76,7 @@ public:
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:
void testPadClearances();
@ -96,17 +96,16 @@ bool test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::Run()
{
auto bds = m_drcEngine->GetDesignSettings();
m_board = m_drcEngine->GetBoard();
DRC_CONSTRAINT worstClearanceConstraint;
m_largestClearance = 0;
for( auto rule : m_drcEngine->QueryRulesById( test::DRC_RULE_ID_T::DRC_RULE_ID_CLEARANCE ) )
if( m_drcEngine->QueryWorstConstraint( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE, worstClearanceConstraint, DRCCQ_LARGEST_MINIMUM ) )
{
drc_dbg(1, "process rule %p\n", rule );
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() );
m_largestClearance = worstClearanceConstraint.GetValue().Min();
}
else
{
ReportAux("No Clearance constraints found...");
return false;
}
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() ) )
continue;
auto rule = m_drcEngine->EvalRulesForItems( test::DRC_RULE_ID_T::DRC_RULE_ID_CLEARANCE, aItem, track );
auto minClearance = rule->GetConstraint().GetValue().Min();
auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE, aItem, track, aItem->GetLayer() );
auto minClearance = constraint.GetValue().Min();
int actual = INT_MAX;
wxPoint pos;
@ -220,13 +219,13 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::testCopperDrawItem( BOARD_ITEM* a
wxString msg;
msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ),
rule->GetName(),
constraint.GetParentRule()->GetName(),
MessageTextFromValue( userUnits(), minClearance, true ),
MessageTextFromValue( userUnits(), actual, true ) );
drcItem->SetErrorMessage( msg );
drcItem->SetItems( track, aItem );
drcItem->SetViolatingRule( rule );
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, pos );
}
@ -242,8 +241,8 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::testCopperDrawItem( BOARD_ITEM* a
if( drawItem && pad->GetParent() == drawItem->GetParent() )
continue;
auto rule = m_drcEngine->EvalRulesForItems( test::DRC_RULE_ID_T::DRC_RULE_ID_CLEARANCE, aItem, pad );
auto minClearance = rule->GetConstraint().GetValue().Min();
auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE, aItem, pad );
auto minClearance = constraint.GetValue().Min();
int actual = INT_MAX;
@ -265,13 +264,13 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::testCopperDrawItem( BOARD_ITEM* a
wxString msg;
msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ),
rule->GetName(),
constraint.GetParentRule()->GetName(),
MessageTextFromValue( userUnits(), minClearance, true ),
MessageTextFromValue( userUnits(), actual, true ) );
drcItem->SetErrorMessage( msg );
drcItem->SetItems( pad, aItem );
drcItem->SetViolatingRule( rule );
drcItem->SetViolatingRule( constraint.GetParentRule() );
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
auto rule = m_drcEngine->EvalRulesForItems( test::DRC_RULE_ID_T::DRC_RULE_ID_CLEARANCE, aRefSeg, pad );
auto minClearance = rule->GetConstraint().GetValue().Min();
auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE, aRefSeg, pad );
auto minClearance = constraint.GetValue().Min();
int clearanceAllowed = minClearance - bds.GetDRCEpsilon();
int actual;
@ -374,7 +373,7 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, TRACK
drcItem->SetErrorMessage( msg );
drcItem->SetItems( aRefSeg, pad );
drcItem->SetViolatingRule( rule );
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, pad->GetPosition() );
@ -427,8 +426,8 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, TRACK
if( !trackBB.Intersects( refSegBB ) )
continue;
auto rule = m_drcEngine->EvalRulesForItems( test::DRC_RULE_ID_T::DRC_RULE_ID_CLEARANCE, aRefSeg, track );
auto minClearance = rule->GetConstraint().GetValue().Min();
auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE, aRefSeg, track );
auto minClearance = constraint.GetValue().Min();
SHAPE_SEGMENT trackSeg( track->GetStart(), track->GetEnd(), track->GetWidth() );
int actual;
@ -440,7 +439,7 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, TRACK
// fixme
drcItem->SetErrorMessage( "FIXME" );
drcItem->SetItems( aRefSeg, track );
drcItem->SetViolatingRule( rule );
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, (wxPoint) intersection.get() );
@ -461,7 +460,7 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, TRACK
drcItem->SetErrorMessage( msg );
drcItem->SetItems( aRefSeg, track );
drcItem->SetViolatingRule( rule );
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, pos );
@ -493,8 +492,8 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, TRACK
// fixme: per-layer onLayer() property
auto rule = m_drcEngine->EvalRulesForItems( test::DRC_RULE_ID_T::DRC_RULE_ID_CLEARANCE, aRefSeg, zone );
auto minClearance = rule->GetConstraint().GetValue().Min();
auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE, aRefSeg, zone );
auto minClearance = constraint.GetValue().Min();
int widths = refSegWidth / 2;
// 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;
msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ),
rule->GetName(),
constraint.GetParentRule()->GetName(),
MessageTextFromValue( userUnits(), minClearance, true ),
MessageTextFromValue( userUnits(), actual, true ) );
drcItem->SetErrorMessage( msg );
drcItem->SetItems( aRefSeg, zone );
drcItem->SetViolatingRule( rule );
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, getLocation( aRefSeg, zone ) );
}
@ -628,8 +627,8 @@ bool test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::doPadToPadsDrc( D_PAD* aRefPad, D
continue;
}
auto rule = m_drcEngine->EvalRulesForItems( test::DRC_RULE_ID_T::DRC_RULE_ID_CLEARANCE, aRefPad, pad );
auto minClearance = rule->GetConstraint().GetValue().Min();
auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE, aRefPad, pad );
auto minClearance = constraint.GetValue().Min();
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->SetItems( aRefPad, pad );
drcItem->SetViolatingRule( rule );
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, aRefPad->GetPosition() );
return false;
@ -711,8 +710,8 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZones()
// Examine a candidate zone: compare zoneToTest to zoneRef
// 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 zone2zoneClearance = rule->GetConstraint().GetValue().Min();
auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE, zoneRef, zoneToTest );
auto zone2zoneClearance = constraint.GetValue().Min();
// Keepout areas have no clearance, so set zone2zoneClearance to 1
// ( 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 );
drcItem->SetItems( zoneRef, zoneToTest );
drcItem->SetViolatingRule( rule );
drcItem->SetViolatingRule( constraint.GetParentRule() );
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 );
drcItem->SetItems( zoneToTest, zoneRef );
drcItem->SetViolatingRule( rule );
drcItem->SetViolatingRule( constraint.GetParentRule() );
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 );
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";
}
virtual std::set<test::DRC_RULE_ID_T> GetMatchingRuleIds() const override;
virtual std::set<test::DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
private:
};
@ -88,11 +88,14 @@ bool test::DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run()
m_board = m_drcEngine->GetBoard();
DRC_CONSTRAINT worstClearanceConstraint;
m_largestClearance = 0;
if( m_drcEngine->QueryWorstConstraint( test::DRC_RULE_ID_T::DRC_RULE_ID_EDGE_CLEARANCE, worstClearanceConstraint, DRCCQ_LARGEST_MINIMUM ) )
if( m_drcEngine->QueryWorstConstraint( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_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 );
@ -104,11 +107,13 @@ bool test::DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run()
auto queryBoardOutlineItems = [&] ( BOARD_ITEM *item ) -> int
{
boardOutline.push_back( dyn_cast<DRAWSEGMENT*>( item ) );
return 0;
};
auto queryBoardGeometryItems = [&] ( BOARD_ITEM *item ) -> int
{
boardItems.push_back( item );
return 0;
};
@ -130,8 +135,8 @@ bool test::DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run()
auto shape = boardItem->GetEffectiveShape();
test::DRC_RULE* rule = m_drcEngine->EvalRulesForItems( test::DRC_RULE_ID_T::DRC_RULE_ID_EDGE_CLEARANCE, outlineItem, boardItem );
int minClearance = rule->GetConstraint().GetValue().Min();
test::DRC_CONSTRAINT constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE, outlineItem, boardItem );
int minClearance = constraint.GetValue().Min();
int actual;
if( refShape->Collide( shape.get(), minClearance, &actual ) )
@ -140,13 +145,13 @@ bool test::DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run()
wxString msg;
msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ),
rule->GetName(),
constraint.GetParentRule()->GetName(),
MessageTextFromValue( userUnits(), minClearance, true ),
MessageTextFromValue( userUnits(), actual, true ) );
drcItem->SetErrorMessage( msg );
drcItem->SetItems( outlineItem, boardItem );
drcItem->SetViolatingRule( rule );
drcItem->SetViolatingRule( constraint.GetParentRule() );
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)";
}
virtual std::set<test::DRC_RULE_ID_T> GetMatchingRuleIds() const override;
virtual std::set<test::DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
private:
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_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 );
if( rule->GetConstraint().m_Value.HasMin() )
m_largestClearance = worstClearanceConstraint.GetValue().Min();
}
else
{
drc_dbg(1, "min-hole-clearance %d\n", rule->GetConstraint().m_Value.Min() );
m_largestClearance = std::max( m_largestClearance, rule->GetConstraint().m_Value.Min() );
}
ReportAux("No Clearance constraints found...");
return false;
}
ReportAux( "Worst hole clearance : %d nm", m_largestClearance );
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
auto rule = m_drcEngine->EvalRulesForItems( test::DRC_RULE_ID_T::DRC_RULE_ID_HOLE_CLEARANCE, aRefPad, pad );
auto minClearance = rule->GetConstraint().GetValue().Min();
auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE, aRefPad, pad );
auto minClearance = constraint.GetValue().Min();
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();
// fixme: pad stacks...
@ -291,7 +294,7 @@ bool test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::doPadToPadHoleDrc( D_PAD* aRefPad,
drcItem->SetErrorMessage( msg );
drcItem->SetItems( pad, aRefPad );
drcItem->SetViolatingRule( rule );
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, pad->GetPosition() );
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
{
auto rule = m_drcEngine->EvalRulesForItems( test::DRC_RULE_ID_T::DRC_RULE_ID_HOLE_CLEARANCE, aRefPad, pad );
auto minClearance = rule->GetConstraint().GetValue().Min();
auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE, aRefPad, pad );
auto minClearance = constraint.GetValue().Min();
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();
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->SetItems( aRefPad, pad );
drcItem->SetViolatingRule( rule );
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, pad->GetPosition() );
return false;
@ -386,10 +389,10 @@ void test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::testHoles2Holes()
int actual = ( checkHole.m_location - refHole.m_location ).EuclideanNorm();
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 );
int minClearance = rule->GetConstraint().GetValue().Min();
DRC_CONSTRAINT constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE, refHole.m_owner, checkHole.m_owner );
int minClearance = constraint.GetValue().Min();
accountCheck( rule );
accountCheck( constraint.GetParentRule() );
if( actual < minClearance )
{
@ -400,7 +403,7 @@ void test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::testHoles2Holes()
MessageTextFromValue( userUnits(), minClearance, true ),
MessageTextFromValue( userUnits(), actual, true ) );
drcItem->SetViolatingRule( rule );
drcItem->SetViolatingRule( constraint.GetParentRule() );
drcItem->SetErrorMessage( msg );
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)";
}
virtual std::set<test::DRC_RULE_ID_T> GetMatchingRuleIds() const override;
virtual std::set<test::DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
private:
bool checkVia( VIA* via );
@ -133,10 +133,10 @@ bool test::DRC_TEST_PROVIDER_HOLE_SIZE::checkPad( D_PAD* aPad )
if( holeSize == 0 )
return true;
auto rule = m_drcEngine->EvalRulesForItems( test::DRC_RULE_ID_T::DRC_RULE_ID_HOLE_SIZE, aPad );
auto minHole = rule->GetConstraint().GetValue().Min();
auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_SIZE, aPad );
auto minHole = constraint.GetValue().Min();
accountCheck( rule );
accountCheck( constraint );
if( holeSize < minHole )
{
@ -147,7 +147,7 @@ bool test::DRC_TEST_PROVIDER_HOLE_SIZE::checkPad( D_PAD* aPad )
MessageTextFromValue( userUnits(), minHole, true ),
MessageTextFromValue( userUnits(), holeSize, true ) );
drcItem->SetViolatingRule( rule );
drcItem->SetViolatingRule( constraint.GetParentRule() );
drcItem->SetErrorMessage( msg );
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 )
{
auto rule = m_drcEngine->EvalRulesForItems( test::DRC_RULE_ID_T::DRC_RULE_ID_HOLE_SIZE, via );
auto minHole = rule->GetConstraint().GetValue().Min();
auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_SIZE, via );
auto minHole = constraint.GetValue().Min();
accountCheck( rule );
accountCheck( constraint );
if( via->GetDrillValue() < minHole )
{
@ -179,7 +179,7 @@ bool test::DRC_TEST_PROVIDER_HOLE_SIZE::checkVia( VIA* via )
MessageTextFromValue( userUnits(), minHole, true ),
MessageTextFromValue( userUnits(), via->GetDrillValue(), true ) );
drcItem->SetViolatingRule( rule );
drcItem->SetViolatingRule( constraint.GetParentRule() );
drcItem->SetErrorMessage( msg );
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)";
}
virtual std::set<test::DRC_RULE_ID_T> GetMatchingRuleIds() const override;
virtual std::set<test::DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
private:
bool checkVia( VIA* via );
@ -132,7 +132,7 @@ bool test::DRC_TEST_PROVIDER_HOLE_SIZE::checkPad( D_PAD* aPad )
if( holeSize == 0 )
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();
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 )
{
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();
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 };
}