Better error reporting for DRC rule parsing.

This commit is contained in:
Jeff Young 2020-05-24 15:54:26 +01:00
parent 416d82727f
commit 160981ee71
20 changed files with 100 additions and 67 deletions

View File

@ -353,7 +353,7 @@ bool DSNLEXER::IsSymbol( int aTok )
void DSNLEXER::Expecting( int aTok )
{
wxString errText = wxString::Format(
_( "Expecting \"%s\"" ), GetChars( GetTokenString( aTok ) ) );
_( "Expecting %s" ), GetChars( GetTokenString( aTok ) ) );
THROW_PARSE_ERROR( errText, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
}
@ -361,7 +361,7 @@ void DSNLEXER::Expecting( int aTok )
void DSNLEXER::Expecting( const char* text )
{
wxString errText = wxString::Format(
_( "Expecting \"%s\"" ), GetChars( wxString::FromUTF8( text ) ) );
_( "Expecting '%s'" ), GetChars( wxString::FromUTF8( text ) ) );
THROW_PARSE_ERROR( errText, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
}
@ -369,7 +369,7 @@ void DSNLEXER::Expecting( const char* text )
void DSNLEXER::Unexpected( int aTok )
{
wxString errText = wxString::Format(
_( "Unexpected \"%s\"" ), GetChars( GetTokenString( aTok ) ) );
_( "Unexpected %s" ), GetChars( GetTokenString( aTok ) ) );
THROW_PARSE_ERROR( errText, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
}
@ -385,7 +385,7 @@ void DSNLEXER::Duplicate( int aTok )
void DSNLEXER::Unexpected( const char* text )
{
wxString errText = wxString::Format(
_( "Unexpected \"%s\"" ), GetChars( wxString::FromUTF8( text ) ) );
_( "Unexpected '%s'" ), GetChars( wxString::FromUTF8( text ) ) );
THROW_PARSE_ERROR( errText, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
}

View File

@ -24,7 +24,7 @@
#include <wx/statline.h>
#include <widgets/paged_dialog.h>
#include <wx/stc/stc.h>
// Maps from dialogTitle <-> pageTitle for keeping track of last-selected pages.
// This is not a simple page index because some dialogs have dynamic page sets.
@ -219,7 +219,14 @@ bool PAGED_DIALOG::TransferDataFromWindow()
}
void PAGED_DIALOG::SetError( const wxString& aMessage, wxWindow* aPage, wxObject* aCtrl,
void PAGED_DIALOG::SetError( const wxString& aMessage, const wxString& aPageName, int aCtrlId,
int aRow, int aCol )
{
SetError( aMessage, FindWindow( aPageName ), FindWindow( aCtrlId ), aRow, aCol );
}
void PAGED_DIALOG::SetError( const wxString& aMessage, wxWindow* aPage, wxWindow* aCtrl,
int aRow, int aCol )
{
for( size_t i = 0; i < m_treebook->GetPageCount(); ++i )
@ -250,19 +257,31 @@ void PAGED_DIALOG::OnUpdateUI( wxUpdateUIEvent& event )
{
// We will re-enter this routine when the error dialog is displayed, so make
// sure we don't keep putting up more dialogs.
wxObject* ctrl = m_errorCtrl;
wxWindow* ctrl = m_errorCtrl;
m_errorCtrl = nullptr;
DisplayErrorMessage( this, m_errorMessage );
DisplayErrorMessage( ctrl, m_errorMessage );
if( auto textCtrl = dynamic_cast<wxTextCtrl*>( ctrl ) )
if( wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( ctrl ) )
{
textCtrl->SetSelection( -1, -1 );
textCtrl->SetFocus();
return;
}
if( auto grid = dynamic_cast<wxGrid*>( ctrl ) )
if( wxStyledTextCtrl* scintilla = dynamic_cast<wxStyledTextCtrl*>( ctrl ) )
{
if( m_errorRow > 0 )
{
int pos = scintilla->PositionFromLine( m_errorRow - 1 ) + ( m_errorCol - 1 );
scintilla->GotoPos( pos );
}
scintilla->SetFocus();
return;
}
if( wxGrid* grid = dynamic_cast<wxGrid*>( ctrl ) )
{
grid->SetFocus();
grid->MakeCellVisible( m_errorRow, m_errorCol );

View File

@ -511,11 +511,11 @@ void DIALOG_ERC::OnERCItemRClick( wxDataViewEvent& aEvent )
break;
case 7:
m_parent->DoShowSchematicSetupDialog( _( "Pin Conflicts Map" ) );
m_parent->ShowSchematicSetupDialog( _( "Pin Conflicts Map" ) );
break;
case 8:
m_parent->DoShowSchematicSetupDialog( _( "Violation Severity" ) );
m_parent->ShowSchematicSetupDialog( _( "Violation Severity" ) );
break;
}
}

View File

@ -49,7 +49,7 @@ DIALOG_SCHEMATIC_SETUP::DIALOG_SCHEMATIC_SETUP( SCH_EDIT_FRAME* aFrame ) :
m_textVars = new PANEL_TEXT_VARIABLES( m_treebook, &Prj() );
/*
* WARNING: If you change page names you MUST update calls to DoShowSchematicSetupDialog().
* WARNING: If you change page names you MUST update calls to ShowSchematicSetupDialog().
*/
m_treebook->AddPage( new wxPanel( this ), _( "General" ) );

View File

@ -347,13 +347,12 @@ bool SCH_EDIT_FRAME::LoadProjectFile()
}
void SCH_EDIT_FRAME::DoShowSchematicSetupDialog( const wxString& aInitialPage,
const wxString& aInitialParentPage )
void SCH_EDIT_FRAME::ShowSchematicSetupDialog( const wxString& aInitialPage )
{
DIALOG_SCHEMATIC_SETUP dlg( this );
if( !aInitialPage.IsEmpty() )
dlg.SetInitialPage( aInitialPage, aInitialParentPage );
dlg.SetInitialPage( aInitialPage, wxEmptyString );
if( dlg.ShowQuasiModal() == wxID_OK )
{

View File

@ -214,8 +214,7 @@ public:
*/
bool LoadProjectFile();
void DoShowSchematicSetupDialog( const wxString& aInitialPage = wxEmptyString,
const wxString& aInitialParentPage = wxEmptyString );
void ShowSchematicSetupDialog( const wxString& aInitialPage = wxEmptyString );
/**
* Insert or append a wanted symbol field name into the field names template.

View File

@ -90,7 +90,7 @@ int SCH_EDITOR_CONTROL::SaveAs( const TOOL_EVENT& aEvent )
int SCH_EDITOR_CONTROL::ShowSchematicSetup( const TOOL_EVENT& aEvent )
{
m_frame->DoShowSchematicSetupDialog();
m_frame->ShowSchematicSetupDialog();
return 0;
}

View File

@ -31,7 +31,7 @@ private:
wxString m_title;
wxString m_errorMessage;
wxObject* m_errorCtrl; // the control associated with m_errorMessage
wxWindow* m_errorCtrl; // the control associated with m_errorMessage
int m_errorRow; // the row if m_errorCtrl is a grid
int m_errorCol; // the column if m_errorCtrl is a grid
@ -46,8 +46,11 @@ public:
void SetInitialPage( const wxString& aPage, const wxString& aParentPage = wxEmptyString );
void SetError( const wxString& aMessage, wxWindow* aPage, wxObject* aCtrl,
int aRow = -1, int aCol = -1 );
void SetError( const wxString& aMessage, const wxString& aPageName, int aCtrlId, int aRow = -1,
int aCol = -1 );
void SetError( const wxString& aMessage, wxWindow* aPage, wxWindow* aCtrl, int aRow = -1,
int aCol = -1 );
protected:
void finishInitialization();

View File

@ -55,7 +55,7 @@ DIALOG_BOARD_SETUP::DIALOG_BOARD_SETUP( PCB_EDIT_FRAME* aFrame ) :
m_textVars = new PANEL_TEXT_VARIABLES( this, &Prj() );
/*
* WARNING: If you change page names you MUST update calls to DoShowBoardSetupDialog().
* WARNING: If you change page names you MUST update calls to ShowBoardSetupDialog().
*/
m_treebook->AddPage( new wxPanel( this ), _( "Board Stackup" ) );

View File

@ -388,7 +388,7 @@ void DIALOG_DRC::OnDRCItemRClick( wxDataViewEvent& aEvent )
break;
case 6:
m_brdEditor->DoShowBoardSetupDialog( _( "Violation Severity" ) );
m_brdEditor->ShowBoardSetupDialog( _( "Violation Severity" ) );
break;
}

View File

@ -22,7 +22,7 @@ PANEL_SETUP_RULES_BASE::PANEL_SETUP_RULES_BASE( wxWindow* parent, wxWindowID id,
m_title->Wrap( -1 );
m_topMargin->Add( m_title, 0, wxTOP|wxBOTTOM, 5 );
m_textEditor = new wxStyledTextCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, wxEmptyString );
m_textEditor = new wxStyledTextCtrl( this, ID_RULES_EDITOR, wxDefaultPosition, wxDefaultSize, 0, wxEmptyString );
m_textEditor->SetUseTabs( true );
m_textEditor->SetTabWidth( 4 );
m_textEditor->SetIndent( 4 );

View File

@ -12,7 +12,7 @@
<property name="encoding">UTF-8</property>
<property name="event_generation">connect</property>
<property name="file">panel_setup_rules_base</property>
<property name="first_id">1000</property>
<property name="first_id">2240</property>
<property name="help_provider">none</property>
<property name="indent_with_spaces"></property>
<property name="internationalize">1</property>
@ -25,7 +25,7 @@
<property name="skip_php_events">1</property>
<property name="skip_python_events">1</property>
<property name="ui_table">UI</property>
<property name="use_enum">1</property>
<property name="use_enum">0</property>
<property name="use_microsoft_bom">0</property>
<object class="Panel" expanded="1">
<property name="aui_managed">0</property>
@ -166,7 +166,7 @@
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="id">ID_RULES_EDITOR</property>
<property name="indentation_guides">1</property>
<property name="line_numbers">1</property>
<property name="max_size"></property>

View File

@ -22,6 +22,8 @@
///////////////////////////////////////////////////////////////////////////
#define ID_RULES_EDITOR 2240
///////////////////////////////////////////////////////////////////////////////
/// Class PANEL_SETUP_RULES_BASE
///////////////////////////////////////////////////////////////////////////////

View File

@ -44,14 +44,13 @@
#include <tools/zone_filler_tool.h>
#include <kiface_i.h>
#include <pcbnew.h>
#include <drc/drc.h>
#include <netlist_reader/pcb_netlist.h>
#include <math/util.h> // for KiROUND
#include <dialog_drc.h>
#include <wx/progdlg.h>
#include <board_commit.h>
#include <geometry/shape_arc.h>
#include <drc/drc.h>
#include <drc/drc_rule_parser.h>
#include <drc/drc_item.h>
#include <drc/drc_courtyard_tester.h>
@ -59,11 +58,12 @@
#include <drc/drc_keepout_tester.h>
#include <drc/drc_netclass_tester.h>
#include <drc/drc_textvar_tester.h>
#include <dialogs/panel_setup_rules.h>
#include <confirm.h>
DRC::DRC() :
PCB_TOOL_BASE( "pcbnew.DRCTool" ),
m_pcbEditorFrame( nullptr ),
m_editFrame( nullptr ),
m_pcb( nullptr ),
m_board_outline_valid( false ),
m_drcDialog( nullptr ),
@ -94,14 +94,14 @@ DRC::~DRC()
void DRC::Reset( RESET_REASON aReason )
{
m_pcbEditorFrame = getEditFrame<PCB_EDIT_FRAME>();
m_editFrame = getEditFrame<PCB_EDIT_FRAME>();
if( m_pcb != m_pcbEditorFrame->GetBoard() )
if( m_pcb != m_editFrame->GetBoard() )
{
if( m_drcDialog )
DestroyDRCDialog( wxID_OK );
m_pcb = m_pcbEditorFrame->GetBoard();
m_pcb = m_editFrame->GetBoard();
}
}
@ -117,7 +117,7 @@ void DRC::ShowDRCDialog( wxWindow* aParent )
// if any parent is specified, the dialog is modal.
// if this is the default PCB editor frame, it is not modal
show_dlg_modal = false;
aParent = m_pcbEditorFrame;
aParent = m_editFrame;
}
Activate();
@ -125,7 +125,7 @@ void DRC::ShowDRCDialog( wxWindow* aParent )
if( !m_drcDialog )
{
m_drcDialog = new DIALOG_DRC( this, m_pcbEditorFrame, aParent );
m_drcDialog = new DIALOG_DRC( this, m_editFrame, aParent );
updatePointers();
if( show_dlg_modal )
@ -181,7 +181,7 @@ void DRC::DestroyDRCDialog( int aReason )
int DRC::testZoneToZoneOutlines( BOARD_COMMIT& aCommit )
{
BOARD* board = m_pcbEditorFrame->GetBoard();
BOARD* board = m_editFrame->GetBoard();
int nerrors = 0;
std::vector<SHAPE_POLY_SET> smoothed_polys;
@ -353,9 +353,9 @@ int DRC::testZoneToZoneOutlines( BOARD_COMMIT& aCommit )
}
void DRC::LoadRules()
bool DRC::LoadRules()
{
wxString rulesFilepath = m_pcbEditorFrame->Prj().AbsolutePath( "drc-rules" );
wxString rulesFilepath = m_editFrame->Prj().AbsolutePath( "drc-rules" );
wxFileName rulesFile( rulesFilepath );
if( rulesFile.FileExists() )
@ -378,7 +378,11 @@ void DRC::LoadRules()
m_ruleSelectors.clear();
m_rules.clear();
DisplayError( m_drcDialog, pe.What() );
wxSafeYield( m_editFrame );
m_editFrame->ShowBoardSetupDialog( _( "Rules" ), pe.What(), ID_RULES_EDITOR,
pe.lineNumber, pe.byteIndex );
return false;
}
}
}
@ -388,17 +392,20 @@ void DRC::LoadRules()
BOARD_DESIGN_SETTINGS& bds = m_pcb->GetDesignSettings();
bds.m_DRCRuleSelectors = m_ruleSelectors;
bds.m_DRCRules = m_rules;
return true;
}
void DRC::RunTests( wxTextCtrl* aMessages )
{
// Make absolutely sure these are up-to-date
LoadRules();
if( !LoadRules() )
return;
wxASSERT( m_pcb == m_pcbEditorFrame->GetBoard() );
wxASSERT( m_pcb == m_editFrame->GetBoard() );
BOARD_COMMIT commit( m_pcbEditorFrame );
BOARD_COMMIT commit( m_editFrame );
BOARD_DESIGN_SETTINGS& bds = m_pcb->GetDesignSettings();
m_largestClearance = bds.GetBiggestClearanceValue();
@ -480,7 +487,7 @@ void DRC::RunTests( wxTextCtrl* aMessages )
}
// caller (a wxTopLevelFrame) is the wxDialog or the Pcb Editor frame that call DRC:
wxWindow* caller = aMessages ? aMessages->GetParent() : m_pcbEditorFrame;
wxWindow* caller = aMessages ? aMessages->GetParent() : m_editFrame;
if( m_refillZones )
{
@ -504,7 +511,7 @@ void DRC::RunTests( wxTextCtrl* aMessages )
wxSafeYield();
}
testTracks( commit, aMessages ? aMessages->GetParent() : m_pcbEditorFrame, true );
testTracks( commit, aMessages ? aMessages->GetParent() : m_editFrame, true );
// test zone clearances to other zones
if( aMessages )
@ -594,7 +601,7 @@ void DRC::RunTests( wxTextCtrl* aMessages )
}
NETLIST netlist;
m_pcbEditorFrame->FetchNetlistFromSchematic( netlist, PCB_EDIT_FRAME::ANNOTATION_DIALOG );
m_editFrame->FetchNetlistFromSchematic( netlist, PCB_EDIT_FRAME::ANNOTATION_DIALOG );
if( m_drcDialog )
m_drcDialog->Raise();
@ -648,17 +655,17 @@ void DRC::RunTests( wxTextCtrl* aMessages )
void DRC::updatePointers()
{
// update my pointers, m_pcbEditorFrame is the only unchangeable one
m_pcb = m_pcbEditorFrame->GetBoard();
// update my pointers, m_editFrame is the only unchangeable one
m_pcb = m_editFrame->GetBoard();
m_pcbEditorFrame->ResolveDRCExclusions();
m_editFrame->ResolveDRCExclusions();
if( m_drcDialog ) // Use diag list boxes only in DRC dialog
{
m_drcDialog->SetMarkersProvider( new BOARD_DRC_ITEMS_PROVIDER( m_pcb ) );
m_drcDialog->SetUnconnectedProvider( new RATSNEST_DRC_ITEMS_PROVIDER( m_pcbEditorFrame,
m_drcDialog->SetUnconnectedProvider( new RATSNEST_DRC_ITEMS_PROVIDER( m_editFrame,
&m_unconnected ) );
m_drcDialog->SetFootprintsProvider( new VECTOR_DRC_ITEMS_PROVIDER( m_pcbEditorFrame,
m_drcDialog->SetFootprintsProvider( new VECTOR_DRC_ITEMS_PROVIDER( m_editFrame,
&m_footprints ) );
}
}
@ -1142,7 +1149,7 @@ void DRC::testOutline( BOARD_COMMIT& aCommit )
void DRC::testDisabledLayers( BOARD_COMMIT& aCommit )
{
BOARD* board = m_pcbEditorFrame->GetBoard();
BOARD* board = m_editFrame->GetBoard();
wxCHECK( board, /*void*/ );
LSET disabledLayers = board->GetEnabledLayers().flip();

View File

@ -163,7 +163,7 @@ 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
PCB_EDIT_FRAME* m_editFrame; // The pcb frame editor which owns the board
BOARD* m_pcb;
SHAPE_POLY_SET m_board_outlines; // The board outline including cutouts
bool m_board_outline_valid;
@ -171,8 +171,8 @@ private:
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;
bool m_drcRun; // indicates DRC has been run at least once
bool m_footprintsTested; // indicates footprints were tested in last run
std::vector<DRC_SELECTOR*> m_ruleSelectors;
std::vector<DRC_RULE*> m_rules;
@ -192,7 +192,7 @@ private:
*/
void updatePointers();
EDA_UNITS userUnits() const { return m_pcbEditorFrame->GetUserUnits(); }
EDA_UNITS userUnits() const { return m_editFrame->GetUserUnits(); }
/**
* Adds a DRC marker to the PCB through the COMMIT mechanism.
@ -300,7 +300,7 @@ public:
/**
* Load the DRC rules. Must be called after the netclasses have been read.
*/
void LoadRules();
bool LoadRules();
/**
* Test the board footprints against a netlist. Will report DRCE_MISSING_FOOTPRINT,

View File

@ -204,7 +204,7 @@ void PCB_EDIT_FRAME::Tracks_and_Vias_Size_Event( wxCommandEvent& event )
else if( ii == int( m_SelTrackWidthBox->GetCount() - 1 ) )
{
m_SelTrackWidthBox->SetSelection( GetDesignSettings().GetTrackWidthIndex() );
DoShowBoardSetupDialog( _( "Tracks & Vias" ) );
ShowBoardSetupDialog( _( "Tracks & Vias" ) );
}
else
GetDesignSettings().SetTrackWidthIndex( ii );
@ -222,7 +222,7 @@ void PCB_EDIT_FRAME::Tracks_and_Vias_Size_Event( wxCommandEvent& event )
else if( ii == int( m_SelViaSizeBox->GetCount() - 1 ) )
{
m_SelViaSizeBox->SetSelection( GetDesignSettings().GetViaSizeIndex() );
DoShowBoardSetupDialog( _( "Tracks & Vias" ) );
ShowBoardSetupDialog( _( "Tracks & Vias" ) );
}
else
GetDesignSettings().SetViaSizeIndex( ii );

View File

@ -593,8 +593,6 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
SetBoard( loadedBoard );
m_toolManager->GetTool<DRC>()->LoadRules();
// we should not ask PLUGINs to do these items:
loadedBoard->BuildListOfNets();
loadedBoard->SynchronizeNetsAndNetClasses();

View File

@ -623,13 +623,16 @@ void PCB_EDIT_FRAME::ActivateGalCanvas()
}
void PCB_EDIT_FRAME::DoShowBoardSetupDialog( const wxString& aInitialPage,
const wxString& aInitialParentPage )
void PCB_EDIT_FRAME::ShowBoardSetupDialog( const wxString& aInitialPage, const wxString& aErrorMsg,
int aErrorCtrlId, int aErrorLine, int aErrorCol )
{
DIALOG_BOARD_SETUP dlg( this );
if( !aInitialPage.IsEmpty() )
dlg.SetInitialPage( aInitialPage, aInitialParentPage );
dlg.SetInitialPage( aInitialPage, wxEmptyString );
if( !aErrorMsg.IsEmpty() )
dlg.SetError( aErrorMsg, aInitialPage, aErrorCtrlId, aErrorLine, aErrorCol );
if( dlg.ShowQuasiModal() == wxID_OK )
{
@ -753,6 +756,8 @@ void PCB_EDIT_FRAME::onBoardLoaded()
SetMsgPanel( GetBoard() );
SetStatusText( wxEmptyString );
m_toolManager->GetTool<DRC>()->LoadRules();
SetShutdownBlockReason( _( "PCB file changes are unsaved" ) );
}

View File

@ -540,8 +540,9 @@ public:
/**
* Function ShowBoardSetupDialog
*/
void DoShowBoardSetupDialog( const wxString& aInitialPage = wxEmptyString,
const wxString& aInitialParentPage = wxEmptyString );
void ShowBoardSetupDialog( const wxString& aInitialPage = wxEmptyString,
const wxString& aErrorMsg = wxEmptyString, int aErrorCtrlId = -1,
int aErrorLine = -1, int aErrorCol = -1 );
/* toolbars update UI functions: */

View File

@ -312,7 +312,7 @@ int PCB_EDITOR_CONTROL::Plot( const TOOL_EVENT& aEvent )
int PCB_EDITOR_CONTROL::BoardSetup( const TOOL_EVENT& aEvent )
{
getEditFrame<PCB_EDIT_FRAME>()->DoShowBoardSetupDialog();
getEditFrame<PCB_EDIT_FRAME>()->ShowBoardSetupDialog();
return 0;
}