drc_proto: update file format, get the thing to compile again
This commit is contained in:
parent
8b716b2b5c
commit
e0ffdc8fe7
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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_
|
|
@ -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: ");
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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 };
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 };
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 };
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 };
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 };
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue