fix Bug #152546 (Netlist not respecting case sensitivity for labels): the label matching is now case sensitive. To avoid issues with previous eeschema versions, add in ERC a dectection for "similar" labels (labels which differ only by a case sensitivity)

(this option can be disabled, and saved in project config)
This commit is contained in:
jean-pierre charras 2015-12-20 13:40:17 +01:00
parent 0842a107fb
commit fcdbb7484c
11 changed files with 869 additions and 84 deletions

View File

@ -54,6 +54,10 @@ wxString DRC_ITEM::GetErrorText() const
return wxString( _("A no connect symbol is connected to more than 1 pin")); return wxString( _("A no connect symbol is connected to more than 1 pin"));
case ERCE_GLOBLABEL: case ERCE_GLOBLABEL:
return wxString( _("Global label not connected to any other global label") ); return wxString( _("Global label not connected to any other global label") );
case ERCE_SIMILAR_LABELS:
return wxString( _("Labels are similar (lower/upper case difference only)") );
case ERCE_SIMILAR_GLBL_LABELS:
return wxString( _("Global labels are similar (lower/upper case difference only)") );
default: default:
return wxString( wxT("Unkown.") ); return wxString( wxT("Unkown.") );

View File

@ -369,6 +369,32 @@ public:
*/ */
void SortListbySheet(); void SortListbySheet();
/**
* Counts number of pins connected on the same net.
* Used to count all pins connected to a no connect symbol
* @return the pin count of the net starting at aNetStart
* @param aNetStart = index in list of net objects of the first item
*/
int CountPinsInNet( unsigned aNetStart );
/**
* Function TestforNonOrphanLabel
* Sheet labels are expected to be connected to a hierarchical label.
* Hierarchical labels are expected to be connected to a sheet label.
* Global labels are expected to be not orphan (connected to at least one other global label.
* this function tests the connection to an other suitable label
*/
void TestforNonOrphanLabel( unsigned aNetItemRef, unsigned aStartNet );
/**
* Function TestforSimilarLabels
* detects labels which are different when using case sensitive comparisons
* but are equal when using case insensitive comparisons
* It can be due to a mistake from designer, so this kind of labels
* is reported by TestforSimilarLabels
*/
void TestforSimilarLabels();
#if defined(DEBUG) #if defined(DEBUG)
void DumpNetTable() void DumpNetTable()
@ -403,7 +429,7 @@ private:
return Objet1->GetNet() < Objet2->GetNet(); return Objet1->GetNet() < Objet2->GetNet();
} }
/* Comparison routine to sort items by Sheet Number /* Comparison routine to sort items by Sheet path
*/ */
static bool sortItemsBySheet( const NETLIST_OBJECT* Objet1, const NETLIST_OBJECT* Objet2 ) static bool sortItemsBySheet( const NETLIST_OBJECT* Objet1, const NETLIST_OBJECT* Objet2 )
{ {

View File

@ -1,7 +1,7 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2012 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net> * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
* *
@ -37,6 +37,7 @@
#include <schframe.h> #include <schframe.h>
#include <invoke_sch_dialog.h> #include <invoke_sch_dialog.h>
#include <project.h> #include <project.h>
#include <kiface_i.h>
#include <netlist.h> #include <netlist.h>
#include <class_netlist_object.h> #include <class_netlist_object.h>
@ -48,10 +49,19 @@
#include <erc.h> #include <erc.h>
#include <id.h> #include <id.h>
extern int DiagErc[PIN_NMAX][PIN_NMAX];
extern int DefaultDiagErc[PIN_NMAX][PIN_NMAX];
bool DIALOG_ERC::m_writeErcFile = false;
bool DIALOG_ERC::m_writeErcFile = false; // saved only for the current session
bool DIALOG_ERC::m_TestSimilarLabels = true; // Save in project config
bool DIALOG_ERC::m_diagErcTableInit = false; // saved only for the current session
bool DIALOG_ERC::m_tstUniqueGlobalLabels = true; // saved only for the current session
// Control identifiers for events
#define ID_MATRIX_0 1800
BEGIN_EVENT_TABLE( DIALOG_ERC, DIALOG_ERC_BASE ) BEGIN_EVENT_TABLE( DIALOG_ERC, DIALOG_ERC_BASE )
EVT_COMMAND_RANGE( ID_MATRIX_0, ID_MATRIX_0 + ( PIN_NMAX * PIN_NMAX ) - 1, EVT_COMMAND_RANGE( ID_MATRIX_0, ID_MATRIX_0 + ( PIN_NMAX * PIN_NMAX ) - 1,
wxEVT_COMMAND_BUTTON_CLICKED, DIALOG_ERC::ChangeErrorLevel ) wxEVT_COMMAND_BUTTON_CLICKED, DIALOG_ERC::ChangeErrorLevel )
@ -72,6 +82,8 @@ DIALOG_ERC::DIALOG_ERC( SCH_EDIT_FRAME* parent ) :
DIALOG_ERC::~DIALOG_ERC() DIALOG_ERC::~DIALOG_ERC()
{ {
m_TestSimilarLabels = m_cbTestSimilarLabels->GetValue();
m_tstUniqueGlobalLabels = m_cbTestUniqueGlbLabels->GetValue();
} }
@ -86,6 +98,8 @@ void DIALOG_ERC::Init()
} }
m_WriteResultOpt->SetValue( m_writeErcFile ); m_WriteResultOpt->SetValue( m_writeErcFile );
m_cbTestSimilarLabels->SetValue( m_TestSimilarLabels );
m_cbTestUniqueGlbLabels->SetValue( m_tstUniqueGlobalLabels );
SCH_SCREENS screens; SCH_SCREENS screens;
updateMarkerCounts( &screens ); updateMarkerCounts( &screens );
@ -232,7 +246,7 @@ void DIALOG_ERC::OnLeftClickMarkersList( wxHtmlLinkEvent& event )
void DIALOG_ERC::OnLeftDblClickMarkersList( wxMouseEvent& event ) void DIALOG_ERC::OnLeftDblClickMarkersList( wxMouseEvent& event )
{ {
// Remember: OnLeftClickMarkersList was called just berfore // Remember: OnLeftClickMarkersList was called just before
// and therefore m_lastMarkerFound was initialized. // and therefore m_lastMarkerFound was initialized.
// (NULL if not found) // (NULL if not found)
if( m_lastMarkerFound ) if( m_lastMarkerFound )
@ -257,10 +271,10 @@ void DIALOG_ERC::ReBuildMatrixPanel()
wxSize bitmap_size = dummy->GetSize(); wxSize bitmap_size = dummy->GetSize();
delete dummy; delete dummy;
if( !DiagErcTableInit ) if( !m_diagErcTableInit )
{ {
memcpy( DiagErc, DefaultDiagErc, sizeof(DefaultDiagErc) ); memcpy( DiagErc, DefaultDiagErc, sizeof(DefaultDiagErc) );
DiagErcTableInit = true; m_diagErcTableInit = true;
} }
wxPoint pos; wxPoint pos;
@ -389,6 +403,10 @@ void DIALOG_ERC::ResetDefaultERCDiag( wxCommandEvent& event )
{ {
memcpy( DiagErc, DefaultDiagErc, sizeof( DiagErc ) ); memcpy( DiagErc, DefaultDiagErc, sizeof( DiagErc ) );
ReBuildMatrixPanel(); ReBuildMatrixPanel();
m_TestSimilarLabels = true;
m_cbTestSimilarLabels->SetValue( m_TestSimilarLabels );
m_tstUniqueGlobalLabels = true;
m_cbTestUniqueGlbLabels->SetValue( m_tstUniqueGlobalLabels );
} }
@ -432,13 +450,9 @@ void DIALOG_ERC::TestErc( wxArrayString* aMessagesList )
{ {
wxFileName fn; wxFileName fn;
if( !DiagErcTableInit )
{
memcpy( DiagErc, DefaultDiagErc, sizeof( DefaultDiagErc ) );
DiagErcTableInit = true;
}
m_writeErcFile = m_WriteResultOpt->GetValue(); m_writeErcFile = m_WriteResultOpt->GetValue();
m_TestSimilarLabels = m_cbTestSimilarLabels->GetValue();
m_tstUniqueGlobalLabels = m_cbTestUniqueGlbLabels->GetValue();
// Build the whole sheet list in hierarchy (sheet, not screen) // Build the whole sheet list in hierarchy (sheet, not screen)
SCH_SHEET_LIST sheets; SCH_SHEET_LIST sheets;
@ -511,12 +525,14 @@ void DIALOG_ERC::TestErc( wxArrayString* aMessagesList )
case NET_HIERBUSLABELMEMBER: case NET_HIERBUSLABELMEMBER:
case NET_SHEETLABEL: case NET_SHEETLABEL:
case NET_SHEETBUSLABELMEMBER: case NET_SHEETBUSLABELMEMBER:
case NET_GLOBLABEL:
// ERC problems when pin sheets do not match hierarchical labels. // ERC problems when pin sheets do not match hierarchical labels.
// Each pin sheet must match a hierarchical label // Each pin sheet must match a hierarchical label
// Each hierarchical label must match a pin sheet // Each hierarchical label must match a pin sheet
TestLabel( objectsConnectedList.get(), net, nextNet ); objectsConnectedList->TestforNonOrphanLabel( net, nextNet );
break;
case NET_GLOBLABEL:
if( m_tstUniqueGlobalLabels )
objectsConnectedList->TestforNonOrphanLabel( net, nextNet );
break; break;
case NET_NOCONNECT: case NET_NOCONNECT:
@ -524,7 +540,7 @@ void DIALOG_ERC::TestErc( wxArrayString* aMessagesList )
// ERC problems when a noconnect symbol is connected to more than one pin. // ERC problems when a noconnect symbol is connected to more than one pin.
MinConn = NET_NC; MinConn = NET_NC;
if( CountPinsInNet( objectsConnectedList.get(), nextNet ) > 1 ) if( objectsConnectedList->CountPinsInNet( nextNet ) > 1 )
Diagnose( objectsConnectedList->GetItem( net ), NULL, MinConn, UNC ); Diagnose( objectsConnectedList->GetItem( net ), NULL, MinConn, UNC );
break; break;
@ -539,6 +555,11 @@ void DIALOG_ERC::TestErc( wxArrayString* aMessagesList )
lastNet = net; lastNet = net;
} }
// Test similar labels (i;e. labels which are identical when
// using case insensitive comparisons)
if( m_TestSimilarLabels )
objectsConnectedList->TestforSimilarLabels();
// Displays global results: // Displays global results:
updateMarkerCounts( &screens ); updateMarkerCounts( &screens );

View File

@ -27,22 +27,12 @@
#include <wx/htmllbox.h> #include <wx/htmllbox.h>
#include <vector> #include <vector>
#include <lib_pin.h> // For PIN_NMAX definition
#include <dialog_erc_base.h> #include <dialog_erc_base.h>
#include "dialog_erc_listbox.h" #include "dialog_erc_listbox.h"
/* Variable locales */ // DIALOG_ERC class declaration
extern int DiagErc[PIN_NMAX][PIN_NMAX];
extern bool DiagErcTableInit; // go to true after DiagErc init
extern int DefaultDiagErc[PIN_NMAX][PIN_NMAX];
/* Control identifiers */
#define ID_MATRIX_0 1800
/*!
* DIALOG_ERC class declaration
*/
class DIALOG_ERC : public DIALOG_ERC_BASE class DIALOG_ERC : public DIALOG_ERC_BASE
{ {
@ -54,6 +44,11 @@ private:
bool m_initialized; bool m_initialized;
const SCH_MARKER* m_lastMarkerFound; const SCH_MARKER* m_lastMarkerFound;
static bool m_writeErcFile; static bool m_writeErcFile;
static bool m_diagErcTableInit; // go to true after DiagErc init
static bool m_tstUniqueGlobalLabels;
public:
static bool m_TestSimilarLabels;
public: public:
DIALOG_ERC( SCH_EDIT_FRAME* parent ); DIALOG_ERC( SCH_EDIT_FRAME* parent );

View File

@ -56,6 +56,9 @@ DIALOG_ERC_BASE::DIALOG_ERC_BASE( wxWindow* parent, wxWindowID id, const wxStrin
sdiagSizer->Add( gSizeDiag, 0, wxEXPAND, 5 ); sdiagSizer->Add( gSizeDiag, 0, wxEXPAND, 5 );
m_staticline1 = new wxStaticLine( sdiagSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
sdiagSizer->Add( m_staticline1, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 );
m_WriteResultOpt = new wxCheckBox( sdiagSizer->GetStaticBox(), wxID_ANY, _("Create ERC file report"), wxDefaultPosition, wxDefaultSize, 0 ); m_WriteResultOpt = new wxCheckBox( sdiagSizer->GetStaticBox(), wxID_ANY, _("Create ERC file report"), wxDefaultPosition, wxDefaultSize, 0 );
sdiagSizer->Add( m_WriteResultOpt, 0, wxTOP|wxBOTTOM|wxRIGHT, 5 ); sdiagSizer->Add( m_WriteResultOpt, 0, wxTOP|wxBOTTOM|wxRIGHT, 5 );
@ -83,7 +86,7 @@ DIALOG_ERC_BASE::DIALOG_ERC_BASE( wxWindow* parent, wxWindowID id, const wxStrin
bercSizer->Add( m_textMarkers, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); bercSizer->Add( m_textMarkers, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_MarkersList = new ERC_HTML_LISTFRAME( m_PanelERC, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO|wxSUNKEN_BORDER ); m_MarkersList = new ERC_HTML_LISTFRAME( m_PanelERC, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO|wxSUNKEN_BORDER );
bercSizer->Add( m_MarkersList, 1, wxALL|wxEXPAND, 5 ); bercSizer->Add( m_MarkersList, 1, wxEXPAND|wxALL, 5 );
wxBoxSizer* bbuttonsSizer; wxBoxSizer* bbuttonsSizer;
bbuttonsSizer = new wxBoxSizer( wxHORIZONTAL ); bbuttonsSizer = new wxBoxSizer( wxHORIZONTAL );
@ -113,9 +116,30 @@ DIALOG_ERC_BASE::DIALOG_ERC_BASE( wxWindow* parent, wxWindowID id, const wxStrin
m_ResetOptButton = new wxButton( m_PanelERCOptions, ID_RESET_MATRIX, _("Initialize to Default"), wxDefaultPosition, wxDefaultSize, 0 ); m_ResetOptButton = new wxButton( m_PanelERCOptions, ID_RESET_MATRIX, _("Initialize to Default"), wxDefaultPosition, wxDefaultSize, 0 );
m_panelMatrixSizer->Add( m_ResetOptButton, 0, wxALIGN_RIGHT|wxTOP|wxRIGHT|wxLEFT, 5 ); m_panelMatrixSizer->Add( m_ResetOptButton, 0, wxALIGN_RIGHT|wxTOP|wxRIGHT|wxLEFT, 5 );
m_staticText8 = new wxStaticText( m_PanelERCOptions, wxID_ANY, _("Pin to pin connections"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE );
m_staticText8->Wrap( -1 );
m_panelMatrixSizer->Add( m_staticText8, 0, wxRIGHT|wxLEFT|wxEXPAND, 5 );
m_matrixPanel = new wxPanel( m_PanelERCOptions, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); m_matrixPanel = new wxPanel( m_PanelERCOptions, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
m_panelMatrixSizer->Add( m_matrixPanel, 1, wxEXPAND | wxALL, 5 ); m_panelMatrixSizer->Add( m_matrixPanel, 1, wxEXPAND | wxALL, 5 );
m_staticline2 = new wxStaticLine( m_PanelERCOptions, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
m_panelMatrixSizer->Add( m_staticline2, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 );
m_staticText9 = new wxStaticText( m_PanelERCOptions, wxID_ANY, _("Label to label connections"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE );
m_staticText9->Wrap( -1 );
m_panelMatrixSizer->Add( m_staticText9, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
m_cbTestSimilarLabels = new wxCheckBox( m_PanelERCOptions, wxID_ANY, _("Test similar labels"), wxDefaultPosition, wxDefaultSize, 0 );
m_cbTestSimilarLabels->SetToolTip( _("Similar labels are labels (inside a sheet) which differs only by upper/lower case") );
m_panelMatrixSizer->Add( m_cbTestSimilarLabels, 0, wxALL, 5 );
m_cbTestUniqueGlbLabels = new wxCheckBox( m_PanelERCOptions, wxID_ANY, _("Test unique global labels"), wxDefaultPosition, wxDefaultSize, 0 );
m_cbTestUniqueGlbLabels->SetToolTip( _("Global labels are used to connect signals across the full hierarchy.\nThey are expected to be at least two labels with the same name.") );
m_panelMatrixSizer->Add( m_cbTestUniqueGlbLabels, 0, wxALL, 5 );
m_PanelERCOptions->SetSizer( m_panelMatrixSizer ); m_PanelERCOptions->SetSizer( m_panelMatrixSizer );
m_PanelERCOptions->Layout(); m_PanelERCOptions->Layout();

View File

@ -44,7 +44,7 @@
<property name="minimum_size"></property> <property name="minimum_size"></property>
<property name="name">DIALOG_ERC_BASE</property> <property name="name">DIALOG_ERC_BASE</property>
<property name="pos"></property> <property name="pos"></property>
<property name="size">519,457</property> <property name="size">519,464</property>
<property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property> <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
<property name="subclass">DIALOG_SHIM; dialog_shim.h</property> <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
<property name="title">Electrical Rules Checker</property> <property name="title">Electrical Rules Checker</property>
@ -815,6 +815,87 @@
</object> </object>
</object> </object>
</object> </object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
<property name="proportion">0</property>
<object class="wxStaticLine" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_staticline1</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style">wxLI_HORIZONTAL</property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="0"> <object class="sizeritem" expanded="0">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxTOP|wxBOTTOM|wxRIGHT</property> <property name="flag">wxTOP|wxBOTTOM|wxRIGHT</property>
@ -1177,7 +1258,7 @@
</object> </object>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="1">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property> <property name="flag">wxEXPAND|wxALL</property>
<property name="proportion">1</property> <property name="proportion">1</property>
<object class="wxHtmlWindow" expanded="1"> <object class="wxHtmlWindow" expanded="1">
<property name="BottomDockable">1</property> <property name="BottomDockable">1</property>
@ -1708,6 +1789,89 @@
<event name="OnUpdateUI"></event> <event name="OnUpdateUI"></event>
</object> </object>
</object> </object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxRIGHT|wxLEFT|wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Pin to pin connections</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_staticText8</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style">wxALIGN_CENTRE</property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="1">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxEXPAND | wxALL</property> <property name="flag">wxEXPAND | wxALL</property>
@ -1788,6 +1952,346 @@
<event name="OnUpdateUI"></event> <event name="OnUpdateUI"></event>
</object> </object>
</object> </object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
<property name="proportion">0</property>
<object class="wxStaticLine" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_staticline2</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style">wxLI_HORIZONTAL</property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Label to label connections</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_staticText9</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style">wxALIGN_CENTRE</property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="checked">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Test similar labels</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_cbTestSimilarLabels</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip">Similar labels are labels (inside a sheet) which differs only by upper/lower case</property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnCheckBox"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="checked">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Test unique global labels</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_cbTestUniqueGlbLabels</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip">Global labels are used to connect signals across the full hierarchy.&#x0A;They are expected to be at least two labels with the same name.</property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnCheckBox"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
</object> </object>
</object> </object>
</object> </object>

View File

@ -23,6 +23,7 @@ class ERC_HTML_LISTFRAME;
#include <wx/settings.h> #include <wx/settings.h>
#include <wx/textctrl.h> #include <wx/textctrl.h>
#include <wx/sizer.h> #include <wx/sizer.h>
#include <wx/statline.h>
#include <wx/checkbox.h> #include <wx/checkbox.h>
#include <wx/statbox.h> #include <wx/statbox.h>
#include <wx/html/htmlwin.h> #include <wx/html/htmlwin.h>
@ -56,6 +57,7 @@ class DIALOG_ERC_BASE : public DIALOG_SHIM
wxTextCtrl* m_LastWarningCount; wxTextCtrl* m_LastWarningCount;
wxStaticText* m_LastErrCountText; wxStaticText* m_LastErrCountText;
wxTextCtrl* m_LastErrCount; wxTextCtrl* m_LastErrCount;
wxStaticLine* m_staticline1;
wxCheckBox* m_WriteResultOpt; wxCheckBox* m_WriteResultOpt;
wxStaticText* m_titleMessages; wxStaticText* m_titleMessages;
wxTextCtrl* m_MessagesList; wxTextCtrl* m_MessagesList;
@ -66,7 +68,12 @@ class DIALOG_ERC_BASE : public DIALOG_SHIM
wxButton* m_buttonClose; wxButton* m_buttonClose;
wxPanel* m_PanelERCOptions; wxPanel* m_PanelERCOptions;
wxButton* m_ResetOptButton; wxButton* m_ResetOptButton;
wxStaticText* m_staticText8;
wxPanel* m_matrixPanel; wxPanel* m_matrixPanel;
wxStaticLine* m_staticline2;
wxStaticText* m_staticText9;
wxCheckBox* m_cbTestSimilarLabels;
wxCheckBox* m_cbTestUniqueGlbLabels;
// Virtual event handlers, overide them in your derived class // Virtual event handlers, overide them in your derived class
virtual void OnCloseErcDialog( wxCloseEvent& event ) { event.Skip(); } virtual void OnCloseErcDialog( wxCloseEvent& event ) { event.Skip(); }
@ -80,7 +87,7 @@ class DIALOG_ERC_BASE : public DIALOG_SHIM
public: public:
DIALOG_ERC_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Electrical Rules Checker"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 519,457 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); DIALOG_ERC_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Electrical Rules Checker"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 519,464 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_ERC_BASE(); ~DIALOG_ERC_BASE();
}; };

View File

@ -51,6 +51,7 @@
#include <dialogs/dialog_eeschema_options.h> #include <dialogs/dialog_eeschema_options.h>
#include <dialogs/dialog_libedit_options.h> #include <dialogs/dialog_libedit_options.h>
#include <dialogs/dialog_schematic_find.h> #include <dialogs/dialog_schematic_find.h>
#include <dialog_erc.h>
#include <wildcards_and_files_ext.h> #include <wildcards_and_files_ext.h>
@ -438,16 +439,18 @@ PARAM_CFG_ARRAY& SCH_EDIT_FRAME::GetProjectFileParametersList()
*/ */
m_projectFileParams.push_back( new PARAM_CFG_WXSTRING( wxT( "NetFmtName" ), m_projectFileParams.push_back( new PARAM_CFG_WXSTRING( wxT( "NetFmtName" ),
&m_netListFormat) ); &m_netListFormat) );
m_projectFileParams.push_back( new PARAM_CFG_BOOL( wxT( "SpiceForceRefPrefix" ), m_projectFileParams.push_back( new PARAM_CFG_BOOL( wxT( "SpiceForceRefPrefix" ),
&m_spiceNetlistAddReferencePrefix, false ) ); &m_spiceNetlistAddReferencePrefix, false ) );
m_projectFileParams.push_back( new PARAM_CFG_BOOL( wxT( "SpiceUseNetNumbers" ), m_projectFileParams.push_back( new PARAM_CFG_BOOL( wxT( "SpiceUseNetNumbers" ),
&m_spiceNetlistUseNetcodeAsNetname, false ) ); &m_spiceNetlistUseNetcodeAsNetname, false ) );
m_projectFileParams.push_back( new PARAM_CFG_INT( wxT( "LabSize" ), m_projectFileParams.push_back( new PARAM_CFG_INT( wxT( "LabSize" ),
&s_defaultTextSize, &s_defaultTextSize,
DEFAULT_SIZE_TEXT, 5, DEFAULT_SIZE_TEXT, 5, 1000 ) );
1000 ) );
m_projectFileParams.push_back( new PARAM_CFG_BOOL( wxT( "ERC_TestSimilarLabels" ),
&DIALOG_ERC::m_TestSimilarLabels, true ) );
return m_projectFileParams; return m_projectFileParams;
} }

View File

@ -119,9 +119,9 @@ const wxString CommentERC_V[] =
/* Look up table which gives the diag for a pair of connected pins /* Look up table which gives the diag for a pair of connected pins
* Can be modified by ERC options. * Can be modified by ERC options.
* at start up: must be loaded by DefaultDiagErc * at start up: must be loaded by DefaultDiagErc
* Can be modified in dialog ERC
*/ */
int DiagErc[PIN_NMAX][PIN_NMAX]; int DiagErc[PIN_NMAX][PIN_NMAX];
bool DiagErcTableInit; // go to true after DiagErc init
/** /**
* Default Look up table which gives the ERC error level for a pair of connected pins * Default Look up table which gives the ERC error level for a pair of connected pins
@ -196,6 +196,8 @@ int TestDuplicateSheetNames( bool aCreateMarker )
continue; continue;
// We have found a second sheet: compare names // We have found a second sheet: compare names
// we are using case insensitive comparison to avoid mistakes between
// similar names like Mysheet and mysheet
if( ( (SCH_SHEET*) item )->GetName().CmpNoCase( if( ( (SCH_SHEET*) item )->GetName().CmpNoCase(
( ( SCH_SHEET* ) test_item )->GetName() ) == 0 ) ( ( SCH_SHEET* ) test_item )->GetName() ) == 0 )
{ {
@ -502,20 +504,19 @@ void TestOthersItems( NETLIST_OBJECT_LIST* aList,
} }
} }
int NETLIST_OBJECT_LIST::CountPinsInNet( unsigned aNetStart )
int CountPinsInNet( NETLIST_OBJECT_LIST* aList, unsigned aNetStart )
{ {
int count = 0; int count = 0;
int curr_net = aList->GetItemNet( aNetStart ); int curr_net = GetItemNet( aNetStart );
/* Test pins connected to NetItemRef */ /* Test pins connected to NetItemRef */
for( unsigned item = aNetStart; item < aList->size(); item++ ) for( unsigned item = aNetStart; item < size(); item++ )
{ {
// We examine only a given net. We stop the search if the net changes // We examine only a given net. We stop the search if the net changes
if( curr_net != aList->GetItemNet( item ) ) // End of net if( curr_net != GetItemNet( item ) ) // End of net
break; break;
if( aList->GetItemType( item ) == NET_PIN ) if( GetItemType( item ) == NET_PIN )
count++; count++;
} }
@ -571,7 +572,7 @@ bool WriteDiagnosticERC( const wxString& aFullFileName )
msg << wxString::Format( _( "\n ** ERC messages: %d Errors %d Warnings %d\n" ), msg << wxString::Format( _( "\n ** ERC messages: %d Errors %d Warnings %d\n" ),
total_count, err_count, warn_count ); total_count, err_count, warn_count );
// Currently: write report unsing UTF8 (as usual in Kicad). // Currently: write report using UTF8 (as usual in Kicad).
// TODO: see if we can use the current encoding page (mainly for Windows users), // TODO: see if we can use the current encoding page (mainly for Windows users),
// Or other format (HTML?) // Or other format (HTML?)
file.Write( msg ); file.Write( msg );
@ -582,7 +583,7 @@ bool WriteDiagnosticERC( const wxString& aFullFileName )
} }
void TestLabel( NETLIST_OBJECT_LIST* aList, unsigned aNetItemRef, unsigned aStartNet ) void NETLIST_OBJECT_LIST::TestforNonOrphanLabel( unsigned aNetItemRef, unsigned aStartNet )
{ {
unsigned netItemTst = aStartNet; unsigned netItemTst = aStartNet;
int erc = 1; int erc = 1;
@ -594,24 +595,246 @@ void TestLabel( NETLIST_OBJECT_LIST* aList, unsigned aNetItemRef, unsigned aStar
continue; continue;
/* Is always in the same net? */ /* Is always in the same net? */
if( ( netItemTst == aList->size() ) if( ( netItemTst == size() )
|| ( aList->GetItemNet( aNetItemRef ) != aList->GetItemNet( netItemTst ) ) ) || ( GetItemNet( aNetItemRef ) != GetItemNet( netItemTst ) ) )
{ {
/* End Netcode found. */ /* End Netcode found. */
if( erc ) if( erc )
{ {
/* Glabel or SheetLabel orphaned. */ /* Glabel or SheetLabel orphaned. */
Diagnose( aList->GetItem( aNetItemRef ), NULL, -1, WAR ); Diagnose( GetItem( aNetItemRef ), NULL, -1, WAR );
} }
return; return;
} }
if( aList->GetItem( aNetItemRef )->IsLabelConnected( aList->GetItem( netItemTst ) ) ) if( GetItem( aNetItemRef )->IsLabelConnected( GetItem( netItemTst ) ) )
erc = 0; erc = 0;
//same thing, different order. //same thing, different order.
if( aList->GetItem( netItemTst )->IsLabelConnected( aList->GetItem( aNetItemRef ) ) ) if( GetItem( netItemTst )->IsLabelConnected( GetItem( aNetItemRef ) ) )
erc = 0; erc = 0;
} }
} }
// this code try to detect similar labels, i.e. labels which are identical
// when they are compared using case insensitive coparisons.
// A helper struct to compare NETLIST_OBJECT items by sheetpath and label texts
// for a std::set<NETLIST_OBJECT*> container
// the full text is "sheetpath+label" for local labels and "label" for global labels
struct compare_labels
{
bool operator() ( const NETLIST_OBJECT* lab1, const NETLIST_OBJECT* lab2 )
{
wxString str1 = lab1->m_SheetPath.Path() + lab1->m_Label;
wxString str2 = lab2->m_SheetPath.Path() + lab2->m_Label;
return str1.Cmp( str2 ) < 0;
}
};
struct compare_label_names
{
bool operator() ( const NETLIST_OBJECT* lab1, const NETLIST_OBJECT* lab2 )
{
return lab1->m_Label.Cmp( lab2->m_Label ) < 0;
}
};
struct compare_paths
{
bool operator() ( const NETLIST_OBJECT* lab1, const NETLIST_OBJECT* lab2 )
{
return lab1->m_SheetPath.Path().Cmp( lab2->m_SheetPath.Path() ) < 0;
}
};
// Helper functions to build the warning messages about Similar Labels:
static int countIndenticalLabels( std::vector<NETLIST_OBJECT*>& aList, NETLIST_OBJECT* aLabel );
static void SimilarLabelsDiagnose( NETLIST_OBJECT* aItemA, NETLIST_OBJECT* aItemB );
void NETLIST_OBJECT_LIST::TestforSimilarLabels()
{
// Similar labels which are different when using case sensitive comparisons
// but are equal when using case insensitive comparisons
// list of all labels (used the better item to build diag messages)
std::vector<NETLIST_OBJECT*> fullLabelList;
// list of all labels , each label appears only once (used to to detect similar labels)
std::set<NETLIST_OBJECT*, compare_labels> uniqueLabelList;
wxString msg;
// Build a list of differents labels. If inside a given sheet there are
// more than one given label, only one label is stored.
// not also the sheet labels are not taken in account for 2 reasons:
// * they are in the root sheet but they are seen only from the child sheet
// * any mismatch between child sheet hierarchical labels and the sheet label
// already detected by ERC
for( unsigned netItem = 0; netItem < size(); ++netItem )
{
switch( GetItemType( netItem ) )
{
case NET_LABEL:
case NET_BUSLABELMEMBER:
case NET_PINLABEL:
case NET_GLOBBUSLABELMEMBER:
case NET_HIERLABEL:
case NET_HIERBUSLABELMEMBER:
case NET_GLOBLABEL:
// add this label in lists
uniqueLabelList.insert( GetItem( netItem ) );
fullLabelList.push_back( GetItem( netItem ) );
break;
case NET_SHEETLABEL:
case NET_SHEETBUSLABELMEMBER:
default:
break;
}
}
// build global labels and compare
std::set<NETLIST_OBJECT*, compare_label_names> loc_labelList;
std::set<NETLIST_OBJECT*>::const_iterator it;
for( it = uniqueLabelList.begin(); it != uniqueLabelList.end(); ++it )
{
if( (*it)->IsLabelGlobal() )
loc_labelList.insert( *it );
}
// compare global labels (same label names appears only once in list)
for( it = loc_labelList.begin(); it != loc_labelList.end(); ++it )
{
std::set<NETLIST_OBJECT*>::const_iterator it_aux = it;
for( ++it_aux; it_aux != loc_labelList.end(); ++it_aux )
{
if( (*it)->m_Label.CmpNoCase( (*it_aux)->m_Label ) == 0 )
{
// Create new marker for ERC.
int cntA = countIndenticalLabels( fullLabelList, *it );
int cntB = countIndenticalLabels( fullLabelList, *it_aux );
if( cntA <= cntB )
SimilarLabelsDiagnose( (*it), (*it_aux) );
else
SimilarLabelsDiagnose( (*it_aux), (*it) );
}
}
}
// Build paths list
std::set<NETLIST_OBJECT*, compare_paths> pathsList;
for( it = uniqueLabelList.begin(); it != uniqueLabelList.end(); ++it )
pathsList.insert( *it );
// Examine each label inside a sheet path:
for( it = pathsList.begin(); it != pathsList.end(); ++it )
{
loc_labelList.clear();
std::set<NETLIST_OBJECT*>::const_iterator it_aux = uniqueLabelList.begin();
for( ; it_aux != uniqueLabelList.end(); ++it_aux )
{
if( (*it)->m_SheetPath.Path() == (*it_aux)->m_SheetPath.Path() )
loc_labelList.insert( *it_aux );
}
// at this point, loc_labelList contains labels of the current sheet path.
// Detect similar labels (same label names appears only once in list)
std::set<NETLIST_OBJECT*>::const_iterator ref_it;
for( ref_it = loc_labelList.begin(); ref_it != loc_labelList.end(); ++ref_it )
{
NETLIST_OBJECT* ref_item = *ref_it;
it_aux = ref_it;
for( ++it_aux; it_aux != loc_labelList.end(); ++it_aux )
{
// global label versus global label was already examined.
// here, at least one label must be local
if( ref_item->IsLabelGlobal() && (*it_aux)->IsLabelGlobal() )
continue;
if( ref_item->m_Label.CmpNoCase( (*it_aux)->m_Label ) == 0 )
{
// Create new marker for ERC.
int cntA = countIndenticalLabels( fullLabelList, ref_item );
int cntB = countIndenticalLabels( fullLabelList, *it_aux );
if( cntA <= cntB )
SimilarLabelsDiagnose( ref_item, (*it_aux) );
else
SimilarLabelsDiagnose( (*it_aux), ref_item );
}
}
}
}
}
// Helper function: count the number of labels identical to aLabel
// for global label: global labels in the full project
// for local label: all labels in the current sheet
static int countIndenticalLabels( std::vector<NETLIST_OBJECT*>& aList, NETLIST_OBJECT* aLabel )
{
int count = 0;
if( aLabel->IsLabelGlobal() )
{
for( unsigned netItem = 0; netItem < aList.size(); ++netItem )
{
NETLIST_OBJECT* item = aList[netItem];
if( item->IsLabelGlobal() && item->m_Label == aLabel->m_Label )
count++;
}
}
else
{
for( unsigned netItem = 0; netItem < aList.size(); ++netItem )
{
NETLIST_OBJECT* item = aList[netItem];
if( item->m_Label == aLabel->m_Label &&
item->m_SheetPath.Path() == aLabel->m_SheetPath.Path() )
count++;
}
}
return count;
}
// Helper function: creates a marker for similar labels ERC warning
static void SimilarLabelsDiagnose( NETLIST_OBJECT* aItemA, NETLIST_OBJECT* aItemB )
{
// Create new marker for ERC.
SCH_MARKER* marker = new SCH_MARKER();
marker->SetTimeStamp( GetNewTimeStamp() );
marker->SetMarkerType( MARKER_BASE::MARKER_ERC );
marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_WARNING );
SCH_SCREEN* screen = aItemA->m_SheetPath.LastScreen();
screen->Append( marker );
wxString fmt = aItemA->IsLabelGlobal() ?
_( "Global label '%s' (sheet '%s') looks like:" ) :
_( "Local label '%s' (sheet '%s') looks like:" );
wxString msg;
msg.Printf( fmt, GetChars( aItemA->m_Label ), GetChars( aItemA->m_SheetPath.PathHumanReadable() ) );
marker->SetData( aItemA->IsLabelGlobal() && aItemB->IsLabelGlobal() ?
ERCE_SIMILAR_GLBL_LABELS : ERCE_SIMILAR_LABELS,
aItemA->m_Start, msg, aItemA->m_Start );
fmt = aItemB->IsLabelGlobal() ? _( "Global label '%s' (sheet '%s')" ) :
_( "Local label '%s' (sheet '%s')" );
msg.Printf( fmt, GetChars( aItemB->m_Label ), GetChars( aItemB->m_SheetPath.PathHumanReadable() ) );
marker->SetAuxiliaryData( msg, aItemB->m_Start );
}

View File

@ -31,7 +31,7 @@
#define _ERC_H #define _ERC_H
class EDA_DRAW_PANEL; //class EDA_DRAW_PANEL;
class NETLIST_OBJECT; class NETLIST_OBJECT;
class NETLIST_OBJECT_LIST; class NETLIST_OBJECT_LIST;
@ -58,6 +58,8 @@ extern const wxString CommentERC_V[];
#define ERCE_HIERACHICAL_LABEL 6 // mismatch between hierarchical labels and pins sheets #define ERCE_HIERACHICAL_LABEL 6 // mismatch between hierarchical labels and pins sheets
#define ERCE_NOCONNECT_CONNECTED 7 // a no connect symbol is connected to more than 1 pin #define ERCE_NOCONNECT_CONNECTED 7 // a no connect symbol is connected to more than 1 pin
#define ERCE_GLOBLABEL 8 // global label not connected to any other global label #define ERCE_GLOBLABEL 8 // global label not connected to any other global label
#define ERCE_SIMILAR_LABELS 9 // 2 labels are equal fir case insensitive comparisons
#define ERCE_SIMILAR_GLBL_LABELS 10 // 2 labels are equal fir case insensitive comparisons
/* Minimal connection table */ /* Minimal connection table */
#define NPI 4 // Net with Pin isolated, this pin has type Not Connected and must be left N.C. #define NPI 4 // Net with Pin isolated, this pin has type Not Connected and must be left N.C.
@ -73,14 +75,14 @@ extern const wxString CommentERC_V[];
* *
* @param aFullFileName A wxString object containing the file name and path. * @param aFullFileName A wxString object containing the file name and path.
*/ */
extern bool WriteDiagnosticERC( const wxString& aFullFileName ); bool WriteDiagnosticERC( const wxString& aFullFileName );
/** /**
* Performs ERC testing and creates an ERC marker to show the ERC problem for aNetItemRef * Performs ERC testing and creates an ERC marker to show the ERC problem for aNetItemRef
* or between aNetItemRef and aNetItemTst. * or between aNetItemRef and aNetItemTst.
* if MinConn < 0: this is an error on labels * if MinConn < 0: this is an error on labels
*/ */
extern void Diagnose( NETLIST_OBJECT* NetItemRef, NETLIST_OBJECT* NetItemTst, void Diagnose( NETLIST_OBJECT* NetItemRef, NETLIST_OBJECT* NetItemTst,
int MinConnexion, int Diag ); int MinConnexion, int Diag );
/** /**
@ -92,27 +94,10 @@ extern void Diagnose( NETLIST_OBJECT* NetItemRef, NETLIST_OBJECT* NetItemTst,
* @param aMinConnexion = a pointer to a variable to store the minimal connection * @param aMinConnexion = a pointer to a variable to store the minimal connection
* found( NOD, DRV, NPI, NET_NC) * found( NOD, DRV, NPI, NET_NC)
*/ */
extern void TestOthersItems( NETLIST_OBJECT_LIST* aList, void TestOthersItems( NETLIST_OBJECT_LIST* aList,
unsigned aNetItemRef, unsigned aNetStart, unsigned aNetItemRef, unsigned aNetStart,
int* aMinConnexion ); int* aMinConnexion );
/**
* Counts number of pins connected on the same net.
* Used to find all pins conected to a no connect symbol
* @return the pin count of the net starting at aNetStart
* @param aNetStart = index in list of net objects of the first item
* @param aList = a reference to the list of connected objects
*/
int CountPinsInNet( NETLIST_OBJECT_LIST* aList, unsigned aNetStart );
/**
* Function TestLabel
* performs an ERC on a sheet labels to verify that it is connected to a corresponding
* sub sheet global label.
*/
extern void TestLabel( NETLIST_OBJECT_LIST* aList, unsigned aNetItemRef, unsigned aStartNet );
/** /**
* Function TestDuplicateSheetNames( ) * Function TestDuplicateSheetNames( )
* inside a given sheet, one cannot have sheets with duplicate names (file * inside a given sheet, one cannot have sheets with duplicate names (file
@ -121,7 +106,7 @@ extern void TestLabel( NETLIST_OBJECT_LIST* aList, unsigned aNetItemRef, unsigne
* @param aCreateMarker: true = create error markers in schematic, * @param aCreateMarker: true = create error markers in schematic,
* false = calculate error count only * false = calculate error count only
*/ */
extern int TestDuplicateSheetNames( bool aCreateMarker ); int TestDuplicateSheetNames( bool aCreateMarker );
#endif // _ERC_H #endif // _ERC_H

View File

@ -52,19 +52,12 @@
/** @brief Kicad can use case sensitive or case insensitive comparisons for labels /** @brief Kicad can use case sensitive or case insensitive comparisons for labels
* Currently, it uses case insensitive. * Currently, it uses case insensitive.
* Can be changed by defining LABEL_CASE_SENSITIVE (uncomment next line). * Can be changed by comment/uncomment next lines.
*/ */
//#define LABEL_CASE_SENSITIVE
/// Compiler controlled string compare function, either case independent or not:
inline int CmpLabel_KEEPCASE( const wxString& aString1, const wxString& aString2 ) inline int CmpLabel_KEEPCASE( const wxString& aString1, const wxString& aString2 )
{ {
#ifdef LABEL_CASE_SENSITIVE return aString1.Cmp( aString2 ); // case sensitive
// case specificity, the normal behavior: //return aString1.CmpNoCase( aString2 ); // case insensitive
return aString1.Cmp( aString2 );
#else
// case independence (only for guys who want that: not recommended)
return aString1.CmpNoCase( aString2 );
#endif
} }