Iron out some wrinkles in the DRC migration.

This commit is contained in:
Jeff Young 2020-09-12 01:22:46 +01:00
parent 8ac7288696
commit 5be887a60f
5 changed files with 72 additions and 81 deletions

View File

@ -375,25 +375,64 @@ bool DRC_ENGINE::CompileRules()
} }
void DRC_ENGINE::InitEngine() bool DRC_ENGINE::LoadRules( wxFileName aPath )
{
NULL_REPORTER nullReporter;
REPORTER* reporter = m_reporter ? m_reporter : &nullReporter;
if( aPath.FileExists() )
{
m_ruleConditions.clear();
m_rules.clear();
FILE* fp = wxFopen( aPath.GetFullPath(), wxT( "rt" ) );
if( fp )
{
try
{
DRC_RULES_PARSER parser( m_board, fp, aPath.GetFullPath() );
parser.Parse( m_rules, reporter );
}
catch( PARSE_ERROR& pe )
{
// Don't leave possibly malformed stuff around for us to trip over
m_ruleConditions.clear();
m_rules.clear();
// JEY TODO
//wxSafeYield( m_editFrame );
//m_editFrame->ShowBoardSetupDialog( _( "Rules" ), pe.What(), ID_RULES_EDITOR,
// pe.lineNumber, pe.byteIndex );
return false;
}
}
}
return true;
}
void DRC_ENGINE::InitEngine( wxFileName aRulePath )
{ {
m_testProviders = DRC_TEST_PROVIDER_REGISTRY::Instance().GetTestProviders(); m_testProviders = DRC_TEST_PROVIDER_REGISTRY::Instance().GetTestProviders();
for( auto provider : m_testProviders ) for( DRC_TEST_PROVIDER* provider : m_testProviders )
{ {
ReportAux( wxString::Format( "Create DRC provider: '%s'", provider->GetName() ) ); ReportAux( wxString::Format( "Create DRC provider: '%s'", provider->GetName() ) );
provider->SetDRCEngine( this ); provider->SetDRCEngine( this );
} }
LoadRules( aRulePath );
inferLegacyRules(); inferLegacyRules();
CompileRules(); CompileRules();
} }
void DRC_ENGINE::RunTests( ) void DRC_ENGINE::RunTests( )
{ {
InitEngine();
m_drcReport = std::make_shared<DRC_REPORT>(); m_drcReport = std::make_shared<DRC_REPORT>();
for( DRC_TEST_PROVIDER* provider : m_testProviders ) for( DRC_TEST_PROVIDER* provider : m_testProviders )
@ -492,23 +531,25 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRulesForItems( DRC_CONSTRAINT_TYPE_T aConstraintI
if( rcond->conditions.size() == 0 ) // uconditional if( rcond->conditions.size() == 0 ) // uconditional
{ {
REPORT( "No condition found; rule applied." ); REPORT( _( "Unconditional constraint; rule applied." ) );
return rcond->constraint; return rcond->constraint;
} }
for( DRC_RULE_CONDITION* condition : rcond->conditions ) for( DRC_RULE_CONDITION* condition : rcond->conditions )
{ {
REPORT( wxString::Format( _( "Checking rule condition \"%s\"." ),
condition->GetExpression() ) );
bool result = condition->EvaluateFor( a, b, aLayer, aReporter ); bool result = condition->EvaluateFor( a, b, aLayer, aReporter );
REPORT( result ? _( "Rule applied." )
: _( "Condition not satisfied; rule not applied." ) );
if( result ) if( result )
{
REPORT( _( "Rule applied." ) );
return rcond->constraint; return rcond->constraint;
}
else
{
REPORT( _( "Condition not satisfied; rule not applied." ) );
REPORT( "" );
}
} }
} }

View File

@ -149,7 +149,9 @@ public:
m_reporter = aReporter; m_reporter = aReporter;
} }
void InitEngine(); bool LoadRules( wxFileName aPath );
void InitEngine( wxFileName aRulePath );
void RunTests(); void RunTests();

View File

@ -165,21 +165,20 @@ DRC_RULE_CONDITION::~DRC_RULE_CONDITION()
bool DRC_RULE_CONDITION::EvaluateFor( const BOARD_ITEM* aItemA, const BOARD_ITEM* aItemB, bool DRC_RULE_CONDITION::EvaluateFor( const BOARD_ITEM* aItemA, const BOARD_ITEM* aItemB,
PCB_LAYER_ID aLayer, REPORTER* aReporter ) PCB_LAYER_ID aLayer, REPORTER* aReporter )
{ {
#define REPORT( s ) { if( aReporter ) { aReporter->Report( s ); } }
if( GetExpression().IsEmpty() ) if( GetExpression().IsEmpty() )
{ {
if( aReporter ) REPORT( _( "Unconditional constraint." ) );
aReporter->Report( _( "Unconditional constraint." ) );
return true; return true;
} }
if( aReporter ) REPORT( _( "Checking rule condition \"" + GetExpression() + "\"." ) );
aReporter->Report( _( "Evaluating expression \"" + GetExpression() + "\"." ) );
if( !m_ucode ) if( !m_ucode )
{ {
if( aReporter ) REPORT( _( "ERROR in expression." ) );
aReporter->Report( _( "ERROR in expression." ) );
return false; return false;
} }
@ -191,8 +190,7 @@ bool DRC_RULE_CONDITION::EvaluateFor( const BOARD_ITEM* aItemA, const BOARD_ITEM
ctx.SetItems( a, b ); ctx.SetItems( a, b );
ctx.SetErrorCallback( [&]( const wxString& aMessage, int aOffset ) ctx.SetErrorCallback( [&]( const wxString& aMessage, int aOffset )
{ {
if( aReporter ) REPORT( _( "ERROR: " ) + aMessage );
aReporter->Report( _( "ERROR: " ) + aMessage );
} ); } );
return m_ucode->Run( &ctx )->AsDouble() != 0.0; return m_ucode->Run( &ctx )->AsDouble() != 0.0;

View File

@ -183,14 +183,13 @@ void PCB_INSPECTION_TOOL::reportZoneConnection( ZONE_CONTAINER* aZone, D_PAD* aP
void PCB_INSPECTION_TOOL::reportCopperClearance( PCB_LAYER_ID aLayer, BOARD_CONNECTED_ITEM* aA, void PCB_INSPECTION_TOOL::reportCopperClearance( PCB_LAYER_ID aLayer, BOARD_CONNECTED_ITEM* aA,
BOARD_ITEM* aB, REPORTER* r ) BOARD_ITEM* aB, REPORTER* r )
{ {
wxString source;
r->Report( "" ); r->Report( "" );
DRC_ENGINE drcEngine( m_frame->GetBoard(), &m_frame->GetBoard()->GetDesignSettings() ); DRC_ENGINE drcEngine( m_frame->GetBoard(), &m_frame->GetBoard()->GetDesignSettings() );
drcEngine.InitEngine(); drcEngine.InitEngine( m_frame->Prj().AbsolutePath( "drc-rules" ) );
auto constraint = drcEngine.EvalRulesForItems( DRC_CONSTRAINT_TYPE_CLEARANCE, aA, aB, aLayer ); auto constraint = drcEngine.EvalRulesForItems( DRC_CONSTRAINT_TYPE_CLEARANCE, aA, aB,
aLayer, r );
if( r ) if( r )
{ {

View File

@ -184,57 +184,11 @@ PROJECT_CONTEXT loadKicadProject( wxString filename )
} }
class TEST_DRC_ENGINE : public DRC_ENGINE
{
public:
TEST_DRC_ENGINE( BOARD* aBoard, BOARD_DESIGN_SETTINGS* aSettings ) :
DRC_ENGINE( aBoard, aSettings )
{ }
bool LoadRules( wxFileName aPath )
{
if( aPath.FileExists() )
{
m_ruleConditions.clear();
m_rules.clear();
FILE* fp = wxFopen( aPath.GetFullPath(), wxT( "rt" ) );
if( fp )
{
try
{
DRC_RULES_PARSER parser( m_board, fp, aPath.GetFullPath() );
parser.Parse( m_rules, nullptr );
}
catch( PARSE_ERROR& pe )
{
// Don't leave possibly malformed stuff around for us to trip over
m_ruleConditions.clear();
m_rules.clear();
//wxSafeYield( m_editFrame );
//m_editFrame->ShowBoardSetupDialog( _( "Rules" ), pe.What(), ID_RULES_EDITOR,
// pe.lineNumber, pe.byteIndex );
throw;
return false;
}
}
}
return true;
}
};
int main( int argc, char *argv[] ) int main( int argc, char *argv[] )
{ {
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance(); PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
propMgr.Rebuild(); propMgr.Rebuild();
if( argc < 2 ) if( argc < 2 )
{ {
printf("usage: %s board_file.kicad_pcb [drc-rules-file]\n", argv[0] ); printf("usage: %s board_file.kicad_pcb [drc-rules-file]\n", argv[0] );
@ -245,24 +199,21 @@ int main( int argc, char *argv[] )
TEST_DRC_ENGINE drcEngine( project.board.get(), &project.board->GetDesignSettings() ); DRC_ENGINE drcEngine( project.board.get(), &project.board->GetDesignSettings() );
CONSOLE_LOG consoleLog; CONSOLE_LOG consoleLog;
drcEngine.SetLogReporter( new CONSOLE_MSG_REPORTER ( &consoleLog ) ); drcEngine.SetLogReporter( new CONSOLE_MSG_REPORTER ( &consoleLog ) );
drcEngine.SetProgressReporter( new CONSOLE_PROGRESS_REPORTER ( &consoleLog ) ); drcEngine.SetProgressReporter( new CONSOLE_PROGRESS_REPORTER ( &consoleLog ) );
wxString rulesFilepath;
if( argc > 2 ) if( argc > 2 )
{ rulesFilepath = wxString( argv[2] );
try else
{ rulesFilepath = project.project->AbsolutePath( "drc-rules" );
drcEngine.LoadRules( wxString( argv[2] ) );
} drcEngine.InitEngine( rulesFilepath );
catch( PARSE_ERROR& err )
{
return -1;
}
}
drcEngine.RunTests(); drcEngine.RunTests();
auto report = drcEngine.GetReport(); auto report = drcEngine.GetReport();