Commit 79b6e427 authored by jean-pierre charras's avatar jean-pierre charras

Pcbnew: netlist.cpp: code cleaning. Comments added and updated

parent 1a8e4510
...@@ -269,6 +269,18 @@ public: ...@@ -269,6 +269,18 @@ public:
*/ */
void SetLastNetListRead( const wxString& aNetListFile ); void SetLastNetListRead( const wxString& aNetListFile );
/**
* Function Test_Duplicate_Missing_And_Extra_Footprints
* Build a list of duplicate, missing and extra footprints
* from the current board and a netlist netlist :
* Shows 3 lists:
* 1 - duplicate footprints on board
* 2 - missing footprints (found in netlist but not on board)
* 3 - footprints not in netlist but on board
* @param aNetlistFullFilename = the full filename netlist
*/
void Test_Duplicate_Missing_And_Extra_Footprints( const wxString& aNetlistFullFilename );
/** /**
* Function OnHotKey. * Function OnHotKey.
* ** Commands are case insensitive ** * ** Commands are case insensitive **
...@@ -1044,17 +1056,16 @@ public: ...@@ -1044,17 +1056,16 @@ public:
// netlist handling: // netlist handling:
void InstallNetlistFrame( wxDC* DC, const wxPoint& pos ); void InstallNetlistFrame( wxDC* DC );
/** /**
* Function ReadPcbNetlist * Function ReadPcbNetlist
* Update footprints (load missing footprints and delete on request extra * Update footprints (load missing footprints and delete on demand extra
* footprints) * footprints)
* Update connectivity info ( Net Name list ) * Update connectivity info, references, values and "TIME STAMP"
* Update Reference, value and "TIME STAMP"
* @param aNetlistFullFilename = netlist file name (*.net) * @param aNetlistFullFilename = netlist file name (*.net)
* @param aCmpFullFileName = cmp/footprint list file name (*.cmp) if not found, * @param aCmpFullFileName = cmp/footprint link file name (*.cmp).
* only the netlist will be used * if not found, only the netlist will be used
* @param aMessageWindow = a reference to a wxTextCtrl where to display messages. * @param aMessageWindow = a reference to a wxTextCtrl where to display messages.
* can be NULL * can be NULL
* @param aChangeFootprint if true, footprints that have changed in netlist will be changed * @param aChangeFootprint if true, footprints that have changed in netlist will be changed
...@@ -1064,20 +1075,6 @@ public: ...@@ -1064,20 +1075,6 @@ public:
* footprints from components (use after reannotation of the * footprints from components (use after reannotation of the
* schematic) * schematic)
* @return true if Ok * @return true if Ok
*
* the format of the netlist is something like:
# EESchema Netlist Version 1.0 generee le 18/5/2005-12:30:22
* (
* ( 40C08647 $noname R20 4,7K {Lib=R}
* ( 1 VCC )
* ( 2 MODB_1 )
* )
* ( 40C0863F $noname R18 4,7_k {Lib=R}
* ( 1 VCC )
* ( 2 MODA_1 )
* )
* }
* #End
*/ */
bool ReadPcbNetlist( const wxString& aNetlistFullFilename, bool ReadPcbNetlist( const wxString& aNetlistFullFilename,
const wxString& aCmpFullFileName, const wxString& aCmpFullFileName,
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
; General Product Description Definitions ; General Product Description Definitions
!define PRODUCT_NAME "KiCad" !define PRODUCT_NAME "KiCad"
!define PRODUCT_VERSION "2011.04.28" !define PRODUCT_VERSION "2011.04.29"
!define PRODUCT_WEB_SITE "http://iut-tice.ujf-grenoble.fr/kicad/" !define PRODUCT_WEB_SITE "http://iut-tice.ujf-grenoble.fr/kicad/"
!define SOURCEFORGE_WEB_SITE "http://kicad.sourceforge.net/" !define SOURCEFORGE_WEB_SITE "http://kicad.sourceforge.net/"
!define COMPANY_NAME "" !define COMPANY_NAME ""
......
...@@ -291,22 +291,15 @@ void MODULE::Flip(const wxPoint& aCentre ) ...@@ -291,22 +291,15 @@ void MODULE::Flip(const wxPoint& aCentre )
void MODULE::SetPosition( const wxPoint& newpos ) void MODULE::SetPosition( const wxPoint& newpos )
{ {
int deltaX = newpos.x - m_Pos.x; wxPoint delta = newpos - m_Pos;
int deltaY = newpos.y - m_Pos.y;
m_Pos.x += deltaX; m_Pos += delta;
m_Pos.y += deltaY; m_Reference->m_Pos += delta;
m_Value->m_Pos += delta;
m_Reference->m_Pos.x += deltaX;
m_Reference->m_Pos.y += deltaY;
m_Value->m_Pos.x += deltaX;
m_Value->m_Pos.y += deltaY;
for( D_PAD* pad = m_Pads; pad; pad = pad->Next() ) for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
{ {
pad->m_Pos.x += deltaX; pad->m_Pos += delta;
pad->m_Pos.y += deltaY;
} }
EDA_ITEM* PtStruct = m_Drawings; EDA_ITEM* PtStruct = m_Drawings;
...@@ -325,8 +318,7 @@ void MODULE::SetPosition( const wxPoint& newpos ) ...@@ -325,8 +318,7 @@ void MODULE::SetPosition( const wxPoint& newpos )
case TYPE_TEXTE_MODULE: case TYPE_TEXTE_MODULE:
{ {
TEXTE_MODULE* pt_texte = (TEXTE_MODULE*) PtStruct; TEXTE_MODULE* pt_texte = (TEXTE_MODULE*) PtStruct;
pt_texte->m_Pos.x += deltaX; pt_texte->m_Pos += delta;
pt_texte->m_Pos.y += deltaY;
break; break;
} }
...@@ -357,7 +349,7 @@ void MODULE::SetOrientation( int newangle ) ...@@ -357,7 +349,7 @@ void MODULE::SetOrientation( int newangle )
pad->m_Orient += newangle; /* change m_Orientation */ pad->m_Orient += newangle; /* change m_Orientation */
NORMALIZE_ANGLE_POS( pad->m_Orient ); NORMALIZE_ANGLE_POS( pad->m_Orient );
RotatePoint( &px, &py, (int) m_Orient ); RotatePoint( &px, &py, m_Orient );
pad->m_Pos.x = m_Pos.x + px; pad->m_Pos.x = m_Pos.x + px;
pad->m_Pos.y = m_Pos.y + py; pad->m_Pos.y = m_Pos.y + py;
} }
......
...@@ -14,13 +14,7 @@ ...@@ -14,13 +14,7 @@
#include "dialog_netlist.h" #include "dialog_netlist.h"
extern void TestFor_Duplicate_Missing_And_Extra_Footprints( wxWindow* frame, void PCB_EDIT_FRAME::InstallNetlistFrame( wxDC* DC )
const wxString& NetlistFullFilename,
BOARD* Pcb );
void PCB_EDIT_FRAME::InstallNetlistFrame( wxDC* DC, const wxPoint& pos )
{ {
/* Setup the netlist file name to the last net list file read or the board file /* Setup the netlist file name to the last net list file read or the board file
* name if no last file read is not set. * name if no last file read is not set.
...@@ -62,7 +56,6 @@ DIALOG_NETLIST::DIALOG_NETLIST( PCB_EDIT_FRAME* aParent, wxDC * aDC, ...@@ -62,7 +56,6 @@ DIALOG_NETLIST::DIALOG_NETLIST( PCB_EDIT_FRAME* aParent, wxDC * aDC,
Init(); Init();
if( GetSizer() )
GetSizer()->SetSizeHints( this ); GetSizer()->SetSizeHints( this );
} }
...@@ -117,8 +110,7 @@ void DIALOG_NETLIST::OnReadNetlistFileClick( wxCommandEvent& event ) ...@@ -117,8 +110,7 @@ void DIALOG_NETLIST::OnReadNetlistFileClick( wxCommandEvent& event )
void DIALOG_NETLIST::OnTestFootprintsClick( wxCommandEvent& event ) void DIALOG_NETLIST::OnTestFootprintsClick( wxCommandEvent& event )
{ {
TestFor_Duplicate_Missing_And_Extra_Footprints( this, m_NetlistFilenameCtrl->GetValue(), m_Parent->Test_Duplicate_Missing_And_Extra_Footprints( m_NetlistFilenameCtrl->GetValue() );
m_Parent->GetBoard() );
} }
......
...@@ -217,7 +217,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) ...@@ -217,7 +217,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break; break;
case ID_GET_NETLIST: case ID_GET_NETLIST:
InstallNetlistFrame( &dc, wxPoint( -1, -1 ) ); InstallNetlistFrame( &dc );
break; break;
case ID_GET_TOOLS: case ID_GET_TOOLS:
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
/** /**
* These strings are used in menus and tools, that do the same command * These strings are used in menus and tools, that do the same command
* But they are internatinalized, and therefore must be created * But they are internationalized, and therefore must be created
* at run time, on the fly. * at run time, on the fly.
* So they cannot be static. * So they cannot be static.
* *
......
...@@ -3,11 +3,10 @@ ...@@ -3,11 +3,10 @@
/***********************/ /***********************/
/* /*
* Function to read a netlist. While reading a netlist: * Functions to read a netlist. They are:
* - Load new footprints * - Load new footprints and nitialize net info
* - Initialize net info
* - Test for missing or extra footprints * - Test for missing or extra footprints
* - Recalculate ratsnest * - Recalculate full connectivity info
* *
* Important remark: * Important remark:
* When reading a netlist Pcbnew must identify existing footprints (link * When reading a netlist Pcbnew must identify existing footprints (link
...@@ -15,16 +14,15 @@ ...@@ -15,16 +14,15 @@
* This identification can be from 2 fields: * This identification can be from 2 fields:
* - The reference (U2, R5 ..): this is the normal mode * - The reference (U2, R5 ..): this is the normal mode
* - The Time Stamp (Signature Temporelle), useful after a full schematic * - The Time Stamp (Signature Temporelle), useful after a full schematic
* reannotation * reannotation because references can be changed for the same schematic.
* because references can be changed for the same schematic. * So when reading a netlist ReadPcbNetlist() can use references or time stamps
* So when reading a netlist this identification ReadPcbNetlist() has * to identify footprints on board and the corresponding component in schematic.
* selection of the way to identify footprints.
* If we want to fully reannotate a schematic this sequence must be used * If we want to fully reannotate a schematic this sequence must be used
* SAVE your board !!! * 1 - SAVE your board !!!
* Create and read the netlist (to ensure all info is correct, mainly * 2 - Create and read the netlist (to ensure all info is correct, mainly
* references and time stamp) * references and time stamp)
* Reannotate the schematic (references will be changed, but not time stamp) * 3 - Reannotate the schematic (references will be changed, but not time stamps )
* Recreate and read the new netlist using the Time Stamp identification * 4 - Recreate and read the new netlist using the Time Stamp identification
* (that reinit the new references) * (that reinit the new references)
*/ */
...@@ -45,18 +43,21 @@ ...@@ -45,18 +43,21 @@
#include "dialog_netlist.h" #include "dialog_netlist.h"
// constants used by ReadPcbNetlist(): // constants used by ReadPcbNetlist():
#define TESTONLY 1 #define TESTONLY true
#define READMODULE 0 #define READMODULE false
/*
class MODULEtoLOAD * Helper class, to store new footprints info found in netlist.
* New footprints are footprints relative to new components found in netlist
*/
class MODULE_INFO
{ {
public: public:
wxString m_LibName; wxString m_LibName;
wxString m_CmpName; wxString m_CmpName;
wxString m_TimeStampPath; wxString m_TimeStampPath;
public: MODULEtoLOAD( const wxString& libname, public: MODULE_INFO( const wxString& libname,
const wxString& cmpname, const wxString& cmpname,
const wxString& timestamp_path ) const wxString& timestamp_path )
{ {
...@@ -65,65 +66,158 @@ public: MODULEtoLOAD( const wxString& libname, ...@@ -65,65 +66,158 @@ public: MODULEtoLOAD( const wxString& libname,
m_TimeStampPath = timestamp_path; m_TimeStampPath = timestamp_path;
} }
~MODULEtoLOAD() { }; ~MODULE_INFO() { };
}; };
/*
* Helper class, to read a netlist.
*/
class NETLIST_READER
{
private:
PCB_EDIT_FRAME* m_pcbframe; // the main pcbnew frame
wxTextCtrl* m_messageWindow; // a textctrl to show messages (can be NULL)
wxString m_netlistFullName; // The full netlist filename
wxString m_cmplistFullName; // The full component/footprint association filename
MODULE* m_currModule; // The footprint currently being read in netlist
std::vector <MODULE_INFO*> m_newModulesList; // The list of new footprints,
// found in netlist, but not on board
// (must be loaded from libraries)
bool m_useCmpFile; // true to use .cmp files as component/footprint file link
// false to use netlist only to know component/footprint link
public:
bool m_UseTimeStamp; // Set to true to identify footprits by time stamp
// false to use schematic reference
bool m_ChangeFootprints; // Set to true to change existing footprints to new ones
// when netlist gives a different footprint name
public: NETLIST_READER( PCB_EDIT_FRAME* aFrame, wxTextCtrl* aMessageWindow = NULL )
{
m_pcbframe = aFrame;
m_messageWindow = aMessageWindow;
m_UseTimeStamp = false;
m_ChangeFootprints = false;
m_useCmpFile = true;
}
~NETLIST_READER()
{
// Free new modules list:
for( unsigned ii = 0; ii < m_newModulesList.size(); ii++ )
delete m_newModulesList[ii];
m_newModulesList.clear();
}
/**
* Function ReadNetList
* The main function to read a netlist, and update the board
* @param aFile = the already opened file (will be closed by ReadNetList)
* @param aNetlistFileName = the netlist full file name (*.net file)
* @param aCmplistFileName = the auxiliary component full file name (*.cmp file)
* If the aCmplistFileName file is not given or not found,
* the netlist is used to know the component/footprint link.
*/
bool ReadNetList( FILE* aFile, const wxString& aNetlistFileName,
const wxString& aCmplistFileName );
static int BuildFootprintsListFromNetlistFile( /**
const wxString& aNetlistFullFilename, * Function BuildFootprintListFromNetlist
* Fill aBufName with footprints references read from the netlist.
* @param aNetlistFilename = netlist full file name
* @param aBufName = wxArrayString to fill with footprint names
* @return the footprint count, or -1 if netlist file cannot opened
*/
int BuildFootprintListFromNetlist( const wxString& aNetlistFilename,
wxArrayString& aBufName ); wxArrayString& aBufName );
static FILE * OpenNetlistFile( const wxString& aFullFileName );
static int SetPadNetName( char* Text,
MODULE* Module,
wxTextCtrl* aMessageWindow );
static int ReadListeModules( const wxString& CmpFullFileName,
const wxString* RefCmp,
const wxString* TimeStampPath,
wxString& NameModule );
static MODULE* ReadNetModule( PCB_EDIT_FRAME* aFrame,
wxTextCtrl* aMessageWindow,
const wxString& CmpFullFileName,
char* Text,
int* UseFichCmp,
int TstOnly,
bool Select_By_Timestamp,
bool aChangeFootprint );
static void LoadListeModules( PCB_EDIT_FRAME* aPcbFrame );
/**
* function RemoveExtraFootprints
* Remove (delete) not locked footprints found on board, but not in netlist
* @param aNetlistFileName = the netlist full file name (*.net file)
*/
void RemoveExtraFootprints( const wxString& aNetlistFileName );
private:
/**
* Function SetPadNetName
* Update a pad netname using the current footprint
* from the netlist (line format: ( <pad number> <net name> ) )
* @param aText = current line read from netlist
*/
bool SetPadNetName( char* aText );
/**
* Function ReadNetlistModuleDescr
* Read the full description of a footprint, from the netlist
* and update the corresponding module.
* @param aTstOnly bool to switch between 2 modes:
* aTstOnly = false:
* if the module does not exist, it is added to m_newModulesList
* aTstOnly = true:
* if the module does not exist, it is loaded and added to the board module list
* @param aText contains the first line of description
* This function uses m_useFichCmp as a flag to know the footprint name:
* If true: component file *.cmp is used
* If false: the netlist only is used
* This flag is reset to false if the .cmp file is not found
*/
MODULE* ReadNetlistModuleDescr( char* aText, bool aTstOnly );
/**
* Function loadNewModules
* Load from libraries new modules found in netlist and add them to the current Board.
*/
void loadNewModules();
static std::vector < MODULEtoLOAD* > s_ModuleToLoad_List; /**
* function readModulesComponentsTable
* read the *.cmp file ( filename in m_cmplistFullName )
* giving the equivalence beteween modules and components
* @return true and the module name in aModuleName, false if not found
*
* @param aCmpIdent = component identification: schematic reference or time stamp
* @param aModuleName the footprint name corresponding to the component identification
*/
bool readModulesComponentsTable( const wxString* aCmpIdent, wxString& aModuleName );
};
/** /**
* Function OpenNetlistFile * Function OpenNetlistFile
* used to open a netlist file * used to open a netlist file
*/ */
FILE * OpenNetlistFile( const wxString& aFullFileName ) static FILE* OpenNetlistFile( const wxString& aFullFileName )
{ {
if( aFullFileName.IsEmpty() ) if( aFullFileName.IsEmpty() )
return FALSE; /* No filename: exit */ return false; /* No filename: exit */
FILE * netfile = wxFopen( aFullFileName, wxT( "rt" ) ); FILE* file = wxFopen( aFullFileName, wxT( "rt" ) );
if( netfile == NULL ) if( file == NULL )
{ {
wxString msg; wxString msg;
msg.Printf( _( "Netlist file %s not found" ), GetChars( aFullFileName ) ); msg.Printf( _( "Netlist file %s not found" ), GetChars( aFullFileName ) );
DisplayError( NULL, msg ); wxMessageBox( msg );
} }
return netfile; return file;
} }
/* Function to sort the footprint list. /* Function to sort the footprint list.
* the given list is sorted by name * the given list is sorted by name
*/ */
static bool SortByLibName( MODULEtoLOAD* ref, MODULEtoLOAD* cmp ) static bool SortByLibName( MODULE_INFO* ref, MODULE_INFO* cmp )
{ {
int ii = ref->m_LibName.CmpNoCase( cmp->m_LibName ); int ii = ref->m_LibName.CmpNoCase( cmp->m_LibName );
return ii > 0; return ii > 0;
} }
/** /**
* Function ReadPcbNetlist * Function ReadPcbNetlist
* Update footprints (load missing footprints and delete on request extra * Update footprints (load missing footprints and delete on request extra
...@@ -132,27 +226,16 @@ static bool SortByLibName( MODULEtoLOAD* ref, MODULEtoLOAD* cmp ) ...@@ -132,27 +226,16 @@ static bool SortByLibName( MODULEtoLOAD* ref, MODULEtoLOAD* cmp )
* Update Reference, value and "TIME STAMP" * Update Reference, value and "TIME STAMP"
* @param aNetlistFullFilename = netlist file name (*.net) * @param aNetlistFullFilename = netlist file name (*.net)
* @param aCmpFullFileName = cmp/footprint list file name (*.cmp) if not found, * @param aCmpFullFileName = cmp/footprint list file name (*.cmp) if not found,
* @param aMessageWindow - Please document me. * @param aMessageWindow = a wxTextCtrl to print messages (can be NULL).
* @param aChangeFootprint - Please document me. * @param aChangeFootprint = true to change existing footprints
* @param aDeleteBadTracks - Please document me. * when the netlist gives a different footprint.
* @param aDeleteExtraFootprints - Please document me. * false to keep existing footprints
* @param aSelect_By_Timestamp - Please document me. * @param aDeleteBadTracks - true to erase erroneous tracks after updating connectivity info.
* @param aDeleteExtraFootprints - true to remove unlocked footprints found on board but not in netlist.
* @param aSelect_By_Timestamp - true to use schematic timestamps instead of schematic references
* to identify footprints on board
* (Must be used after a full reannotation in schematic).
* @return true if Ok * @return true if Ok
* only the netlist will be used
*
* the format of the netlist is something like:
* \# EESchema Netlist Version 1.0 generee le 18/5/2005-12:30:22
* (
* ( 40C08647 $noname R20 4,7K {Lib=R}
* ( 1 VCC )
* ( 2 MODB_1 )
* )
* ( 40C0863F $noname R18 4,7_k {Lib=R}
* ( 1 VCC )
* ( 2 MODA_1 )
* )
* }
* \#End
*/ */
bool PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFullFilename, bool PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFullFilename,
const wxString& aCmpFullFileName, const wxString& aCmpFullFileName,
...@@ -162,13 +245,8 @@ bool PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFullFilename, ...@@ -162,13 +245,8 @@ bool PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFullFilename,
bool aDeleteExtraFootprints, bool aDeleteExtraFootprints,
bool aSelect_By_Timestamp ) bool aSelect_By_Timestamp )
{ {
int State, Comment; FILE* netfile = OpenNetlistFile( aNetlistFullFilename );
MODULE* Module = NULL;
D_PAD* PtPad;
char* Text;
int UseFichCmp = 1;
FILE * netfile = OpenNetlistFile( aNetlistFullFilename );
if( !netfile ) if( !netfile )
return false; return false;
...@@ -179,6 +257,11 @@ bool PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFullFilename, ...@@ -179,6 +257,11 @@ bool PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFullFilename,
wxString msg; wxString msg;
msg.Printf( _( "Reading Netlist \"%s\"" ), GetChars( aNetlistFullFilename ) ); msg.Printf( _( "Reading Netlist \"%s\"" ), GetChars( aNetlistFullFilename ) );
aMessageWindow->AppendText( msg + wxT( "\n" ) ); aMessageWindow->AppendText( msg + wxT( "\n" ) );
if( ! aCmpFullFileName.IsEmpty() )
{
msg.Printf( _( "Using component/footprint link file \"%s\"" ), GetChars( aCmpFullFileName ) );
aMessageWindow->AppendText( msg + wxT( "\n" ) );
}
} }
// Clear undo and redo lists to avoid inconsistencies between lists // Clear undo and redo lists to avoid inconsistencies between lists
...@@ -190,51 +273,143 @@ bool PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFullFilename, ...@@ -190,51 +273,143 @@ bool PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFullFilename,
GetBoard()->m_Status_Pcb = 0; GetBoard()->m_Status_Pcb = 0;
SetCurItem( NULL ); SetCurItem( NULL );
State = 0;
Comment = 0;
s_ModuleToLoad_List.clear();
wxBusyCursor dummy; // Shows an hourglass while calculating wxBusyCursor dummy; // Shows an hourglass while calculating
NETLIST_READER netList_Reader( this, aMessageWindow );
netList_Reader.m_UseTimeStamp = aSelect_By_Timestamp;
netList_Reader.m_ChangeFootprints = aChangeFootprint;
netList_Reader.ReadNetList( netfile, aNetlistFullFilename, aCmpFullFileName );
// Delete footprints not found in netlist:
if( aDeleteExtraFootprints )
{
netList_Reader.RemoveExtraFootprints( aNetlistFullFilename );
}
// Rebuild the board connectivity:
Compile_Ratsnest( NULL, true );
if( GetBoard()->m_Track )
{
if( aDeleteBadTracks ) // Remove erroneous tracks
{
RemoveMisConnectedTracks( NULL );
Compile_Ratsnest( NULL, true );
}
}
GetBoard()->DisplayInfo( this );
DrawPanel->Refresh();
return true;
}
/* function RemoveExtraFootprints
* Remove (delete) not locked footprints found on board, but not in netlist
*/
void NETLIST_READER::RemoveExtraFootprints( const wxString& aNetlistFileName )
{
wxArrayString modulesInNetlist;
// Build list of modules in the netlist
int modulesCount =
BuildFootprintListFromNetlist( aNetlistFileName, modulesInNetlist );
if( modulesCount == 0 )
return;
MODULE* NextModule;
MODULE* Module = m_pcbframe->GetBoard()->m_Modules;
bool ask_user = true;
for( ; Module != NULL; Module = NextModule )
{
int ii;
NextModule = Module->Next();
if( Module->m_ModuleStatus & MODULE_is_LOCKED )
continue;
for( ii = 0; ii < modulesCount; ii++ )
{
if( Module->m_Reference->m_Text.CmpNoCase( modulesInNetlist[ii] ) == 0 )
break; /* Module is found in net list. */
}
if( ii == modulesCount ) // Module not found in netlist.
{
if( ask_user )
{
ask_user = false;
if( !IsOK( NULL,
_( "Ok to delete not locked footprints not found in netlist?" ) ) )
break;
}
Module->DeleteStructure();
}
}
}
/*
* Function ReadNetlist
* Update footprints (load missing footprints and delete on request extra
* footprints)
* Update References, values, "TIME STAMP" and connectivity data
* return true if Ok
*
* the format of the netlist is something like:
* # EESchema Netlist Version 1.0 generee le 18/5/2005-12:30:22
* (
* ( 40C08647 $noname R20 4,7K {Lib=R}
* ( 1 VCC )
* ( 2 MODB_1 )
* )
* ( 40C0863F $noname R18 4,7_k {Lib=R}
* ( 1 VCC )
* ( 2 MODA_1 )
* )
* }
* #End
*/
bool NETLIST_READER::ReadNetList( FILE* aFile,
const wxString& aNetlistFileName,
const wxString& aCmplistFileName )
{
int State = 0;
int Comment = 0;
m_netlistFullName = aNetlistFileName;
m_cmplistFullName = aCmplistFileName;
m_useCmpFile = true;
/* First, read the netlist: Build the list of footprints to load (new /* First, read the netlist: Build the list of footprints to load (new
* footprints) * footprints)
*/ */
FILE_LINE_READER netlistReader( netfile, aNetlistFullFilename ); FILE_LINE_READER netlineReader( aFile, m_netlistFullName ); // netlineReader dtor will close aFile
while( netlistReader.ReadLine() ) while( netlineReader.ReadLine() )
{ {
char* Line = netlistReader.Line(); char* line = StrPurge( netlineReader.Line() );
Text = StrPurge( Line );
if( Comment ) /* Comments in progress */ if( Comment ) /* Comments in progress */
{ {
// Test for end of the current comment // Test for end of the current comment
if( ( Text = strchr( Text, '}' ) ) == NULL ) if( ( line = strchr( line, '}' ) ) == NULL )
continue; continue;
Comment = 0; Comment = 0;
} }
if( *Text == '{' ) /* Start Comment */ if( *line == '{' ) /* Start Comment */
{ {
Comment = 1; Comment = 1;
if( ( Text = strchr( Text, '}' ) ) == NULL ) if( ( line = strchr( line, '}' ) ) == NULL )
continue; continue;
} }
if( *Text == '(' ) if( *line == '(' )
State++; State++;
if( *Text == ')' ) if( *line == ')' )
State--; State--;
if( State == 2 ) if( State == 2 )
{ {
Module = ReadNetModule( this, ReadNetlistModuleDescr( line, TESTONLY );
aMessageWindow,
aCmpFullFileName,
Text,
&UseFichCmp,
TESTONLY,
aSelect_By_Timestamp,
aChangeFootprint );
continue; continue;
} }
...@@ -245,66 +420,46 @@ bool PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFullFilename, ...@@ -245,66 +420,46 @@ bool PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFullFilename,
} }
/* Load new footprints */ /* Load new footprints */
if( s_ModuleToLoad_List.size() ) loadNewModules();
{
LoadListeModules( this );
// Free module list:
for( unsigned ii = 0; ii < s_ModuleToLoad_List.size(); ii++ )
{
delete s_ModuleToLoad_List[ii];
}
s_ModuleToLoad_List.clear();
}
/* Second read , All footprints are on board. /* Second read , All footprints are on board.
* One must update the schematic info (pad netnames) * One must update the schematic info (pad netnames)
*/ */
netlistReader.Rewind(); netlineReader.Rewind();
while( netlistReader.ReadLine() ) m_currModule = NULL;
while( netlineReader.ReadLine() )
{ {
char* Line = netlistReader.Line(); char* line = StrPurge( netlineReader.Line() );
Text = StrPurge( Line );
if( Comment ) // we are reading a comment if( Comment ) // we are reading a comment
{ {
// Test for end of the current comment // Test for end of the current comment
if( ( Text = strchr( Text, '}' ) ) == NULL ) if( ( line = strchr( line, '}' ) ) == NULL )
continue; continue;
Comment = 0; Comment = 0;
} }
if( *Text == '{' ) // this is the beginning of a comment if( *line == '{' ) // this is the beginning of a comment
{ {
Comment = 1; Comment = 1;
if( ( Text = strchr( Text, '}' ) ) == NULL ) if( ( line = strchr( line, '}' ) ) == NULL )
continue; continue;
} }
if( *Text == '(' ) if( *line == '(' )
State++; State++;
if( *Text == ')' ) if( *line == ')' )
State--; State--;
if( State == 2 ) if( State == 2 )
{ {
Module = ReadNetModule( this, m_currModule = ReadNetlistModuleDescr( line, READMODULE );
aMessageWindow, if( m_currModule == NULL ) // the module could not be created (perhaps
aCmpFullFileName,
Text,
&UseFichCmp,
READMODULE,
aSelect_By_Timestamp,
aChangeFootprint );
if( Module == NULL ) // the module could not be created (perhaps
// footprint not found in library) // footprint not found in library)
{
continue; continue;
}
else /* clear pads netnames */ else /* clear pads netnames */
{ {
PtPad = Module->m_Pads; D_PAD* PtPad = m_currModule->m_Pads;
for( ; PtPad != NULL; PtPad = (D_PAD*) PtPad->Next() ) for( ; PtPad != NULL; PtPad = PtPad->Next() )
{ {
PtPad->SetNetname( wxEmptyString ); PtPad->SetNetname( wxEmptyString );
} }
...@@ -314,103 +469,36 @@ bool PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFullFilename, ...@@ -314,103 +469,36 @@ bool PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFullFilename,
if( State >= 3 ) if( State >= 3 )
{ {
if( Module ) if( m_currModule )
{ SetPadNetName( line );
SetPadNetName( Text, Module, aMessageWindow );
}
State--; State--;
} }
} }
// Delete footprints not found in netlist:
if( aDeleteExtraFootprints )
{
wxArrayString ModuleListFromNetlist;
// Build list of modules in the netlist
int NbModulesNetListe =
BuildFootprintsListFromNetlistFile( aNetlistFullFilename,
ModuleListFromNetlist );
if( NbModulesNetListe )
{
MODULE* NextModule;
Module = GetBoard()->m_Modules;
bool ask_for_confirmation = true;
for( ; Module != NULL; Module = NextModule )
{
int ii;
NextModule = Module->Next();
if( Module->m_ModuleStatus & MODULE_is_LOCKED )
continue;
for( ii = 0; ii < NbModulesNetListe; ii++ )
{
if( Module->m_Reference->m_Text.CmpNoCase(
ModuleListFromNetlist[ii] ) == 0 )
{
break; /* Module is already in net list. */
}
}
if( ii == NbModulesNetListe ) /* Module not found in
* net list. */
{
if( ask_for_confirmation )
{
ask_for_confirmation = false;
if( !IsOK( NULL,
_( "Ok to delete footprints not in netlist?" ) ) )
break;
}
Module->DeleteStructure();
}
}
}
}
// Rebuild the board connectivity:
Compile_Ratsnest( NULL, true );
if( GetBoard()->m_Track )
{
if( aDeleteBadTracks ) // Remove erroneous tracks
{
RemoveMisConnectedTracks( NULL );
Compile_Ratsnest( NULL, true );
}
}
GetBoard()->DisplayInfo( this );
DrawPanel->Refresh();
return true; return true;
} }
/* Load the description of a footprint, net list type Pcbnew /* Function ReadNetlistModuleDescr
* Read the full description of a footprint, from the netlist
* and update the corresponding module. * and update the corresponding module.
* * param aTstOnly bool to switch between 2 modes:
* If TstOnly == 0 if the module does not exist, it is responsible * If aTstOnly == false:
* If TstOnly! = 0 if the module does not exist, it is added to the list * if the module does not exist, it is added to m_newModulesList
* Load modules has * If aTstOnly = true:
* Text contains the first line of description * if the module does not exist, it is loaded and added to the board module list
* UseFichCmp is a flag * param aText contains the first line of description
* If! = 0, file components. CMP will be used * This function uses m_useFichCmp as a flag to know the footprint name:
* Is reset to 0 if the file does not exist * If true: component file *.cmp is used
* * If false: the netlist only is used
* This flag is reset to false if the .cmp file is not found
* Analyze lines like: * Analyze lines like:
* ($ 40C08647 noname R20 4.7 K Lib = (R) * ($ 40C08647 noname R20 4.7 K Lib = R
* (1 VCC) * (1 VCC)
* (2 MODB_1) * (2 MODB_1)
*/ */
MODULE* ReadNetModule( PCB_EDIT_FRAME* aFrame, MODULE* NETLIST_READER::ReadNetlistModuleDescr( char* aText, bool aTstOnly )
wxTextCtrl* aMessageWindow,
const wxString& aCmpFullFileName,
char* Text,
int* UseFichCmp,
int TstOnly,
bool aSelect_By_Timestamp,
bool aChangeFootprint )
{ {
MODULE* Module;
char* text; char* text;
wxString TimeStampPath; wxString TimeStampPath;
wxString TextNameLibMod; wxString TextNameLibMod;
...@@ -419,9 +507,8 @@ MODULE* ReadNetModule( PCB_EDIT_FRAME* aFrame, ...@@ -419,9 +507,8 @@ MODULE* ReadNetModule( PCB_EDIT_FRAME* aFrame,
wxString NameLibCmp; wxString NameLibCmp;
int Error = 0; int Error = 0;
char Line[1024]; char Line[1024];
bool Found;
strcpy( Line, Text ); strcpy( Line, aText );
TextValeur = wxT( "~" ); TextValeur = wxT( "~" );
...@@ -449,44 +536,35 @@ MODULE* ReadNetModule( PCB_EDIT_FRAME* aFrame, ...@@ -449,44 +536,35 @@ MODULE* ReadNetModule( PCB_EDIT_FRAME* aFrame,
return NULL; return NULL;
/* Test if module is already loaded. */ /* Test if module is already loaded. */
Module = aFrame->GetBoard()->m_Modules; wxString * identMod = &TextCmpName;
MODULE* NextModule; if( m_UseTimeStamp )
identMod = &TimeStampPath;
for( Found = false; Module != NULL; Module = NextModule ) MODULE* Module = m_pcbframe->GetBoard()->m_Modules;
MODULE* NextModule;
bool found = false;
for( ; Module != NULL; Module = NextModule )
{ {
NextModule = Module->Next(); NextModule = Module->Next();
if( aSelect_By_Timestamp ) /* identification by time stamp */ if( m_UseTimeStamp ) /* identification by time stamp */
{ {
if( TimeStampPath.CmpNoCase( Module->m_Path ) == 0 ) if( TimeStampPath.CmpNoCase( Module->m_Path ) == 0 )
Found = true; found = true;
} }
else /* identification by Reference */ else /* identification by Reference */
{ {
if( TextCmpName.CmpNoCase( Module->m_Reference->m_Text ) == 0 ) if( TextCmpName.CmpNoCase( Module->m_Reference->m_Text ) == 0 )
Found = true; found = true;
} }
if( Found ) // test footprint matching for existing modules: current if( found ) // test footprint matching for existing modules: current
// m_LibRef and module name in netlist must match
{ {
if( TstOnly != TESTONLY ) // m_LibRef and module name in netlist must match
if( aTstOnly != TESTONLY )
{ {
NameLibCmp = TextNameLibMod; // Use footprint name from netlist NameLibCmp = TextNameLibMod; // Use footprint name from netlist
if( *UseFichCmp ) // Try to get footprint name from .cmp file if( m_useCmpFile ) // Try to get footprint name from .cmp file
{
if( aSelect_By_Timestamp )
{
*UseFichCmp = ReadListeModules( aCmpFullFileName,
NULL,
&TimeStampPath,
NameLibCmp );
}
else
{ {
*UseFichCmp = ReadListeModules( aCmpFullFileName, m_useCmpFile = readModulesComponentsTable( identMod, NameLibCmp );
&TextCmpName,
NULL,
NameLibCmp );
}
} }
/* Module mismatch: current module and module specified in /* Module mismatch: current module and module specified in
...@@ -494,30 +572,31 @@ MODULE* ReadNetModule( PCB_EDIT_FRAME* aFrame, ...@@ -494,30 +572,31 @@ MODULE* ReadNetModule( PCB_EDIT_FRAME* aFrame,
*/ */
if( Module->m_LibRef.CmpNoCase( NameLibCmp ) != 0 ) if( Module->m_LibRef.CmpNoCase( NameLibCmp ) != 0 )
{ {
if( aChangeFootprint ) // footprint exchange allowed. if( m_ChangeFootprints ) // footprint exchange allowed.
{ {
MODULE* NewModule = MODULE* NewModule =
aFrame->Get_Librairie_Module( wxEmptyString, m_pcbframe->Get_Librairie_Module( wxEmptyString,
NameLibCmp, NameLibCmp,
true ); true );
if( NewModule ) /* Change old module to the new module if( NewModule ) /* Change old module to the new module
* (and delete the old one) */ * (and delete the old one) */
{ {
aFrame->Exchange_Module( Module, NewModule, NULL ); m_pcbframe->Exchange_Module( Module, NewModule, NULL );
Module = NewModule; Module = NewModule;
} }
} }
else else
{ {
wxString msg; wxString msg;
msg.Printf( _( "Component \"%s\": Mismatch! module \ msg.Printf(
is [%s] and netlist said [%s]\n" ), _(
"Component \"%s\": Mismatch! module is [%s] and netlist said [%s]\n" ),
GetChars( TextCmpName ), GetChars( TextCmpName ),
GetChars( Module->m_LibRef ), GetChars( Module->m_LibRef ),
GetChars( NameLibCmp ) ); GetChars( NameLibCmp ) );
if( aMessageWindow ) if( m_messageWindow )
aMessageWindow->AppendText( msg ); m_messageWindow->AppendText( msg );
} }
} }
} }
...@@ -529,39 +608,25 @@ is [%s] and netlist said [%s]\n" ), ...@@ -529,39 +608,25 @@ is [%s] and netlist said [%s]\n" ),
if( Module == NULL ) /* a new module must be loaded from libs */ if( Module == NULL ) /* a new module must be loaded from libs */
{ {
NameLibCmp = TextNameLibMod; // Use footprint name from netlist NameLibCmp = TextNameLibMod; // Use footprint name from netlist
if( *UseFichCmp ) // Try to get footprint name from .cmp file if( m_useCmpFile ) // Try to get footprint name from .cmp file
{
if( aSelect_By_Timestamp == 1 )
{
*UseFichCmp = ReadListeModules( aCmpFullFileName,
NULL,
&TimeStampPath,
NameLibCmp );
}
else
{ {
*UseFichCmp = ReadListeModules( aCmpFullFileName, m_useCmpFile = readModulesComponentsTable( identMod, NameLibCmp );
&TextCmpName,
NULL,
NameLibCmp );
} }
}
if( TstOnly == TESTONLY ) if( aTstOnly == TESTONLY )
{ {
MODULEtoLOAD* newMod; MODULE_INFO* newMod;
newMod = new MODULEtoLOAD( NameLibCmp, TextCmpName, TimeStampPath ); newMod = new MODULE_INFO( NameLibCmp, TextCmpName, TimeStampPath );
s_ModuleToLoad_List.push_back(newMod); m_newModulesList.push_back( newMod );
} }
else else
{ {
if( aMessageWindow ) if( m_messageWindow )
{ {
wxString msg; wxString msg;
msg.Printf( _( "Component [%s] not found" ), msg.Printf( _( "Component [%s] not found" ),
GetChars( TextCmpName ) ); GetChars( TextCmpName ) );
aMessageWindow->AppendText( msg + wxT( "\n" ) ); m_messageWindow->AppendText( msg + wxT( "\n" ) );
} }
} }
return NULL; /* The module could not be loaded. */ return NULL; /* The module could not be loaded. */
...@@ -576,43 +641,39 @@ is [%s] and netlist said [%s]\n" ), ...@@ -576,43 +641,39 @@ is [%s] and netlist said [%s]\n" ),
} }
/** /*
* Function SetPadNetName * Function SetPadNetName
* Update a pad netname in a given footprint * Update a pad netname using the current footprint
* @param Text = Text from netlist (format: (pad = net) ) * Line format: ( <pad number> <net name> )
* @param Module = the given footprint * Param aText = current line read from netlist
* @param aMessageWindow = a wxTextCtrl to print error and warning message
* (can be NULL)
*/ */
int SetPadNetName( char* Text, bool NETLIST_READER::SetPadNetName( char* aText )
MODULE* Module,
wxTextCtrl* aMessageWindow )
{ {
D_PAD* pad; D_PAD* pad;
char* TextPinName, * TextNetName; char* TextPinName, * TextNetName;
int Error = 0; bool found;
bool trouve; bool error = false;
char Line[256]; char Line[256];
wxString Msg;
if( Module == NULL ) if( m_currModule == NULL )
return 0; return false;
strcpy( Line, Text ); strcpy( Line, aText );
if( ( TextPinName = strtok( Line, " ()\t\n" ) ) == NULL ) if( ( TextPinName = strtok( Line, " ()\t\n" ) ) == NULL )
Error = 1; error = true;
if( ( TextNetName = strtok( NULL, " ()\t\n" ) ) == NULL ) if( ( TextNetName = strtok( NULL, " ()\t\n" ) ) == NULL )
Error = 1; error = true;
if( Error ) if( error )
return 0; return 0;
pad = Module->m_Pads; trouve = FALSE; pad = m_currModule->m_Pads;
for( ; pad != NULL; pad = (D_PAD*) pad->Next() ) found = false;
for( ; pad != NULL; pad = pad->Next() )
{ {
if( strnicmp( TextPinName, pad->m_Padname, 4 ) == 0 ) if( strnicmp( TextPinName, pad->m_Padname, 4 ) == 0 )
{ {
trouve = true; found = true;
if( *TextNetName != '?' ) if( *TextNetName != '?' )
pad->SetNetname( FROM_UTF8( TextNetName ) ); pad->SetNetname( FROM_UTF8( TextNetName ) );
else else
...@@ -620,19 +681,20 @@ int SetPadNetName( char* Text, ...@@ -620,19 +681,20 @@ int SetPadNetName( char* Text,
} }
} }
if( !trouve ) if( !found )
{ {
if( aMessageWindow ) if( m_messageWindow )
{ {
wxString msg;
wxString pin_name = FROM_UTF8( TextPinName ); wxString pin_name = FROM_UTF8( TextPinName );
Msg.Printf( _( "Module [%s]: Pad [%s] not found" ), msg.Printf( _( "Module [%s]: Pad [%s] not found" ),
GetChars( Module->m_Reference->m_Text ), GetChars( m_currModule->m_Reference->m_Text ),
GetChars( pin_name ) ); GetChars( pin_name ) );
aMessageWindow->AppendText( Msg + wxT( "\n" ) ); m_messageWindow->AppendText( msg + wxT( "\n" ) );
} }
} }
return trouve; return found;
} }
...@@ -673,58 +735,55 @@ MODULE* PCB_EDIT_FRAME::ListAndSelectModuleName( void ) ...@@ -673,58 +735,55 @@ MODULE* PCB_EDIT_FRAME::ListAndSelectModuleName( void )
} }
/** /*
* Function TestFor_Duplicate_Missing_And_Extra_Footprints * Function Test_Duplicate_Missing_And_Extra_Footprints
* Build a list from the given board and netlist : * Build a list of duplicate, missing and extra footprints
* 1 - for duplicate footprints on board * from the current board and a netlist netlist :
* 2 - for missing footprints * Shows 3 lists:
* 3 - for footprints not in netlist * 1 - duplicate footprints on board
* @param aFrame = current active frame * 2 - missing footprints (found in netlist but not on board)
* @param aNetlistFullFilename = the given netlist * 3 - footprints not in netlist but on board
* @param aPcb = the given board * @param aNetlistFullFilename = the full filename netlist
*/ */
void TestFor_Duplicate_Missing_And_Extra_Footprints( wxWindow* aFrame, void PCB_EDIT_FRAME::Test_Duplicate_Missing_And_Extra_Footprints(
const wxString& aNetlistFullFilename, const wxString& aNetlistFullFilename )
BOARD* aPcb )
#define MAX_LEN_TXT 32
{ {
#define MAX_LEN_TXT 32
int ii; int ii;
MODULE* Module, * pt_aux;
int NbModulesNetListe, nberr = 0; int NbModulesNetListe, nberr = 0;
wxArrayString tmp; wxArrayString tmp;
wxArrayString list; wxArrayString list;
if( aPcb->m_Modules == NULL ) if( GetBoard()->m_Modules == NULL )
{ {
DisplayInfoMessage( aFrame, _( "No modules" ) ); DisplayInfoMessage( this, _( "No modules" ) );
return; return;
} }
/* Build the list of references of the net list modules. */ /* Build the list of references of the net list modules. */
NETLIST_READER netList_Reader( this );
NbModulesNetListe = BuildFootprintsListFromNetlistFile( aNetlistFullFilename, tmp ); NbModulesNetListe = netList_Reader.BuildFootprintListFromNetlist( aNetlistFullFilename, tmp );
if( NbModulesNetListe < 0 ) if( NbModulesNetListe < 0 )
return; /* File not found */ return; /* File not found */
if( NbModulesNetListe == 0 ) if( NbModulesNetListe == 0 )
{ {
DisplayError( aFrame, _( "No modules in NetList" ) ); wxMessageBox( _( "No modules in NetList" ) );
return; return;
} }
/* Search for duplicate footprints. */ /* Search for duplicate footprints. */
list.Add( _( "Duplicates" ) ); list.Add( _( "Duplicates" ) );
Module = aPcb->m_Modules; MODULE* Module = GetBoard()->m_Modules;
for( ; Module != NULL; Module = Module->Next() ) for( ; Module != NULL; Module = Module->Next() )
{ {
pt_aux = Module->Next(); MODULE* pt_aux = Module->Next();
for( ; pt_aux != NULL; pt_aux = pt_aux->Next() ) for( ; pt_aux != NULL; pt_aux = pt_aux->Next() )
{ {
if( Module->m_Reference->m_Text.CmpNoCase( pt_aux->m_Reference-> m_Text ) == 0 ) if( Module->m_Reference->m_Text.CmpNoCase( pt_aux->m_Reference->m_Text ) == 0 )
{ {
list.Add( Module->m_Reference->m_Text ); list.Add( Module->m_Reference->m_Text );
nberr++; nberr++;
...@@ -738,7 +797,7 @@ void TestFor_Duplicate_Missing_And_Extra_Footprints( wxWindow* aFrame, ...@@ -738,7 +797,7 @@ void TestFor_Duplicate_Missing_And_Extra_Footprints( wxWindow* aFrame,
for( ii = 0; ii < NbModulesNetListe; ii++ ) for( ii = 0; ii < NbModulesNetListe; ii++ )
{ {
Module = (MODULE*) aPcb->m_Modules; Module = (MODULE*) GetBoard()->m_Modules;
for( ; Module != NULL; Module = Module->Next() ) for( ; Module != NULL; Module = Module->Next() )
{ {
...@@ -758,8 +817,7 @@ void TestFor_Duplicate_Missing_And_Extra_Footprints( wxWindow* aFrame, ...@@ -758,8 +817,7 @@ void TestFor_Duplicate_Missing_And_Extra_Footprints( wxWindow* aFrame,
/* Search for modules not in net list. */ /* Search for modules not in net list. */
list.Add( _( "Not in Netlist:" ) ); list.Add( _( "Not in Netlist:" ) );
Module = (MODULE*) aPcb->m_Modules; Module = GetBoard()->m_Modules;
for( ; Module != NULL; Module = Module->Next() ) for( ; Module != NULL; Module = Module->Next() )
{ {
for( ii = 0; ii < NbModulesNetListe; ii++ ) for( ii = 0; ii < NbModulesNetListe; ii++ )
...@@ -777,7 +835,7 @@ void TestFor_Duplicate_Missing_And_Extra_Footprints( wxWindow* aFrame, ...@@ -777,7 +835,7 @@ void TestFor_Duplicate_Missing_And_Extra_Footprints( wxWindow* aFrame,
} }
} }
wxSingleChoiceDialog dlg( aFrame, wxEmptyString, _( "Check Modules" ), list, NULL, wxSingleChoiceDialog dlg( this, wxEmptyString, _( "Check Modules" ), list, NULL,
wxCHOICEDLG_STYLE & ~wxCANCEL ); wxCHOICEDLG_STYLE & ~wxCANCEL );
dlg.ShowModal(); dlg.ShowModal();
...@@ -785,30 +843,31 @@ void TestFor_Duplicate_Missing_And_Extra_Footprints( wxWindow* aFrame, ...@@ -785,30 +843,31 @@ void TestFor_Duplicate_Missing_And_Extra_Footprints( wxWindow* aFrame,
/** /**
* Function BuildFootprintsListFromNetlistFile * Function BuildFootprintListFromNetlist
* Fill BufName with footprints names read from the netlist. * Fill BufName with footprints names read from the netlist.
* @param aNetlistFullFilename = netlist file name * @param aNetlistFilename = netlist full file name
* @param aBufName = wxArrayString to fill with footprint names * @param aBufName = wxArrayString to fill with footprint names
* @return Footprint count, or -1 if netlist file cannot opened * @return Footprint count, or -1 if netlist file cannot opened
*/ */
int BuildFootprintsListFromNetlistFile( const wxString& aNetlistFullFilename, int NETLIST_READER::BuildFootprintListFromNetlist( const wxString& aNetlistFilename,
wxArrayString& aBufName ) wxArrayString& aBufName )
{ {
int nb_modules_lus; int nb_modules_lus;
int State, Comment; int State, Comment;
char * Text, * LibModName; char* Text, * LibModName;
FILE * netfile = OpenNetlistFile( aNetlistFullFilename ); FILE* netfile = OpenNetlistFile( aNetlistFilename );
if( !netfile )
if( netfile == NULL )
return -1; return -1;
FILE_LINE_READER netlistReader( netfile, aNetlistFullFilename ); FILE_LINE_READER netlineReader( netfile, aNetlistFilename );
char* Line = netlistReader; char* Line = netlineReader;
State = 0; Comment = 0; State = 0; Comment = 0;
nb_modules_lus = 0; nb_modules_lus = 0;
while( netlistReader.ReadLine( ) ) while( netlineReader.ReadLine() )
{ {
Text = StrPurge( Line ); Text = StrPurge( Line );
if( Comment ) if( Comment )
...@@ -855,18 +914,13 @@ int BuildFootprintsListFromNetlistFile( const wxString& aNetlistFullFilename, ...@@ -855,18 +914,13 @@ int BuildFootprintsListFromNetlistFile( const wxString& aNetlistFullFilename,
/* /*
* Get the file CMP giving the equivalence modules / components * function readModulesComponentsTable
* Returns: * read the *.cmp file ( filename in m_cmplistFullName )
* If this file exists returns: * giving the equivalence modules / components
* 1 and the module name in NameModule * return true and the module name in aModuleName, false if not found
* -1 If not found in module file
* Otherwise 0;
*
* Call settings:
* RefCmp (NULL if selection by TimeStamp)
* TimeStamp (time signature if it exists, NULL otherwise)
* Pointer to the buffer receiving the name of the module
* *
* param aCmpIdent = component identification: schematic reference or time stamp
* param aModuleName the footprint name corresponding to the component identification
* Example file: * Example file:
* *
* Cmp-Mod V01 Genere by Pcbnew 29/10/2003-13: 11:6 * * Cmp-Mod V01 Genere by Pcbnew 29/10/2003-13: 11:6 *
...@@ -885,129 +939,122 @@ int BuildFootprintsListFromNetlistFile( const wxString& aNetlistFullFilename, ...@@ -885,129 +939,122 @@ int BuildFootprintsListFromNetlistFile( const wxString& aNetlistFullFilename,
* EndCmp * EndCmp
* *
*/ */
int ReadListeModules( const wxString& CmpFullFileName, const wxString* RefCmp, bool NETLIST_READER::readModulesComponentsTable( const wxString* aCmpIdent, wxString& aModuleName )
const wxString* TimeStamp, wxString& NameModule )
{ {
wxString refcurrcmp, timestamp, idmod; wxString refcurrcmp; // Stores value read from line like Reference = BUS1;
char* ptcar; wxString timestamp; // Stores value read from line like TimeStamp = /32307DE2/AA450F67;
FILE* FichCmp; wxString idmod; // Stores value read from line like IdModule = CP6;
if( (RefCmp == NULL) && (TimeStamp == 0) ) FILE* cmpFile = wxFopen( m_cmplistFullName, wxT( "rt" ) );
return 0;
FichCmp = wxFopen( CmpFullFileName, wxT( "rt" ) ); if( cmpFile == NULL )
if( FichCmp == NULL )
{ {
wxString msg; wxString msg;
msg.Printf( _( "File <%s> not found, use Netlist for lib module selection" ), msg.Printf( _( "File <%s> not found, use Netlist for lib module selection" ),
GetChars( CmpFullFileName ) ); GetChars( m_cmplistFullName ) );
DisplayError( NULL, msg, 20 ); DisplayError( NULL, msg, 20 );
return 0; return false;
} }
FILE_LINE_READER netlistReader( FichCmp, CmpFullFileName ); FILE_LINE_READER netlineReader( cmpFile, m_cmplistFullName ); // netlineReader dtor will close cmpFile
char* Line = netlistReader; wxString buffer;
wxString value;
while( netlistReader.ReadLine() ) while( netlineReader.ReadLine() )
{ {
if( strnicmp( Line, "BeginCmp", 8 ) != 0 ) buffer = FROM_UTF8( netlineReader.Line() );
if( ! buffer.StartsWith( wxT("BeginCmp") ) )
continue; continue;
/* Begin component description. */ /* Begin component description. */
refcurrcmp.Empty(); refcurrcmp.Empty();
idmod.Empty(); idmod.Empty();
timestamp.Empty(); timestamp.Empty();
while( netlistReader.ReadLine() ) while( netlineReader.ReadLine() )
{ {
if( strnicmp( Line, "EndCmp", 6 ) == 0 ) buffer = FROM_UTF8( netlineReader.Line() );
if( buffer.StartsWith( wxT("EndCmp") ) )
break; break;
if( strnicmp( Line, "Reference =", 11 ) == 0 ) // store string value, stored between '=' and ';' delimiters.
value = buffer.AfterFirst( '=' );
value = value.BeforeLast( ';');
value.Trim(true);
value.Trim(false);
if( buffer.StartsWith( wxT("Reference") ) )
{ {
ptcar = Line + 11; refcurrcmp = value;
ptcar = strtok( ptcar, " =;\t\n" );
if( ptcar )
refcurrcmp = FROM_UTF8( ptcar );
continue; continue;
} }
if( strnicmp( Line, "IdModule =", 11 ) == 0 ) if( buffer.StartsWith( wxT("IdModule =" ) ) )
{ {
ptcar = Line + 11; idmod = value;
ptcar = strtok( ptcar, " =;\t\n" );
if( ptcar )
idmod = FROM_UTF8( ptcar );
continue; continue;
} }
if( strnicmp( Line, "TimeStamp =", 11 ) == 0 )
if( buffer.StartsWith( wxT("TimeStamp =" ) ) )
{ {
ptcar = Line + 11; timestamp = value;
ptcar = strtok( ptcar, " =;\t\n" ); continue;
if( ptcar )
timestamp = FROM_UTF8( ptcar );
} }
} }
/* Check if component read is valid. */ // Check if this component is the right component:
if( RefCmp ) if( m_UseTimeStamp ) // Use schematic timestamp to locate the footprint
{ {
if( RefCmp->CmpNoCase( refcurrcmp ) == 0 ) // Found! if( aCmpIdent->CmpNoCase( timestamp ) == 0 && !timestamp.IsEmpty() )
{ { // Found
NameModule = idmod; aModuleName = idmod;
return 1; return true;
} }
} }
else if( TimeStamp ) else // Use schematic reference to locate the footprint
{ {
if( TimeStamp->CmpNoCase( timestamp ) == 0 if( aCmpIdent->CmpNoCase( refcurrcmp ) == 0 ) // Found!
&& !timestamp.IsEmpty() ) // Found
{ {
NameModule = idmod; aModuleName = idmod;
return 1; return true;
} }
} }
} }
return -1; return true;
} }
/* Load new modules from library. /* Load new modules from library.
* If a module is being loaded it is duplicated, which avoids reading * If a new module is already loaded it is duplicated, which avoids multiple
* unnecessary library. * unnecessary disk or net access to read libraries.
*/ */
void LoadListeModules( PCB_EDIT_FRAME* aPcbFrame ) void NETLIST_READER::loadNewModules()
{ {
MODULEtoLOAD* ref, * cmp; MODULE_INFO* ref, * cmp;
MODULE* Module = NULL; MODULE* Module = NULL;
wxPoint ModuleBestPosition; wxPoint ModuleBestPosition;
BOARD* pcb = m_pcbframe->GetBoard();
if( s_ModuleToLoad_List.size() == 0 ) if( m_newModulesList.size() == 0 )
return; return;
sort( s_ModuleToLoad_List.begin(), s_ModuleToLoad_List.end(), SortByLibName ); sort( m_newModulesList.begin(), m_newModulesList.end(), SortByLibName );
// Calculate the footprint "best" position: // Calculate the footprint "best" position:
if( aPcbFrame->GetBoard()->ComputeBoundingBox( true ) ) if( pcb->ComputeBoundingBox( true ) )
{ {
ModuleBestPosition.x = ModuleBestPosition = pcb->m_BoundaryBox.GetEnd();
aPcbFrame->GetBoard()->m_BoundaryBox.GetRight() + 5000; ModuleBestPosition.y += 5000;
ModuleBestPosition.y =
aPcbFrame->GetBoard()->m_BoundaryBox.GetBottom() + 10000;
} }
else
ModuleBestPosition = wxPoint( 0, 0 );
ref = cmp = s_ModuleToLoad_List[0]; ref = cmp = m_newModulesList[0];
for( unsigned ii = 0; ii < s_ModuleToLoad_List.size(); ii++ ) for( unsigned ii = 0; ii < m_newModulesList.size(); ii++ )
{ {
cmp = s_ModuleToLoad_List[ii]; cmp = m_newModulesList[ii];
if( (ii == 0) || ( ref->m_LibName != cmp->m_LibName) ) if( (ii == 0) || ( ref->m_LibName != cmp->m_LibName) )
{ {
/* New footprint : must be loaded from a library */ /* New footprint : must be loaded from a library */
Module = aPcbFrame->Get_Librairie_Module( wxEmptyString, Module = m_pcbframe->Get_Librairie_Module( wxEmptyString,
cmp->m_LibName, cmp->m_LibName,
FALSE ); false );
ref = cmp; ref = cmp;
if( Module == NULL ) if( Module == NULL )
{ {
...@@ -1030,14 +1077,13 @@ void LoadListeModules( PCB_EDIT_FRAME* aPcbFrame ) ...@@ -1030,14 +1077,13 @@ void LoadListeModules( PCB_EDIT_FRAME* aPcbFrame )
{ {
/* Footprint already loaded from a library, duplicate it (faster) /* Footprint already loaded from a library, duplicate it (faster)
*/ */
MODULE* newmodule;
if( Module == NULL ) if( Module == NULL )
continue; /* Module does not exist in library. */ continue; /* Module does not exist in library. */
newmodule = new MODULE( aPcbFrame->GetBoard() ); MODULE* newmodule = new MODULE( pcb );
newmodule->Copy( Module ); newmodule->Copy( Module );
aPcbFrame->GetBoard()->Add( newmodule, ADD_APPEND ); pcb->Add( newmodule, ADD_APPEND );
Module = newmodule; Module = newmodule;
Module->m_Reference->m_Text = cmp->m_CmpName; Module->m_Reference->m_Text = cmp->m_CmpName;
...@@ -1046,4 +1092,3 @@ void LoadListeModules( PCB_EDIT_FRAME* aPcbFrame ) ...@@ -1046,4 +1092,3 @@ void LoadListeModules( PCB_EDIT_FRAME* aPcbFrame )
} }
} }
} }
release version: release version:
2011 apr 28 2011 apr 29
files (.zip,.tgz): files (.zip,.tgz):
kicad-2011-04-28 kicad-2011-04-29
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment