Better error messages for rule parsing.

This commit is contained in:
Jeff Young 2020-05-16 20:12:56 +01:00
parent f2e003147e
commit 5b07889347
3 changed files with 61 additions and 30 deletions

View File

@ -61,7 +61,8 @@ DRC::DRC() :
PCB_TOOL_BASE( "pcbnew.DRCTool" ),
m_pcbEditorFrame( nullptr ),
m_pcb( nullptr ),
m_drcDialog( nullptr )
m_drcDialog( nullptr ),
m_rulesFileLastMod( 0 )
{
// establish initial values for everything:
m_doPad2PadTest = true; // enable pad to pad clearance tests
@ -98,7 +99,7 @@ void DRC::Reset( RESET_REASON aReason )
m_pcb = m_pcbEditorFrame->GetBoard();
readRules();
loadRules();
}
}
@ -354,35 +355,51 @@ int DRC::TestZoneToZoneOutlines()
}
void DRC::readRules()
void DRC::loadRules()
{
wxString rulesFilepath = m_pcbEditorFrame->Prj().AbsolutePath( "drc-rules" );
wxString rulesFilepath = m_pcbEditorFrame->Prj().AbsolutePath( "drc-rules" );
wxFileName rulesFile( rulesFilepath );
BOARD_DESIGN_SETTINGS& bds = m_pcb->GetDesignSettings();
bds.m_DRCRuleSelectors.clear();
bds.m_DRCRules.clear();
FILE* fp = wxFopen( rulesFilepath, wxT( "rt" ) );
if( fp )
if( rulesFile.FileExists() )
{
try
wxLongLong lastMod = rulesFile.GetModificationTime().GetValue();
if( lastMod > m_rulesFileLastMod )
{
DRC_RULES_PARSER parser( m_pcb, fp, rulesFilepath );
parser.Parse( bds.m_DRCRuleSelectors, bds.m_DRCRules );
}
catch( PARSE_ERROR& pe )
{
DisplayError( m_drcDialog, pe.What() );
m_rulesFileLastMod = lastMod;
m_ruleSelectors.clear();
m_rules.clear();
FILE* fp = wxFopen( rulesFilepath, wxT( "rt" ) );
if( fp )
{
try
{
DRC_RULES_PARSER parser( m_pcb, fp, rulesFilepath );
parser.Parse( m_ruleSelectors, m_rules );
}
catch( PARSE_ERROR& pe )
{
// Don't leave possibly malformed stuff around for us to trip over
m_ruleSelectors.clear();
m_rules.clear();
DisplayError( m_drcDialog, pe.What() );
}
}
}
}
BOARD_DESIGN_SETTINGS& bds = m_pcb->GetDesignSettings();
bds.m_DRCRuleSelectors = m_ruleSelectors;
bds.m_DRCRules = m_rules;
}
void DRC::RunTests( wxTextCtrl* aMessages )
{
// TODO: timestamp file and read only if newer
readRules();
loadRules();
// be sure m_pcb is the current board, not a old one
// ( the board can be reloaded )

View File

@ -159,15 +159,19 @@ private:
bool m_reportAllTrackErrors; // Report all tracks errors (or only 4 first errors)
bool m_testFootprints; // Test footprints against schematic
PCB_EDIT_FRAME* m_pcbEditorFrame; // The pcb frame editor which owns the board
BOARD* m_pcb;
SHAPE_POLY_SET m_board_outlines; // The board outline including cutouts
DIALOG_DRC* m_drcDialog;
PCB_EDIT_FRAME* m_pcbEditorFrame; // The pcb frame editor which owns the board
BOARD* m_pcb;
SHAPE_POLY_SET m_board_outlines; // The board outline including cutouts
DIALOG_DRC* m_drcDialog;
std::vector<DRC_ITEM*> m_unconnected; // list of unconnected pads
std::vector<DRC_ITEM*> m_footprints; // list of footprint warnings
bool m_drcRun;
bool m_footprintsTested;
std::vector<DRC_ITEM*> m_unconnected; // list of unconnected pads
std::vector<DRC_ITEM*> m_footprints; // list of footprint warnings
bool m_drcRun;
bool m_footprintsTested;
wxLongLong m_rulesFileLastMod;
std::vector<DRC_SELECTOR*> m_ruleSelectors;
std::vector<DRC_RULE*> m_rules;
///> Sets up handlers for various events.
void setTransitions() override;
@ -177,7 +181,7 @@ private:
*/
void updatePointers();
void readRules();
void loadRules();
EDA_UNITS userUnits() const { return m_pcbEditorFrame->GetUserUnits(); }

View File

@ -96,7 +96,17 @@ void DRC_RULES_PARSER::Parse( std::vector<DRC_SELECTOR*>& aSelectors,
ruleMap[ rule->m_Name ] = rule;
for( const std::pair<DRC_SELECTOR*, wxString>& entry : selectorRules )
entry.first->m_Rule = ruleMap[ entry.second ];
{
if( ruleMap.count( entry.second ) )
{
entry.first->m_Rule = ruleMap[ entry.second ];
}
else
{
wxString errText = wxString::Format( _( "Rule \"%s\" not found." ), entry.second );
THROW_PARSE_ERROR( errText, CurSource(), "", 0, 0 );
}
}
}