2009-04-24 07:36:36 +00:00
|
|
|
/***********************/
|
|
|
|
/* PCBNEW: netlist.cpp */
|
|
|
|
/***********************/
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
|
|
/*
|
2009-04-24 07:36:36 +00:00
|
|
|
* Function to read a netlist. Whele readint a netlis:
|
|
|
|
* - Load new footprints
|
|
|
|
* - Initialise net info
|
|
|
|
* - Test for missing or extra footprints
|
|
|
|
* - Recalculate ratsnest
|
2008-02-19 00:28:42 +00:00
|
|
|
*
|
2009-04-24 07:36:36 +00:00
|
|
|
* Important remark:
|
|
|
|
* When reading a netlist Pcbnew must identify existing footprints (link between existing footprints an components in netlist)
|
|
|
|
* This identification can be from 2 fields:
|
|
|
|
* - The reference (U2, R5 ..): this is the normal mode
|
|
|
|
* - The Time Stamp (Signature Temporelle), useful after a full schematic reannotation
|
|
|
|
* because references can be changed for the same schematic.
|
|
|
|
* So when reading a netlist this identification ReadPcbNetlist() has aselection of the way to identify footprints.
|
|
|
|
* If we want to fully reannotate a schematic this sequence must be used
|
|
|
|
* SAVE your board !!!
|
|
|
|
* Create and read the netlist (to ensure all info is correct, mainly references and time stamp)
|
|
|
|
* Reannotate the schematic (references will be changed, but not time stamp)
|
|
|
|
* Recreate and read the new netlist using the Time Stamp identification (that reinit the new references)
|
2007-08-20 19:33:15 +00:00
|
|
|
*/
|
2007-06-05 12:10:51 +00:00
|
|
|
#include "fctsys.h"
|
|
|
|
#include "common.h"
|
2009-02-04 15:25:03 +00:00
|
|
|
#include "class_drawpanel.h"
|
|
|
|
#include "confirm.h"
|
|
|
|
#include "kicad_string.h"
|
|
|
|
#include "gestfich.h"
|
2007-06-05 12:10:51 +00:00
|
|
|
#include "pcbnew.h"
|
2009-07-30 11:04:07 +00:00
|
|
|
#include "wxPcbStruct.h"
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2009-04-24 07:36:36 +00:00
|
|
|
#include "dialog_netlist.h"
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2009-04-24 07:36:36 +00:00
|
|
|
#include "protos.h"
|
2008-03-22 18:08:44 +00:00
|
|
|
|
2009-04-24 07:36:36 +00:00
|
|
|
// constants used by ReadPcbNetlist():
|
|
|
|
#define TESTONLY 1
|
|
|
|
#define READMODULE 0
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
|
|
/* Structures locales */
|
2009-04-24 07:36:36 +00:00
|
|
|
class MODULEtoLOAD
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
|
|
|
public:
|
2009-04-24 07:36:36 +00:00
|
|
|
wxString m_LibName;
|
|
|
|
wxString m_CmpName;
|
|
|
|
wxString m_TimeStampPath;
|
|
|
|
MODULEtoLOAD* m_Next;
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
|
|
public:
|
2008-02-19 00:28:42 +00:00
|
|
|
MODULEtoLOAD( const wxString& libname,
|
|
|
|
const wxString& cmpname,
|
2009-04-24 07:36:36 +00:00
|
|
|
const wxString& timestamp_path )
|
|
|
|
{
|
|
|
|
m_LibName = libname;
|
|
|
|
m_CmpName = cmpname;
|
|
|
|
m_TimeStampPath = timestamp_path;
|
|
|
|
m_Next = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-09-01 12:00:30 +00:00
|
|
|
~MODULEtoLOAD() { };
|
2008-12-06 08:21:54 +00:00
|
|
|
|
2009-04-24 07:36:36 +00:00
|
|
|
MODULEtoLOAD* Next() const { return (MODULEtoLOAD*) m_Next; }
|
|
|
|
void SetNext( MODULEtoLOAD* next ) { m_Next = next; }
|
2007-06-05 12:10:51 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* Fonctions locales : */
|
2009-04-24 07:36:36 +00:00
|
|
|
static void SortListModulesToLoadByLibname( int NbModules );
|
|
|
|
static int BuildFootprintsListFromNetlistFile( const wxString& aNetlistFullFilename,
|
|
|
|
wxArrayString& aBufName );
|
|
|
|
static bool OpenNetlistFile( const wxString& aFullFileName );
|
|
|
|
static void AddToList( const wxString& NameLibCmp,
|
|
|
|
const wxString& NameCmp,
|
|
|
|
const wxString& TimeStampPath );
|
|
|
|
static int SetPadNetName( wxWindow* aFrame,
|
|
|
|
char* Text,
|
|
|
|
MODULE* Module,
|
|
|
|
wxTextCtrl* aMessageWindow );
|
|
|
|
static int ReadListeModules( const wxString& CmpFullFileName,
|
|
|
|
const wxString* RefCmp,
|
|
|
|
const wxString* TimeStampPath,
|
|
|
|
wxString& NameModule );
|
|
|
|
static MODULE* ReadNetModule( WinEDA_PcbFrame* aFrame,
|
|
|
|
wxTextCtrl* aMessageWindow,
|
|
|
|
const wxString& CmpFullFileName,
|
|
|
|
char* Text,
|
|
|
|
int* UseFichCmp,
|
|
|
|
int TstOnly,
|
|
|
|
bool Select_By_Timestamp,
|
|
|
|
bool aChangeFootprint );
|
2009-08-19 14:19:35 +00:00
|
|
|
static void LoadListeModules( WinEDA_PcbFrame* aPcbFrame );
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* Variables locales */
|
2007-08-20 19:33:15 +00:00
|
|
|
static int s_NbNewModules;
|
|
|
|
static MODULEtoLOAD* s_ModuleToLoad_List;
|
|
|
|
FILE* source;
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
|
|
|
2008-03-22 18:08:44 +00:00
|
|
|
/************************************************************************/
|
|
|
|
bool OpenNetlistFile( const wxString& aFullFileName )
|
|
|
|
/************************************************************************/
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2009-04-24 07:36:36 +00:00
|
|
|
/** function OpenNetlistFile
|
|
|
|
* used to open a netlist file
|
2007-08-20 19:33:15 +00:00
|
|
|
*/
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2008-03-22 18:08:44 +00:00
|
|
|
if( aFullFileName.IsEmpty() )
|
|
|
|
return FALSE; /* No filename: exit */
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2008-03-22 18:08:44 +00:00
|
|
|
source = wxFopen( aFullFileName, wxT( "rt" ) );
|
2007-08-20 19:33:15 +00:00
|
|
|
if( source == 0 )
|
|
|
|
{
|
2008-03-22 18:08:44 +00:00
|
|
|
wxString msg;
|
|
|
|
msg.Printf( _( "Netlist file %s not found" ), aFullFileName.GetData() );
|
|
|
|
DisplayError( NULL, msg );
|
2007-08-20 19:33:15 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2009-04-24 07:36:36 +00:00
|
|
|
return true;
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-22 18:08:44 +00:00
|
|
|
/*******************************************************************************/
|
|
|
|
void ReadPcbNetlist( WinEDA_PcbFrame* aFrame,
|
|
|
|
const wxString& aNetlistFullFilename,
|
|
|
|
const wxString& aCmpFullFileName,
|
|
|
|
wxTextCtrl* aMessageWindow,
|
|
|
|
bool aChangeFootprint,
|
|
|
|
bool aDeleteBadTracks,
|
|
|
|
bool aDeleteExtraFootprints,
|
2009-04-24 07:36:36 +00:00
|
|
|
bool aSelect_By_Timestamp )
|
2008-03-22 18:08:44 +00:00
|
|
|
/********************************************************************************/
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2009-04-24 07:36:36 +00:00
|
|
|
/** Function ReadPcbNetlist
|
|
|
|
* Update footprints (load missing footprints and delete on request extra footprints)
|
|
|
|
* Update connectivity info ( Net Name list )
|
|
|
|
* Update Reference, value and "TIME STAMP"
|
|
|
|
* @param aNetlistFullFilename = netlist file name (*.net)
|
|
|
|
* @param aCmpFullFileName = cmp/footprint list file name (*.cmp) if not found, only the netmist will be used
|
2008-02-19 00:28:42 +00:00
|
|
|
*
|
2009-04-24 07:36:36 +00:00
|
|
|
* the format of the netlist is something like:
|
2007-08-20 19:33:15 +00:00
|
|
|
# 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 )
|
|
|
|
* )
|
|
|
|
* }
|
2009-04-24 07:36:36 +00:00
|
|
|
* #End
|
2007-08-20 19:33:15 +00:00
|
|
|
*/
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2009-04-24 07:36:36 +00:00
|
|
|
int LineNum, State, Comment;
|
|
|
|
MODULE* Module = NULL;
|
|
|
|
D_PAD* PtPad;
|
|
|
|
char Line[256];
|
|
|
|
char* Text;
|
|
|
|
int UseFichCmp = 1;
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2008-03-22 18:08:44 +00:00
|
|
|
if( !OpenNetlistFile( aNetlistFullFilename ) )
|
2007-08-20 19:33:15 +00:00
|
|
|
return;
|
|
|
|
|
2008-03-22 18:08:44 +00:00
|
|
|
if( aMessageWindow )
|
2009-04-24 07:36:36 +00:00
|
|
|
{
|
|
|
|
wxString msg;
|
|
|
|
msg.Printf( _( "Reading Netlist \"%s\"" ), GetChars( aNetlistFullFilename ) );
|
|
|
|
aMessageWindow->AppendText( msg + wxT( "\n" ) );
|
|
|
|
}
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2009-08-03 07:55:08 +00:00
|
|
|
// Clear undo and redo lists to avoid inconsistencies between lists
|
|
|
|
aFrame->GetScreen()->ClearUndoRedoList();
|
|
|
|
|
2008-04-17 16:25:29 +00:00
|
|
|
aFrame->GetScreen()->SetModify();
|
2009-08-03 07:55:08 +00:00
|
|
|
aFrame->GetBoard()->m_Status_Pcb = 0;
|
|
|
|
State = 0; LineNum = 0; Comment = 0;
|
2007-08-20 19:33:15 +00:00
|
|
|
s_NbNewModules = 0;
|
|
|
|
|
2009-04-24 07:36:36 +00:00
|
|
|
wxBusyCursor dummy; // Shows an hourglass while calculating
|
2008-03-22 18:08:44 +00:00
|
|
|
|
2009-04-24 07:36:36 +00:00
|
|
|
/* First, read the netlist: Build the list of footprints to load (new footprints)
|
2007-08-20 19:33:15 +00:00
|
|
|
*/
|
|
|
|
while( GetLine( source, Line, &LineNum ) )
|
|
|
|
{
|
|
|
|
Text = StrPurge( Line );
|
|
|
|
|
2008-03-22 18:08:44 +00:00
|
|
|
if( Comment ) /* Comments in progress */
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
|
|
|
if( ( Text = strchr( Text, '}' ) ) == NULL )
|
|
|
|
continue;
|
|
|
|
Comment = 0;
|
|
|
|
}
|
2008-03-22 18:08:44 +00:00
|
|
|
if( *Text == '{' ) /* Start Comment */
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
|
|
|
Comment = 1;
|
|
|
|
if( ( Text = strchr( Text, '}' ) ) == NULL )
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( *Text == '(' )
|
|
|
|
State++;
|
2008-02-19 00:28:42 +00:00
|
|
|
|
2007-08-20 19:33:15 +00:00
|
|
|
if( *Text == ')' )
|
|
|
|
State--;
|
|
|
|
|
|
|
|
if( State == 2 )
|
|
|
|
{
|
2008-03-22 18:08:44 +00:00
|
|
|
Module = ReadNetModule( aFrame,
|
2009-04-24 07:36:36 +00:00
|
|
|
aMessageWindow,
|
|
|
|
aCmpFullFileName,
|
|
|
|
Text,
|
|
|
|
&UseFichCmp,
|
|
|
|
TESTONLY,
|
|
|
|
aSelect_By_Timestamp,
|
|
|
|
aChangeFootprint );
|
2007-08-20 19:33:15 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( State >= 3 ) /* la ligne de description d'un pad est ici non analysee */
|
|
|
|
{
|
|
|
|
State--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-03-22 18:08:44 +00:00
|
|
|
/* Load new footprints */
|
2007-08-20 19:33:15 +00:00
|
|
|
if( s_NbNewModules )
|
|
|
|
{
|
2009-08-19 14:19:35 +00:00
|
|
|
LoadListeModules( aFrame );
|
2007-08-20 19:33:15 +00:00
|
|
|
|
|
|
|
// Free module list:
|
|
|
|
MODULEtoLOAD* item, * next_item;
|
|
|
|
for( item = s_ModuleToLoad_List; item != NULL; item = next_item )
|
|
|
|
{
|
|
|
|
next_item = item->Next();
|
|
|
|
delete item;
|
|
|
|
}
|
|
|
|
|
|
|
|
s_ModuleToLoad_List = NULL;
|
|
|
|
}
|
|
|
|
|
2008-03-22 18:08:44 +00:00
|
|
|
/* Second read , All footprints are on board, one must update the schematic info (pad netnames) */
|
2007-08-20 19:33:15 +00:00
|
|
|
fseek( source, 0, SEEK_SET ); LineNum = 0;
|
|
|
|
while( GetLine( source, Line, &LineNum ) )
|
|
|
|
{
|
|
|
|
Text = StrPurge( Line );
|
|
|
|
|
2009-04-24 07:36:36 +00:00
|
|
|
if( Comment ) /* we are reading a commment */
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2009-04-24 07:36:36 +00:00
|
|
|
if( ( Text = strchr( Text, '}' ) ) == NULL ) /* this is the end of a comment */
|
2007-08-20 19:33:15 +00:00
|
|
|
continue;
|
|
|
|
Comment = 0;
|
|
|
|
}
|
2009-04-24 07:36:36 +00:00
|
|
|
if( *Text == '{' ) /* this is the beginning of a comment */
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
|
|
|
Comment = 1;
|
|
|
|
if( ( Text = strchr( Text, '}' ) ) == NULL )
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( *Text == '(' )
|
|
|
|
State++;
|
|
|
|
if( *Text == ')' )
|
|
|
|
State--;
|
|
|
|
|
|
|
|
if( State == 2 )
|
|
|
|
{
|
2008-03-22 18:08:44 +00:00
|
|
|
Module = ReadNetModule( aFrame,
|
2009-04-24 07:36:36 +00:00
|
|
|
aMessageWindow,
|
|
|
|
aCmpFullFileName,
|
|
|
|
Text,
|
|
|
|
&UseFichCmp,
|
|
|
|
READMODULE,
|
|
|
|
aSelect_By_Timestamp,
|
|
|
|
aChangeFootprint );
|
|
|
|
if( Module == NULL ) // the module could not be created (perhaps footprint not found in library)
|
|
|
|
{
|
2007-08-20 19:33:15 +00:00
|
|
|
continue;
|
|
|
|
}
|
2009-04-24 07:36:36 +00:00
|
|
|
else /* clear pads netnames */
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
|
|
|
PtPad = Module->m_Pads;
|
2008-11-24 06:53:43 +00:00
|
|
|
for( ; PtPad != NULL; PtPad = (D_PAD*) PtPad->Next() )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2008-12-14 19:45:05 +00:00
|
|
|
PtPad->SetNetname( wxEmptyString );
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( State >= 3 )
|
|
|
|
{
|
|
|
|
if( Module )
|
|
|
|
{
|
2009-04-24 07:36:36 +00:00
|
|
|
SetPadNetName( NULL, Text, Module, aMessageWindow );
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
State--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose( source );
|
|
|
|
|
2008-03-22 18:08:44 +00:00
|
|
|
// Delete footprints not found in netlist:
|
2009-04-24 07:36:36 +00:00
|
|
|
if( aDeleteExtraFootprints )
|
2008-03-22 18:08:44 +00:00
|
|
|
{
|
2009-04-24 07:36:36 +00:00
|
|
|
wxArrayString ModuleListFromNetlist;
|
|
|
|
/* Build list of modules in the netlist */
|
|
|
|
int NbModulesNetListe = BuildFootprintsListFromNetlistFile(
|
|
|
|
aNetlistFullFilename,
|
|
|
|
ModuleListFromNetlist );
|
2008-03-22 18:08:44 +00:00
|
|
|
if( NbModulesNetListe )
|
|
|
|
{
|
2009-04-24 07:36:36 +00:00
|
|
|
MODULE* NextModule;
|
2009-01-05 05:21:35 +00:00
|
|
|
Module = aFrame->GetBoard()->m_Modules;
|
2009-04-24 07:36:36 +00:00
|
|
|
bool ask_for_confirmation = true;
|
2008-03-22 18:08:44 +00:00
|
|
|
for( ; Module != NULL; Module = NextModule )
|
|
|
|
{
|
|
|
|
int ii;
|
|
|
|
NextModule = Module->Next();
|
2009-04-24 07:36:36 +00:00
|
|
|
if( (Module->m_ModuleStatus & MODULE_is_LOCKED) )
|
2008-03-22 18:08:44 +00:00
|
|
|
continue;
|
|
|
|
for( ii = 0; ii < NbModulesNetListe; ii++ )
|
|
|
|
{
|
|
|
|
if( Module->m_Reference->m_Text.CmpNoCase(
|
|
|
|
ModuleListFromNetlist[ii] ) == 0 )
|
|
|
|
{
|
|
|
|
break; /* Module trouve en netliste */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( ii == NbModulesNetListe ) /* Module not found in netlist */
|
|
|
|
{
|
2009-04-24 07:36:36 +00:00
|
|
|
if( ask_for_confirmation )
|
2008-03-22 18:08:44 +00:00
|
|
|
{
|
|
|
|
ask_for_confirmation = false;
|
2009-04-24 07:36:36 +00:00
|
|
|
if( !IsOK( NULL, _( "Ok to delete footprints not in netlist ?" ) ) )
|
2008-03-22 18:08:44 +00:00
|
|
|
break;
|
|
|
|
}
|
2009-08-19 14:19:35 +00:00
|
|
|
Module->DeleteStructure();
|
2008-03-22 18:08:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Rebuild the connectivity */
|
2009-04-24 07:36:36 +00:00
|
|
|
aFrame->Compile_Ratsnest( NULL, true );
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2009-01-05 05:21:35 +00:00
|
|
|
if( aFrame->GetBoard()->m_Track )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2008-03-22 18:08:44 +00:00
|
|
|
if( aDeleteBadTracks ) // Remove erroneous tracks
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2009-04-24 07:36:36 +00:00
|
|
|
Netliste_Controle_piste( aFrame, NULL, true );
|
|
|
|
aFrame->Compile_Ratsnest( NULL, true );
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-03-22 18:08:44 +00:00
|
|
|
aFrame->DrawPanel->Refresh();
|
2009-04-17 08:51:02 +00:00
|
|
|
aFrame->GetBoard()->DisplayInfo( aFrame );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/****************************************************************************/
|
2008-03-22 18:08:44 +00:00
|
|
|
MODULE* ReadNetModule( WinEDA_PcbFrame* aFrame,
|
|
|
|
wxTextCtrl* aMessageWindow,
|
|
|
|
const wxString& aCmpFullFileName,
|
|
|
|
char* Text,
|
|
|
|
int* UseFichCmp,
|
|
|
|
int TstOnly,
|
|
|
|
bool aSelect_By_Timestamp,
|
|
|
|
bool aChangeFootprint )
|
2007-06-05 12:10:51 +00:00
|
|
|
/****************************************************************************/
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2008-03-22 18:08:44 +00:00
|
|
|
/* charge la description d'une empreinte, netliste type PCBNEW
|
2007-08-20 19:33:15 +00:00
|
|
|
* et met a jour le module correspondant
|
2008-02-19 00:28:42 +00:00
|
|
|
*
|
2007-08-20 19:33:15 +00:00
|
|
|
* Si TstOnly == 0 si le module n'existe pas, il est charge
|
|
|
|
* Si TstOnly != 0 si le module n'existe pas, il est ajoute a la liste des
|
|
|
|
* modules a charger
|
|
|
|
* Text contient la premiere ligne de la description
|
|
|
|
* UseFichCmp est un flag
|
|
|
|
* si != 0, le fichier des composants .CMP sera utilise
|
|
|
|
* est remis a 0 si le fichier n'existe pas
|
2008-02-19 00:28:42 +00:00
|
|
|
*
|
2007-08-20 19:33:15 +00:00
|
|
|
* Analyse les lignes type:
|
|
|
|
* ( 40C08647 $noname R20 4,7K {Lib=R}
|
|
|
|
* ( 1 VCC )
|
|
|
|
* ( 2 MODB_1 )
|
|
|
|
*/
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2009-04-24 07:36:36 +00:00
|
|
|
MODULE* Module;
|
|
|
|
char* text;
|
|
|
|
wxString TimeStampPath;
|
|
|
|
wxString TextNameLibMod;
|
|
|
|
wxString TextValeur;
|
|
|
|
wxString TextCmpName;
|
|
|
|
wxString NameLibCmp;
|
|
|
|
int Error = 0;
|
|
|
|
char Line[1024];
|
|
|
|
bool Found;
|
2007-08-20 19:33:15 +00:00
|
|
|
|
|
|
|
strcpy( Line, Text );
|
|
|
|
|
|
|
|
TextValeur = wxT( "~" );
|
2008-02-19 00:28:42 +00:00
|
|
|
|
2007-08-20 19:33:15 +00:00
|
|
|
if( ( text = strtok( Line, " ()\t\n" ) ) == NULL )
|
|
|
|
Error = 1;
|
|
|
|
else
|
2009-04-24 07:36:36 +00:00
|
|
|
TimeStampPath = CONV_FROM_UTF8( text );
|
2008-02-19 00:28:42 +00:00
|
|
|
|
2007-08-20 19:33:15 +00:00
|
|
|
if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL )
|
|
|
|
Error = 1;
|
|
|
|
else
|
|
|
|
TextNameLibMod = CONV_FROM_UTF8( text );
|
2008-02-19 00:28:42 +00:00
|
|
|
|
2007-08-20 19:33:15 +00:00
|
|
|
if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL )
|
|
|
|
Error = 1;
|
|
|
|
else
|
|
|
|
TextCmpName = CONV_FROM_UTF8( text );
|
2008-02-19 00:28:42 +00:00
|
|
|
|
2007-08-20 19:33:15 +00:00
|
|
|
if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL )
|
|
|
|
Error = -1;
|
|
|
|
else
|
|
|
|
TextValeur = CONV_FROM_UTF8( text );
|
|
|
|
|
|
|
|
if( Error > 0 )
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
/* Tst si composant deja charge */
|
2009-01-05 05:21:35 +00:00
|
|
|
Module = aFrame->GetBoard()->m_Modules;
|
2007-08-20 19:33:15 +00:00
|
|
|
MODULE* NextModule;
|
2009-04-24 07:36:36 +00:00
|
|
|
|
|
|
|
for( Found = false; Module != NULL; Module = NextModule )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2008-03-22 18:08:44 +00:00
|
|
|
NextModule = Module->Next();
|
2009-04-24 07:36:36 +00:00
|
|
|
if( aSelect_By_Timestamp ) /* identification by time stamp */
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2009-04-24 07:36:36 +00:00
|
|
|
if( TimeStampPath.CmpNoCase( Module->m_Path ) == 0 )
|
|
|
|
Found = true;
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
2009-04-24 07:36:36 +00:00
|
|
|
else /* identification by Reference */
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
|
|
|
if( TextCmpName.CmpNoCase( Module->m_Reference->m_Text ) == 0 )
|
2009-04-24 07:36:36 +00:00
|
|
|
Found = true;
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
2009-04-24 07:36:36 +00:00
|
|
|
if( Found ) // test footprint matching for existing modules: current m_LibRef and module name in netlist must match
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
|
|
|
if( TstOnly != TESTONLY )
|
|
|
|
{
|
|
|
|
NameLibCmp = TextNameLibMod;
|
|
|
|
if( *UseFichCmp )
|
|
|
|
{
|
2008-03-22 18:08:44 +00:00
|
|
|
if( aSelect_By_Timestamp )
|
2009-04-24 07:36:36 +00:00
|
|
|
{
|
2008-03-22 18:08:44 +00:00
|
|
|
*UseFichCmp = ReadListeModules( aCmpFullFileName,
|
2009-04-24 07:36:36 +00:00
|
|
|
NULL,
|
|
|
|
&TimeStampPath,
|
|
|
|
NameLibCmp );
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
2009-04-24 07:36:36 +00:00
|
|
|
else
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2008-03-22 18:08:44 +00:00
|
|
|
*UseFichCmp = ReadListeModules( aCmpFullFileName,
|
2009-04-24 07:36:36 +00:00
|
|
|
&TextCmpName,
|
|
|
|
NULL,
|
|
|
|
NameLibCmp );
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
}
|
2009-04-24 07:36:36 +00:00
|
|
|
if( Module->m_LibRef.CmpNoCase( NameLibCmp ) != 0 ) // Module Mismatch: Current module and module specified in netlist are different.
|
|
|
|
{
|
|
|
|
if( aChangeFootprint ) // footprint exchange allowed:
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
|
|
|
MODULE* NewModule =
|
2009-04-24 07:36:36 +00:00
|
|
|
aFrame->Get_Librairie_Module( wxEmptyString, NameLibCmp, true );
|
|
|
|
if( NewModule ) /* Change old module to the new module (and delete the old one)*/
|
2009-08-06 07:11:04 +00:00
|
|
|
{
|
|
|
|
aFrame->Exchange_Module( Module, NewModule, NULL );
|
|
|
|
Module = NewModule;
|
|
|
|
}
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
wxString msg;
|
2009-04-24 07:36:36 +00:00
|
|
|
msg.Printf(
|
|
|
|
_(
|
|
|
|
"Component \"%s\": Mismatch! module is [%s] and netlist said [%s]\n" ),
|
|
|
|
TextCmpName.GetData(), Module->m_LibRef.GetData(),
|
|
|
|
NameLibCmp.GetData() );
|
|
|
|
|
2008-03-22 18:08:44 +00:00
|
|
|
if( aMessageWindow )
|
|
|
|
aMessageWindow->AppendText( msg );
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-04-24 07:36:36 +00:00
|
|
|
if( Module == NULL ) /* a new module must be loaded from libs */
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
|
|
|
if( *UseFichCmp )
|
|
|
|
{
|
2008-03-22 18:08:44 +00:00
|
|
|
if( aSelect_By_Timestamp == 1 )
|
2009-04-24 07:36:36 +00:00
|
|
|
{
|
|
|
|
*UseFichCmp = ReadListeModules( aCmpFullFileName, NULL, &TimeStampPath, NameLibCmp );
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
2009-04-24 07:36:36 +00:00
|
|
|
else
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2009-04-24 07:36:36 +00:00
|
|
|
*UseFichCmp = ReadListeModules( aCmpFullFileName, &TextCmpName, NULL, NameLibCmp );
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if( TstOnly == TESTONLY )
|
2009-04-24 07:36:36 +00:00
|
|
|
AddToList( NameLibCmp, TextCmpName, TimeStampPath );
|
2007-08-20 19:33:15 +00:00
|
|
|
else
|
|
|
|
{
|
2009-04-24 07:36:36 +00:00
|
|
|
if( aMessageWindow )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2008-03-22 18:08:44 +00:00
|
|
|
wxString msg;
|
|
|
|
msg.Printf( _( "Component [%s] not found" ), TextCmpName.GetData() );
|
|
|
|
aMessageWindow->AppendText( msg + wxT( "\n" ) );
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL; /* Le module n'avait pas pu etre charge */
|
|
|
|
}
|
|
|
|
|
2009-04-24 07:36:36 +00:00
|
|
|
/* Fields update ( reference, value and "Time Stamp") */
|
2007-08-20 19:33:15 +00:00
|
|
|
Module->m_Reference->m_Text = TextCmpName;
|
2009-04-24 07:36:36 +00:00
|
|
|
Module->m_Value->m_Text = TextValeur;
|
|
|
|
Module->m_Path = TimeStampPath;
|
2007-08-20 19:33:15 +00:00
|
|
|
|
|
|
|
return Module; /* composant trouve */
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2009-04-24 07:36:36 +00:00
|
|
|
/*******************************************************************************************/
|
|
|
|
int SetPadNetName( wxWindow* frame, char* Text, MODULE* Module, wxTextCtrl* aMessageWindow )
|
|
|
|
/*******************************************************************************************/
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2008-03-22 18:08:44 +00:00
|
|
|
/** Function SetPadNetName
|
|
|
|
* Update a pad netname in a given footprint
|
|
|
|
* @param Text = Text from netlist (format: (pad = net) )
|
|
|
|
* @param Module = the given footprint
|
2009-04-24 07:36:36 +00:00
|
|
|
* @param aMessageWindow = a wxTextCtrl to print error and warning message (can be NULL)
|
2007-08-20 19:33:15 +00:00
|
|
|
*/
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2007-08-20 19:33:15 +00:00
|
|
|
D_PAD* pad;
|
|
|
|
char* TextPinName, * TextNetName;
|
|
|
|
int Error = 0;
|
|
|
|
bool trouve;
|
|
|
|
char Line[256];
|
|
|
|
wxString Msg;
|
|
|
|
|
|
|
|
if( Module == NULL )
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
strcpy( Line, Text );
|
|
|
|
|
|
|
|
if( ( TextPinName = strtok( Line, " ()\t\n" ) ) == NULL )
|
|
|
|
Error = 1;
|
|
|
|
if( ( TextNetName = strtok( NULL, " ()\t\n" ) ) == NULL )
|
|
|
|
Error = 1;
|
|
|
|
if( Error )
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* recherche du pad */
|
|
|
|
pad = Module->m_Pads; trouve = FALSE;
|
2008-11-24 06:53:43 +00:00
|
|
|
for( ; pad != NULL; pad = (D_PAD*) pad->Next() )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2009-04-24 07:36:36 +00:00
|
|
|
if( strnicmp( TextPinName, pad->m_Padname, 4 ) == 0 ) /* trouve */
|
|
|
|
{
|
|
|
|
trouve = true;
|
2007-08-20 19:33:15 +00:00
|
|
|
if( *TextNetName != '?' )
|
2008-12-14 19:45:05 +00:00
|
|
|
pad->SetNetname( CONV_FROM_UTF8( TextNetName ) );
|
2007-08-20 19:33:15 +00:00
|
|
|
else
|
2009-04-24 07:36:36 +00:00
|
|
|
pad->SetNetname( wxEmptyString );
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-04-24 07:36:36 +00:00
|
|
|
if( !trouve )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2009-04-24 07:36:36 +00:00
|
|
|
if( aMessageWindow )
|
|
|
|
{
|
|
|
|
wxString pin_name = CONV_FROM_UTF8( TextPinName );
|
|
|
|
Msg.Printf( _( "Module [%s]: Pad [%s] not found" ),
|
|
|
|
Module->m_Reference->m_Text.GetData(), pin_name.GetData() );
|
|
|
|
aMessageWindow->AppendText( Msg + wxT( "\n" ) );
|
|
|
|
}
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return trouve;
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************/
|
2008-03-22 18:08:44 +00:00
|
|
|
MODULE* WinEDA_PcbFrame::ListAndSelectModuleName( void )
|
2007-06-05 12:10:51 +00:00
|
|
|
/*****************************************************/
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2009-04-24 07:36:36 +00:00
|
|
|
/**
|
|
|
|
* build and shows a list of existing modules on board
|
|
|
|
* The user can slect a module from this list
|
|
|
|
* @return a pointer to the selected module or NULL
|
2007-08-20 19:33:15 +00:00
|
|
|
*/
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2009-04-24 07:36:36 +00:00
|
|
|
int ii, jj;
|
|
|
|
MODULE* Module;
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2009-01-05 05:21:35 +00:00
|
|
|
if( GetBoard()->m_Modules == NULL )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
|
|
|
DisplayError( this, _( "No Modules" ) ); return 0;
|
|
|
|
}
|
|
|
|
|
2009-04-24 07:36:36 +00:00
|
|
|
WinEDAListBox listbox( this, _( "Components" ), NULL, wxEmptyString );
|
|
|
|
Module = (MODULE*) GetBoard()->m_Modules;
|
2008-11-24 06:53:43 +00:00
|
|
|
for( ; Module != NULL; Module = (MODULE*) Module->Next() )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2009-04-24 07:36:36 +00:00
|
|
|
listbox.Append( Module->m_Reference->m_Text );
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
|
2009-04-24 07:36:36 +00:00
|
|
|
ii = listbox.ShowModal();
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2009-04-24 07:36:36 +00:00
|
|
|
if( ii < 0 )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
|
|
|
Module = NULL;
|
|
|
|
}
|
2009-04-24 07:36:36 +00:00
|
|
|
else /* Search for the selected footprint */
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2009-04-24 07:36:36 +00:00
|
|
|
wxString ref = listbox.GetTextSelection();
|
2009-01-05 05:21:35 +00:00
|
|
|
Module = (MODULE*) GetBoard()->m_Modules;
|
2008-11-24 06:53:43 +00:00
|
|
|
for( jj = 0; Module != NULL; Module = (MODULE*) Module->Next(), jj++ )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2009-04-24 07:36:36 +00:00
|
|
|
if( Module->m_Reference->m_Text.Cmp( ref ) == 0 )
|
2007-08-20 19:33:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return Module;
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2008-03-22 18:08:44 +00:00
|
|
|
/*****************************************************************************************/
|
2009-04-24 07:36:36 +00:00
|
|
|
void TestFor_Duplicate_Missing_And_Extra_Footprints( wxWindow* aFrame,
|
|
|
|
const wxString& aNetlistFullFilename,
|
|
|
|
BOARD* aPcb )
|
2008-03-22 18:08:44 +00:00
|
|
|
/******************************************************************************************/
|
|
|
|
|
|
|
|
/** Function TestFor_Duplicate_Missing_And_Extra_Footprints
|
|
|
|
* Build a list from the given board and netlist :
|
|
|
|
* 1 - for duplicate footprints on board
|
|
|
|
* 2 - for missing footprints
|
|
|
|
* 3 - for footprints not in netlist
|
|
|
|
* @param aFrame = current active frame
|
|
|
|
* @param aNetlistFullFilename = the given netlist
|
|
|
|
* @param aPcb = the given board
|
2007-08-20 19:33:15 +00:00
|
|
|
*/
|
2007-06-05 12:10:51 +00:00
|
|
|
#define MAX_LEN_TXT 32
|
|
|
|
{
|
2009-04-24 07:36:36 +00:00
|
|
|
int ii;
|
2007-08-20 19:33:15 +00:00
|
|
|
MODULE* Module, * pt_aux;
|
|
|
|
int NbModulesNetListe, nberr = 0;
|
|
|
|
WinEDA_TextFrame* List;
|
|
|
|
wxArrayString ModuleListFromNetlist;
|
|
|
|
|
2008-03-22 18:08:44 +00:00
|
|
|
if( aPcb->m_Modules == NULL )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2009-04-17 08:51:02 +00:00
|
|
|
DisplayInfoMessage( aFrame, _( "No modules" ), 10 ); return;
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Construction de la liste des references des modules de la netliste */
|
2009-04-24 07:36:36 +00:00
|
|
|
NbModulesNetListe = BuildFootprintsListFromNetlistFile( aNetlistFullFilename,
|
|
|
|
ModuleListFromNetlist );
|
2007-08-20 19:33:15 +00:00
|
|
|
if( NbModulesNetListe < 0 )
|
2008-03-22 18:08:44 +00:00
|
|
|
return; /* File not found */
|
2007-08-20 19:33:15 +00:00
|
|
|
|
|
|
|
if( NbModulesNetListe == 0 )
|
|
|
|
{
|
2008-03-22 18:08:44 +00:00
|
|
|
DisplayError( aFrame, _( "No modules in NetList" ), 10 ); return;
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
|
2008-03-22 18:08:44 +00:00
|
|
|
List = new WinEDA_TextFrame( aFrame, _( "Check Modules" ) );
|
2007-08-20 19:33:15 +00:00
|
|
|
|
|
|
|
/* recherche des doubles */
|
|
|
|
List->Append( _( "Duplicates" ) );
|
|
|
|
|
2008-03-22 18:08:44 +00:00
|
|
|
Module = aPcb->m_Modules;
|
|
|
|
for( ; Module != NULL; Module = Module->Next() )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2008-03-22 18:08:44 +00:00
|
|
|
pt_aux = Module->Next();
|
|
|
|
for( ; pt_aux != NULL; pt_aux = pt_aux->Next() )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
|
|
|
if( Module->m_Reference->m_Text.CmpNoCase( pt_aux->m_Reference->m_Text ) == 0 )
|
|
|
|
{
|
|
|
|
List->Append( Module->m_Reference->m_Text );
|
|
|
|
nberr++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* recherche des manquants par rapport a la netliste*/
|
|
|
|
List->Append( _( "Lack:" ) );
|
|
|
|
|
|
|
|
for( ii = 0; ii < NbModulesNetListe; ii++ )
|
|
|
|
{
|
2008-03-22 18:08:44 +00:00
|
|
|
Module = (MODULE*) aPcb->m_Modules;
|
|
|
|
for( ; Module != NULL; Module = Module->Next() )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
|
|
|
if( Module->m_Reference->m_Text.CmpNoCase(
|
|
|
|
ModuleListFromNetlist[ii] ) == 0 )
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( Module == NULL ) // Module missing, not found in board
|
|
|
|
{
|
|
|
|
List->Append( ModuleListFromNetlist[ii] );
|
|
|
|
nberr++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* recherche des modules supplementaires (i.e. Non en Netliste) */
|
|
|
|
List->Append( _( "Not in Netlist:" ) );
|
|
|
|
|
2008-03-22 18:08:44 +00:00
|
|
|
Module = (MODULE*) aPcb->m_Modules;
|
2007-08-20 19:33:15 +00:00
|
|
|
for( ; Module != NULL; Module = Module->Next() )
|
|
|
|
{
|
|
|
|
for( ii = 0; ii < NbModulesNetListe; ii++ )
|
|
|
|
{
|
|
|
|
if( Module->m_Reference->m_Text.CmpNoCase(
|
|
|
|
ModuleListFromNetlist[ii] ) == 0 )
|
|
|
|
{
|
2008-03-22 18:08:44 +00:00
|
|
|
break; /* Module trouve en netliste */
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( ii == NbModulesNetListe ) /* Module not found in netlist */
|
|
|
|
{
|
|
|
|
List->Append( Module->m_Reference->m_Text );
|
|
|
|
nberr++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
List->ShowModal(); List->Destroy();
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-22 18:08:44 +00:00
|
|
|
/***************************************************************************************/
|
2009-04-24 07:36:36 +00:00
|
|
|
int BuildFootprintsListFromNetlistFile( const wxString& aNetlistFullFilename,
|
|
|
|
wxArrayString& aBufName )
|
2008-03-22 18:08:44 +00:00
|
|
|
/***************************************************************************************/
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2008-03-22 18:08:44 +00:00
|
|
|
/** Function BuildFootprintsListFromNetlistFile
|
|
|
|
* Fill BufName with footprints names read from the netlist.
|
|
|
|
* @param aNetlistFullFilename = netlist file name
|
|
|
|
* @param BufName = wxArrayString to fill with footprint names
|
|
|
|
* @return Footprint count, or -1 if netlist file cannot opened
|
2007-08-20 19:33:15 +00:00
|
|
|
*/
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2007-08-20 19:33:15 +00:00
|
|
|
int textlen;
|
|
|
|
int nb_modules_lus;
|
|
|
|
int State, LineNum, Comment;
|
|
|
|
char Line[1024], * Text, * LibModName;
|
|
|
|
|
2008-03-22 18:08:44 +00:00
|
|
|
if( !OpenNetlistFile( aNetlistFullFilename ) )
|
2007-08-20 19:33:15 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
State = 0; LineNum = 0; Comment = 0;
|
|
|
|
nb_modules_lus = 0;
|
|
|
|
textlen = MAX_LEN_TXT;
|
|
|
|
|
|
|
|
while( GetLine( source, Line, &LineNum ) )
|
|
|
|
{
|
|
|
|
Text = StrPurge( Line );
|
|
|
|
if( Comment ) /* Commentaires en cours */
|
|
|
|
{
|
|
|
|
if( ( Text = strchr( Text, '}' ) ) == NULL )
|
|
|
|
continue;
|
|
|
|
Comment = 0;
|
|
|
|
}
|
|
|
|
if( *Text == '{' ) /* Commentaires */
|
|
|
|
{
|
|
|
|
Comment = 1;
|
|
|
|
if( ( Text = strchr( Text, '}' ) ) == NULL )
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( *Text == '(' )
|
|
|
|
State++;
|
|
|
|
if( *Text == ')' )
|
|
|
|
State--;
|
|
|
|
|
|
|
|
if( State == 2 )
|
|
|
|
{
|
|
|
|
int Error = 0;
|
|
|
|
if( strtok( Line, " ()\t\n" ) == NULL )
|
2008-03-22 18:08:44 +00:00
|
|
|
Error = 1; /* TimeStamp */
|
2007-08-20 19:33:15 +00:00
|
|
|
if( ( LibModName = strtok( NULL, " ()\t\n" ) ) == NULL )
|
2008-03-22 18:08:44 +00:00
|
|
|
Error = 1; /* nom Lib */
|
2007-08-20 19:33:15 +00:00
|
|
|
/* Lecture du nom (reference) du composant: */
|
|
|
|
if( ( Text = strtok( NULL, " ()\t\n" ) ) == NULL )
|
|
|
|
Error = 1;
|
|
|
|
nb_modules_lus++;
|
2008-03-22 18:08:44 +00:00
|
|
|
aBufName.Add( CONV_FROM_UTF8( Text ) );
|
2007-08-20 19:33:15 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( State >= 3 )
|
|
|
|
{
|
|
|
|
State--; /* Lecture 1 ligne relative au Pad */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose( source );
|
|
|
|
return nb_modules_lus;
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************************/
|
2009-04-24 07:36:36 +00:00
|
|
|
int ReadListeModules( const wxString& CmpFullFileName, const wxString* RefCmp,
|
|
|
|
const wxString* TimeStamp, wxString& NameModule )
|
2007-06-05 12:10:51 +00:00
|
|
|
/*****************************************************************************************/
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2007-06-05 12:10:51 +00:00
|
|
|
/*
|
2007-08-20 19:33:15 +00:00
|
|
|
* Lit le fichier .CMP donnant l'equivalence Modules / Composants
|
|
|
|
* Retourne:
|
2009-04-24 07:36:36 +00:00
|
|
|
* Si ce fichier existe retourne :
|
2007-08-20 19:33:15 +00:00
|
|
|
* 1 et le nom module dans NameModule
|
|
|
|
* -1 si module non trouve en fichier
|
|
|
|
* sinon 0;
|
2008-02-19 00:28:42 +00:00
|
|
|
*
|
2007-08-20 19:33:15 +00:00
|
|
|
* parametres d'appel:
|
|
|
|
* RefCmp (NULL si selection par TimeStamp)
|
|
|
|
* TimeStamp (signature temporelle si elle existe, NULL sinon)
|
|
|
|
* pointeur sur le buffer recevant le nom du module
|
2008-02-19 00:28:42 +00:00
|
|
|
*
|
2007-08-20 19:33:15 +00:00
|
|
|
* Exemple de fichier:
|
2008-02-19 00:28:42 +00:00
|
|
|
*
|
2007-08-20 19:33:15 +00:00
|
|
|
* Cmp-Mod V01 Genere par PcbNew le 29/10/2003-13:11:6
|
2008-02-19 00:28:42 +00:00
|
|
|
*
|
2007-08-20 19:33:15 +00:00
|
|
|
* BeginCmp
|
2009-04-24 07:36:36 +00:00
|
|
|
* TimeStamp = /322D3011;
|
2007-08-20 19:33:15 +00:00
|
|
|
* Reference = BUS1;
|
|
|
|
* ValeurCmp = BUSPC;
|
|
|
|
* IdModule = BUS_PC;
|
|
|
|
* EndCmp
|
2008-02-19 00:28:42 +00:00
|
|
|
*
|
2007-08-20 19:33:15 +00:00
|
|
|
* BeginCmp
|
2009-04-24 07:36:36 +00:00
|
|
|
* TimeStamp = /32307DE2/AA450F67;
|
2007-08-20 19:33:15 +00:00
|
|
|
* Reference = C1;
|
|
|
|
* ValeurCmp = 47uF;
|
|
|
|
* IdModule = CP6;
|
|
|
|
* EndCmp
|
2008-02-19 00:28:42 +00:00
|
|
|
*
|
2007-08-20 19:33:15 +00:00
|
|
|
*/
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2009-04-24 07:36:36 +00:00
|
|
|
wxString refcurrcmp, timestamp, idmod;
|
2007-08-20 19:33:15 +00:00
|
|
|
char ia[1024];
|
|
|
|
char* ptcar;
|
|
|
|
FILE* FichCmp;
|
|
|
|
|
|
|
|
if( (RefCmp == NULL) && (TimeStamp == 0) )
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
FichCmp = wxFopen( CmpFullFileName, wxT( "rt" ) );
|
|
|
|
if( FichCmp == NULL )
|
|
|
|
{
|
|
|
|
wxString msg;
|
|
|
|
msg.Printf( _( "File <%s> not found, use Netlist for lib module selection" ),
|
2009-04-24 07:36:36 +00:00
|
|
|
CmpFullFileName.GetData() );
|
2008-03-22 18:08:44 +00:00
|
|
|
DisplayError( NULL, msg, 20 );
|
2007-08-20 19:33:15 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
while( fgets( ia, sizeof(ia), FichCmp ) != NULL )
|
|
|
|
{
|
|
|
|
if( strnicmp( ia, "BeginCmp", 8 ) != 0 )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* Ici une description de 1 composant commence */
|
|
|
|
refcurrcmp.Empty();
|
|
|
|
idmod.Empty();
|
2009-04-24 07:36:36 +00:00
|
|
|
timestamp.Empty();
|
2007-08-20 19:33:15 +00:00
|
|
|
while( fgets( ia, sizeof(ia), FichCmp ) != NULL )
|
|
|
|
{
|
|
|
|
if( strnicmp( ia, "EndCmp", 6 ) == 0 )
|
|
|
|
break;
|
|
|
|
|
|
|
|
if( strnicmp( ia, "Reference =", 11 ) == 0 )
|
|
|
|
{
|
|
|
|
ptcar = ia + 11;
|
|
|
|
ptcar = strtok( ptcar, " =;\t\n" );
|
|
|
|
if( ptcar )
|
|
|
|
refcurrcmp = CONV_FROM_UTF8( ptcar );
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( strnicmp( ia, "IdModule =", 11 ) == 0 )
|
|
|
|
{
|
|
|
|
ptcar = ia + 11;
|
|
|
|
ptcar = strtok( ptcar, " =;\t\n" );
|
|
|
|
if( ptcar )
|
|
|
|
idmod = CONV_FROM_UTF8( ptcar );
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if( strnicmp( ia, "TimeStamp =", 11 ) == 0 )
|
|
|
|
{
|
|
|
|
ptcar = ia + 11;
|
|
|
|
ptcar = strtok( ptcar, " =;\t\n" );
|
|
|
|
if( ptcar )
|
2009-04-24 07:36:36 +00:00
|
|
|
timestamp = CONV_FROM_UTF8( ptcar );
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Fin lecture 1 descr composant */
|
|
|
|
|
|
|
|
/* Test du Composant lu en fichier: est-il le bon */
|
|
|
|
if( RefCmp )
|
|
|
|
{
|
2009-04-24 07:36:36 +00:00
|
|
|
if( RefCmp->CmpNoCase( refcurrcmp ) == 0 ) //Found!
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
|
|
|
fclose( FichCmp );
|
|
|
|
NameModule = idmod;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
2009-04-24 07:36:36 +00:00
|
|
|
else if( TimeStamp )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2009-04-24 07:36:36 +00:00
|
|
|
if( TimeStamp->CmpNoCase( timestamp ) == 0 && !timestamp.IsEmpty() ) //Found
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
|
|
|
fclose( FichCmp );
|
|
|
|
NameModule = idmod;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose( FichCmp );
|
|
|
|
return -1;
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/***********************************************************************************/
|
2009-04-24 07:36:36 +00:00
|
|
|
void AddToList( const wxString& NameLibCmp, const wxString& CmpName, const wxString& path )
|
2007-06-05 12:10:51 +00:00
|
|
|
/************************************************************************************/
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2007-06-05 12:10:51 +00:00
|
|
|
/* Fontion copiant en memoire de travail les caracteristiques
|
2007-08-20 19:33:15 +00:00
|
|
|
* des nouveaux modules
|
|
|
|
*/
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2007-08-20 19:33:15 +00:00
|
|
|
MODULEtoLOAD* NewMod;
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2009-04-24 07:36:36 +00:00
|
|
|
NewMod = new MODULEtoLOAD( NameLibCmp, CmpName, path );
|
2008-11-24 06:53:43 +00:00
|
|
|
NewMod->SetNext( s_ModuleToLoad_List );
|
2007-08-20 19:33:15 +00:00
|
|
|
s_ModuleToLoad_List = NewMod;
|
|
|
|
s_NbNewModules++;
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/***************************************************************/
|
2009-08-19 14:19:35 +00:00
|
|
|
void LoadListeModules( WinEDA_PcbFrame* aPcbFrame )
|
2007-06-05 12:10:51 +00:00
|
|
|
/***************************************************************/
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2007-06-05 12:10:51 +00:00
|
|
|
/* Routine de chargement des nouveaux modules en une seule lecture des
|
2007-08-20 19:33:15 +00:00
|
|
|
* librairies
|
|
|
|
* Si un module vient d'etre charge il est duplique, ce qui evite une lecture
|
|
|
|
* inutile de la librairie
|
|
|
|
*/
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2007-08-20 19:33:15 +00:00
|
|
|
MODULEtoLOAD* ref, * cmp;
|
|
|
|
int ii;
|
|
|
|
MODULE* Module = NULL;
|
2009-08-19 14:19:35 +00:00
|
|
|
wxPoint ModuleBestPosition;
|
2007-08-20 19:33:15 +00:00
|
|
|
|
|
|
|
if( s_NbNewModules == 0 )
|
|
|
|
return;
|
|
|
|
|
|
|
|
SortListModulesToLoadByLibname( s_NbNewModules );
|
|
|
|
ref = cmp = s_ModuleToLoad_List;
|
|
|
|
|
2008-03-22 18:08:44 +00:00
|
|
|
// Calculate the footprint "best" position:
|
|
|
|
if( aPcbFrame->SetBoardBoundaryBoxFromEdgesOnly() )
|
2007-08-20 19:33:15 +00:00
|
|
|
{
|
2009-08-19 14:19:35 +00:00
|
|
|
ModuleBestPosition.x = aPcbFrame->GetBoard()->m_BoundaryBox.GetRight() + 5000;
|
|
|
|
ModuleBestPosition.y = aPcbFrame->GetBoard()->m_BoundaryBox.GetBottom() + 10000;
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
else
|
2009-08-19 14:19:35 +00:00
|
|
|
ModuleBestPosition = wxPoint( 0, 0 );
|
2007-08-20 19:33:15 +00:00
|
|
|
|
|
|
|
for( ii = 0; ii < s_NbNewModules; ii++, cmp = cmp->Next() )
|
|
|
|
{
|
|
|
|
if( (ii == 0) || ( ref->m_LibName != cmp->m_LibName) )
|
2008-12-06 08:21:54 +00:00
|
|
|
{
|
|
|
|
/* New footprint : must be loaded from a library */
|
2009-04-06 16:05:25 +00:00
|
|
|
Module = aPcbFrame->Get_Librairie_Module( wxEmptyString, cmp->m_LibName, FALSE );
|
2007-08-20 19:33:15 +00:00
|
|
|
ref = cmp;
|
|
|
|
if( Module == NULL )
|
|
|
|
{
|
|
|
|
wxString msg;
|
|
|
|
msg.Printf( _( "Component [%s]: footprint <%s> not found" ),
|
2009-04-24 07:36:36 +00:00
|
|
|
cmp->m_CmpName.GetData(), cmp->m_LibName.GetData() );
|
2008-03-22 18:08:44 +00:00
|
|
|
DisplayError( NULL, msg );
|
2007-08-20 19:33:15 +00:00
|
|
|
continue;
|
|
|
|
}
|
2009-08-19 14:19:35 +00:00
|
|
|
Module->SetPosition( ModuleBestPosition );
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2008-03-22 18:08:44 +00:00
|
|
|
/* Update schematic links : reference "Time Stamp" and schematic hierarchical path */
|
2007-08-20 19:33:15 +00:00
|
|
|
Module->m_Reference->m_Text = cmp->m_CmpName;
|
2009-04-24 07:36:36 +00:00
|
|
|
Module->m_TimeStamp = GetTimeStamp();
|
|
|
|
Module->m_Path = cmp->m_TimeStampPath;
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-03-22 18:08:44 +00:00
|
|
|
/* Footprint already loaded from a library, duplicate it (faster) */
|
2007-08-20 19:33:15 +00:00
|
|
|
MODULE* newmodule;
|
|
|
|
if( Module == NULL )
|
2008-03-22 18:08:44 +00:00
|
|
|
continue; /* module non existant en libr */
|
2008-12-06 08:21:54 +00:00
|
|
|
|
2009-01-05 05:21:35 +00:00
|
|
|
newmodule = new MODULE( aPcbFrame->GetBoard() );
|
2007-08-20 19:33:15 +00:00
|
|
|
newmodule->Copy( Module );
|
2008-12-06 08:21:54 +00:00
|
|
|
|
2009-01-05 05:21:35 +00:00
|
|
|
aPcbFrame->GetBoard()->Add( newmodule, ADD_APPEND );
|
2008-12-06 08:21:54 +00:00
|
|
|
|
2007-08-20 19:33:15 +00:00
|
|
|
Module = newmodule;
|
|
|
|
Module->m_Reference->m_Text = cmp->m_CmpName;
|
2009-04-24 07:36:36 +00:00
|
|
|
Module->m_TimeStamp = GetTimeStamp();
|
|
|
|
Module->m_Path = cmp->m_TimeStampPath;
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
}
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Routine utilisee par qsort pour le tri des modules a charger
|
2007-08-20 19:33:15 +00:00
|
|
|
*/
|
|
|
|
static int SortByLibName( MODULEtoLOAD** ref, MODULEtoLOAD** cmp )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2007-08-20 19:33:15 +00:00
|
|
|
int ii = (*ref)->m_LibName.CmpNoCase( (*cmp)->m_LibName );
|
|
|
|
|
|
|
|
return ii;
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2007-06-05 12:10:51 +00:00
|
|
|
/*************************************************/
|
2007-08-20 19:33:15 +00:00
|
|
|
void SortListModulesToLoadByLibname( int NbModules )
|
2007-06-05 12:10:51 +00:00
|
|
|
/**************************************************/
|
2007-08-20 19:33:15 +00:00
|
|
|
|
2007-06-05 12:10:51 +00:00
|
|
|
/* Rearrage la liste des modules List par ordre alphabetique des noms lib des modules
|
2007-08-20 19:33:15 +00:00
|
|
|
*/
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2007-08-20 19:33:15 +00:00
|
|
|
MODULEtoLOAD** base_list, * item;
|
|
|
|
int ii;
|
|
|
|
|
2008-03-22 18:08:44 +00:00
|
|
|
base_list = (MODULEtoLOAD**) MyMalloc( NbModules * sizeof(MODULEtoLOAD*) );
|
2007-08-20 19:33:15 +00:00
|
|
|
|
|
|
|
for( ii = 0, item = s_ModuleToLoad_List; ii < NbModules; ii++ )
|
|
|
|
{
|
|
|
|
base_list[ii] = item;
|
|
|
|
item = item->Next();
|
|
|
|
}
|
|
|
|
|
2008-03-22 18:08:44 +00:00
|
|
|
qsort( base_list, NbModules, sizeof(MODULEtoLOAD*),
|
2009-04-24 07:36:36 +00:00
|
|
|
( int( * ) ( const void*, const void* ) )SortByLibName );
|
2007-08-20 19:33:15 +00:00
|
|
|
|
|
|
|
// Reconstruction du chainage:
|
|
|
|
s_ModuleToLoad_List = *base_list;
|
|
|
|
for( ii = 0; ii < NbModules - 1; ii++ )
|
|
|
|
{
|
|
|
|
item = base_list[ii];
|
2008-11-24 06:53:43 +00:00
|
|
|
item->SetNext( base_list[ii + 1] );
|
2007-08-20 19:33:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Dernier item: Pnext = NULL:
|
|
|
|
item = base_list[ii];
|
2008-11-24 06:53:43 +00:00
|
|
|
item->SetNext( NULL );
|
2007-08-20 19:33:15 +00:00
|
|
|
|
|
|
|
free( base_list );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|