Commit 5d7410c9 authored by Dick Hollenbeck's avatar Dick Hollenbeck

Put netform.cpp functions into a class so scratch memory objects can be freed.

Improve code performance and appearance
parents 74b675c1 7146863b
...@@ -320,3 +320,113 @@ char* strupper( char* Text ) ...@@ -320,3 +320,113 @@ char* strupper( char* Text )
return Text; return Text;
} }
int RefDesStringCompare( const wxString& strFWord, const wxString& strSWord )
{
// The different sections of the first string
wxString strFWordBeg, strFWordMid, strFWordEnd;
// The different sections of the second string
wxString strSWordBeg, strSWordMid, strSWordEnd;
int isEqual = 0; // The numerical results of a string compare
int iReturn = 0; // The variable that is being returned
long lFirstDigit = 0; /* The converted middle section of the first
*string */
long lSecondDigit = 0; /* The converted middle section of the second
*string */
// Split the two strings into separate parts
SplitString( strFWord, &strFWordBeg, &strFWordMid, &strFWordEnd );
SplitString( strSWord, &strSWordBeg, &strSWordMid, &strSWordEnd );
// Compare the Beginning section of the strings
isEqual = strFWordBeg.CmpNoCase( strSWordBeg );
if( isEqual > 0 )
iReturn = 1;
else if( isEqual < 0 )
iReturn = -1;
else
{
// If the first sections are equal compare their digits
strFWordMid.ToLong( &lFirstDigit );
strSWordMid.ToLong( &lSecondDigit );
if( lFirstDigit > lSecondDigit )
iReturn = 1;
else if( lFirstDigit < lSecondDigit )
iReturn = -1;
else
{
// If the first two sections are equal compare the endings
isEqual = strFWordEnd.CmpNoCase( strSWordEnd );
if( isEqual > 0 )
iReturn = 1;
else if( isEqual < 0 )
iReturn = -1;
else
iReturn = 0;
}
}
return iReturn;
}
int SplitString( wxString strToSplit,
wxString* strBeginning,
wxString* strDigits,
wxString* strEnd )
{
// Clear all the return strings
strBeginning->Empty();
strDigits->Empty();
strEnd->Empty();
// There no need to do anything if the string is empty
if( strToSplit.length() == 0 )
return 0;
// Starting at the end of the string look for the first digit
int ii;
for( ii = (strToSplit.length() - 1); ii >= 0; ii-- )
{
if( isdigit( strToSplit[ii] ) )
break;
}
// If there were no digits then just set the single string
if( ii < 0 )
*strBeginning = strToSplit;
else
{
// Since there is at least one digit this is the trailing string
*strEnd = strToSplit.substr( ii + 1 );
// Go to the end of the digits
int position = ii + 1;
for( ; ii >= 0; ii-- )
{
if( !isdigit( strToSplit[ii] ) )
break;
}
// If all that was left was digits, then just set the digits string
if( ii < 0 )
*strDigits = strToSplit.substr( 0, position );
/* We were only looking for the last set of digits everything else is
*part of the preamble */
else
{
*strDigits = strToSplit.substr( ii + 1, position - ii - 1 );
*strBeginning = strToSplit.substr( 0, ii + 1 );
}
}
return 0;
}
...@@ -71,12 +71,6 @@ static bool SortLabelsBySheet( const LABEL_OBJECT& obj1, ...@@ -71,12 +71,6 @@ static bool SortLabelsBySheet( const LABEL_OBJECT& obj1,
static void DeleteSubCmp( std::vector <OBJ_CMP_TO_LIST>& aList ); static void DeleteSubCmp( std::vector <OBJ_CMP_TO_LIST>& aList );
static int PrintListeGLabel( FILE* f, std::vector <LABEL_OBJECT>& aList ); static int PrintListeGLabel( FILE* f, std::vector <LABEL_OBJECT>& aList );
int RefDesStringCompare( const wxString& lhs, const wxString& rhs );
int SplitString( wxString strToSplit,
wxString* strBeginning,
wxString* strDigits,
wxString* strEnd );
// separator used in bom export to spreadsheet // separator used in bom export to spreadsheet
static char s_ExportSeparatorSymbol; static char s_ExportSeparatorSymbol;
...@@ -1049,122 +1043,3 @@ static int PrintListeGLabel( FILE* f, std::vector <LABEL_OBJECT>& aList ) ...@@ -1049,122 +1043,3 @@ static int PrintListeGLabel( FILE* f, std::vector <LABEL_OBJECT>& aList )
} }
/* This function will act just like the strcmp function but correctly sort
* the numerical order in the string
* return -1 if first string is less than the second
* return 0 if the strings are equal
* return 1 if the first string is greater than the second
*/
int RefDesStringCompare( const wxString& strFWord, const wxString& strSWord )
{
// The different sections of the first string
wxString strFWordBeg, strFWordMid, strFWordEnd;
// The different sections of the second string
wxString strSWordBeg, strSWordMid, strSWordEnd;
int isEqual = 0; // The numerical results of a string compare
int iReturn = 0; // The variable that is being returned
long lFirstDigit = 0; /* The converted middle section of the first
*string */
long lSecondDigit = 0; /* The converted middle section of the second
*string */
// Split the two string into separate parts
SplitString( strFWord, &strFWordBeg, &strFWordMid, &strFWordEnd );
SplitString( strSWord, &strSWordBeg, &strSWordMid, &strSWordEnd );
// Compare the Beginning section of the strings
isEqual = strFWordBeg.CmpNoCase( strSWordBeg );
if( isEqual > 0 )
iReturn = 1;
else if( isEqual < 0 )
iReturn = -1;
else
{
// If the first sections are equal compare there digits
strFWordMid.ToLong( &lFirstDigit );
strSWordMid.ToLong( &lSecondDigit );
if( lFirstDigit > lSecondDigit )
iReturn = 1;
else if( lFirstDigit < lSecondDigit )
iReturn = -1;
else
{
// If the first two sections are equal compare the endings
isEqual = strFWordEnd.CmpNoCase( strSWordEnd );
if( isEqual > 0 )
iReturn = 1;
else if( isEqual < 0 )
iReturn = -1;
else
iReturn = 0;
}
}
return iReturn;
}
/* This is the function that breaks a string into three parts.
* The alphabetic preamble
* The numeric part
* Any alphabetic ending
* For example C10A is split to C 10 A
*/
int SplitString( wxString strToSplit,
wxString* strBeginning,
wxString* strDigits,
wxString* strEnd )
{
// Clear all the return strings
strBeginning->Clear();
strDigits->Clear();
strEnd->Clear();
// There no need to do anything if the string is empty
if( strToSplit.length() == 0 )
return 0;
// Starting at the end of the string look for the first digit
int ii;
for( ii = (strToSplit.length() - 1); ii >= 0; ii-- )
{
if( isdigit( strToSplit[ii] ) )
break;
}
// If there were no digits then just set the single string
if( ii < 0 )
*strBeginning = strToSplit;
else
{
// Since there is at least one digit this is the trailing string
*strEnd = strToSplit.substr( ii + 1 );
// Go to the end of the digits
int position = ii + 1;
for( ; ii >= 0; ii-- )
{
if( !isdigit( strToSplit[ii] ) )
break;
}
// If all that was left was digits, then just set the digits string
if( ii < 0 )
*strDigits = strToSplit.substr( 0, position );
/* We were only looking for the last set of digits everything else is
*part of the preamble */
else
{
*strDigits = strToSplit.substr( ii + 1, position - ii - 1 );
*strBeginning = strToSplit.substr( 0, ii + 1 );
}
}
return 0;
}
...@@ -220,7 +220,7 @@ wxString SCH_SHEET_PATH::Path() ...@@ -220,7 +220,7 @@ wxString SCH_SHEET_PATH::Path()
* (the "normal" path uses the time stamps which do not changes even when * (the "normal" path uses the time stamps which do not changes even when
* editing sheet parameters) * editing sheet parameters)
*/ */
wxString SCH_SHEET_PATH::PathHumanReadable() wxString SCH_SHEET_PATH::PathHumanReadable() const
{ {
wxString s, t; wxString s, t;
...@@ -355,6 +355,7 @@ SCH_ITEM* SCH_SHEET_PATH::MatchNextItem( wxFindReplaceData& aSearchData, ...@@ -355,6 +355,7 @@ SCH_ITEM* SCH_SHEET_PATH::MatchNextItem( wxFindReplaceData& aSearchData,
bool SCH_SHEET_PATH::operator=( const SCH_SHEET_PATH& d1 ) bool SCH_SHEET_PATH::operator=( const SCH_SHEET_PATH& d1 )
{ {
m_numSheets = d1.m_numSheets; m_numSheets = d1.m_numSheets;
unsigned i; unsigned i;
for( i = 0; i < m_numSheets; i++ ) for( i = 0; i < m_numSheets; i++ )
{ {
...@@ -370,10 +371,11 @@ bool SCH_SHEET_PATH::operator=( const SCH_SHEET_PATH& d1 ) ...@@ -370,10 +371,11 @@ bool SCH_SHEET_PATH::operator=( const SCH_SHEET_PATH& d1 )
} }
bool SCH_SHEET_PATH::operator==( const SCH_SHEET_PATH& d1 ) bool SCH_SHEET_PATH::operator==( const SCH_SHEET_PATH& d1 ) const
{ {
if( m_numSheets != d1.m_numSheets ) if( m_numSheets != d1.m_numSheets )
return false; return false;
for( unsigned i = 0; i < m_numSheets; i++ ) for( unsigned i = 0; i < m_numSheets; i++ )
{ {
if( m_sheets[i] != d1.m_sheets[i] ) if( m_sheets[i] != d1.m_sheets[i] )
...@@ -384,14 +386,23 @@ bool SCH_SHEET_PATH::operator==( const SCH_SHEET_PATH& d1 ) ...@@ -384,14 +386,23 @@ bool SCH_SHEET_PATH::operator==( const SCH_SHEET_PATH& d1 )
} }
bool SCH_SHEET_PATH::operator!=( const SCH_SHEET_PATH& d1 ) bool SCH_SHEET_PATH::operator!=( const SCH_SHEET_PATH& d1 ) const
{ {
if( m_numSheets != d1.m_numSheets ) if( m_numSheets != d1.m_numSheets )
return true; return true;
for( unsigned i = 0; i < m_numSheets; i++ ) for( unsigned i = 0; i < m_numSheets; i++ )
{ {
if( m_sheets[i] != d1.m_sheets[i] ) if( m_sheets[i] != d1.m_sheets[i] )
{
/*
printf( "micompare this:'%s' d1:'%s'\n",
CONV_TO_UTF8( PathHumanReadable() ),
CONV_TO_UTF8( d1.PathHumanReadable() ) );
*/
return true; return true;
}
} }
return false; return false;
......
...@@ -150,7 +150,7 @@ public: ...@@ -150,7 +150,7 @@ public:
* stamps in the path. (Time stamps do not change even when editing * stamps in the path. (Time stamps do not change even when editing
* sheet parameters). * sheet parameters).
*/ */
wxString PathHumanReadable(); wxString PathHumanReadable() const;
/** Function BuildSheetPathInfoFromSheetPathValue /** Function BuildSheetPathInfoFromSheetPathValue
* Fill this with data to access to the hierarchical sheet known by its * Fill this with data to access to the hierarchical sheet known by its
...@@ -207,9 +207,9 @@ public: ...@@ -207,9 +207,9 @@ public:
bool operator=( const SCH_SHEET_PATH& d1 ); bool operator=( const SCH_SHEET_PATH& d1 );
bool operator==( const SCH_SHEET_PATH& d1 ); bool operator==( const SCH_SHEET_PATH& d1 ) const;
bool operator!=( const SCH_SHEET_PATH& d1 ); bool operator!=( const SCH_SHEET_PATH& d1 ) const;
}; };
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#include "class_netlist_object.h" #include "class_netlist_object.h"
#if defined(DEBUG) #if defined(DEBUG)
#include <iostream> #include <iostream>
const char* ShowType( NetObjetType aType ) const char* ShowType( NetObjetType aType )
...@@ -134,3 +133,4 @@ NETLIST_OBJECT::NETLIST_OBJECT( NETLIST_OBJECT& aSource ) ...@@ -134,3 +133,4 @@ NETLIST_OBJECT::NETLIST_OBJECT( NETLIST_OBJECT& aSource )
NETLIST_OBJECT::~NETLIST_OBJECT() NETLIST_OBJECT::~NETLIST_OBJECT()
{ {
} }
...@@ -6,6 +6,9 @@ ...@@ -6,6 +6,9 @@
#ifndef _CLASS_NETLIST_OBJECT_H_ #ifndef _CLASS_NETLIST_OBJECT_H_
#define _CLASS_NETLIST_OBJECT_H_ #define _CLASS_NETLIST_OBJECT_H_
#include "class_pin.h" // LIB_PIN::ReturnPinStringNum( m_PinNum )
/* Type of Net objects (wires, labels, pins...) */ /* Type of Net objects (wires, labels, pins...) */
enum NetObjetType { enum NetObjetType {
NET_ITEM_UNSPECIFIED, // only for not yet initialized instances NET_ITEM_UNSPECIFIED, // only for not yet initialized instances
...@@ -105,6 +108,17 @@ public: ...@@ -105,6 +108,17 @@ public:
void SetNet( int aNetCode ) { m_NetCode = aNetCode; } void SetNet( int aNetCode ) { m_NetCode = aNetCode; }
int GetNet() const { return m_NetCode; } int GetNet() const { return m_NetCode; }
/**
* Function GetPinNum
* returns a pin number in wxString form. Pin numbers are not always
* numbers. "A23" would be a valid pin number.
*/
wxString GetPinNumText()
{
// hide the ugliness in here, but do it inline.
return LIB_PIN::ReturnPinStringNum( m_PinNum );
}
}; };
#endif // _CLASS_NETLIST_OBJECT_H_ #endif // _CLASS_NETLIST_OBJECT_H_
...@@ -1485,12 +1485,6 @@ wxString LIB_PIN::ReturnPinStringNum( long aPinNum ) ...@@ -1485,12 +1485,6 @@ wxString LIB_PIN::ReturnPinStringNum( long aPinNum )
} }
wxString LIB_PIN::GetNumber( void )
{
return ReturnPinStringNum( m_PinNum );
}
/** Function LIB_PIN::SetPinNumFromString() /** Function LIB_PIN::SetPinNumFromString()
* fill the buffer with pin num as a wxString * fill the buffer with pin num as a wxString
* Pin num is coded as a long * Pin num is coded as a long
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#ifndef CLASS_PIN_H #ifndef CLASS_PIN_H
#define CLASS_PIN_H #define CLASS_PIN_H
#include "classes_body_items.h"
#define TARGET_PIN_DIAM 12 /* Circle diameter drawn at the active end of #define TARGET_PIN_DIAM 12 /* Circle diameter drawn at the active end of
* pins */ * pins */
...@@ -159,7 +160,12 @@ public: ...@@ -159,7 +160,12 @@ public:
*/ */
void ReturnPinStringNum( wxString& aStringBuffer ) const; void ReturnPinStringNum( wxString& aStringBuffer ) const;
wxString GetNumber();
wxString GetNumber()
{
return ReturnPinStringNum( m_PinNum );
}
/** Function ReturnPinStringNum (static function) /** Function ReturnPinStringNum (static function)
* Pin num is coded as a long or 4 ascii chars * Pin num is coded as a long or 4 ascii chars
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
#ifndef CLASSES_BODY_ITEMS_H #ifndef CLASSES_BODY_ITEMS_H
#define CLASSES_BODY_ITEMS_H #define CLASSES_BODY_ITEMS_H
#include "base_struct.h"
class LIB_COMPONENT; class LIB_COMPONENT;
class PLOTTER; class PLOTTER;
......
...@@ -48,51 +48,22 @@ ...@@ -48,51 +48,22 @@
#include "build_version.h" #include "build_version.h"
#include <set>
/** /**
* @bug - Every place in this file where fprintf() is used and the return * @bug - Every place in this file where fprintf() is used and the return
* is not checked is a bug. The fprintf() function can fail and * is not checked is a bug. The fprintf() function can fail and
* returns a value less than 0 when it does. * returns a value less than 0 when it does.
*/ */
static bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFileName );
static bool WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f,
bool with_pcbnew );
static void WriteNetListCADSTAR( WinEDA_SchematicFrame* frame, FILE* f );
static void WriteListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjectsList );
static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f,
bool use_netnames );
static bool WriteGENERICListOfNetsTxt( FILE* f, NETLIST_OBJECT_LIST& aObjectsList );
static bool WriteGENERICListOfNets( wxXmlNode* aNode, NETLIST_OBJECT_LIST& aObjectsList );
static void AddPinToComponentPinList( SCH_COMPONENT* Component,
SCH_SHEET_PATH* sheet,
LIB_PIN* PinEntry );
static void FindAllInstancesOfComponent( SCH_COMPONENT* Component,
LIB_COMPONENT* aEntry,
SCH_SHEET_PATH* Sheet_in );
static bool SortPinsByNum( NETLIST_OBJECT* Pin1, NETLIST_OBJECT* Pin2 );
static void EraseDuplicatePins( NETLIST_OBJECT_LIST& aPinList );
static NETLIST_OBJECT_LIST s_SortedComponentPinList;
#include <set>
/** /**
* Class UNIQUE_STRINGS * Class UNIQUE_STRINGS
* will keep track of unique wxStrings and is useful in telling if a string * tracks unique wxStrings and is useful in telling if a string
* has been seen before. * has been seen before.
*/ */
class UNIQUE_STRINGS class UNIQUE_STRINGS
{ {
private:
std::set<wxString> m_set; ///< set of wxStrings already found std::set<wxString> m_set; ///< set of wxStrings already found
public: public:
...@@ -119,8 +90,77 @@ bool UNIQUE_STRINGS::Lookup( const wxString& aString ) ...@@ -119,8 +90,77 @@ bool UNIQUE_STRINGS::Lookup( const wxString& aString )
return ret; return ret;
} }
/// Used for multi part per package components, avoids using a component more than once.
static UNIQUE_STRINGS s_ReferencesAlreadyFound; /**
* Class NETLIST_HELP
* is a private implementation class used in this source file to keep track
* of and recycle datastructures used in the generation of various exported netlist
* files. Since it is private it is not in a header file.
*/
class NETLIST_HELP
{
NETLIST_OBJECT_LIST m_SortedComponentPinList;
/// Used for "multi parts per package" components, avoids processing a lib component more than once.
UNIQUE_STRINGS m_ReferencesAlreadyFound;
/**
* Function sprintPinNetName
* formats the net name for \a aPin using \a aNetNameFormat into \a aResult.
* <p>
* Net name is:
* <ul>
* <li> "?" if pin not connected
* <li> "netname" for global net (like gnd, vcc ..
* <li> "netname_sheetnumber" for the usual nets
* </ul>
*/
static void sprintPinNetName( wxString* aResult, const wxString& aNetNameFormat, NETLIST_OBJECT* aPin );
/**
* Function findNextComponentAndCreatePinList
* finds a "suitable" component from the DrawList and optionally builds
* its pin list int m_SortedComponentPinList. The list is sorted by pin num.
* A suitable component is a "new" real component (power symbols are not
* considered).
*/
SCH_COMPONENT* findNextComponentAndCreatPinList( EDA_BaseStruct* aItem,
SCH_SHEET_PATH* aSheetPath );
public:
bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFileName );
/**
* Function WriteNetListPCBNEW
* generates a net list file (Format 2 improves ORCAD PCB)
* = TRUE if with_pcbnew
* Format Pcbnew (OrcadPcb2 + reviews and lists of net)
* = FALSE if with_pcbnew
* Format ORCADPCB2 strict
*/
bool WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f,
bool with_pcbnew );
void WriteNetListCADSTAR( WinEDA_SchematicFrame* frame, FILE* f );
void WriteListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjectsList );
void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f,
bool use_netnames );
bool WriteGENERICListOfNetsTxt( FILE* f, NETLIST_OBJECT_LIST& aObjectsList );
bool WriteGENERICListOfNets( wxXmlNode* aNode, NETLIST_OBJECT_LIST& aObjectsList );
bool AddPinToComponentPinList( SCH_COMPONENT* Component,
SCH_SHEET_PATH* sheet,
LIB_PIN* PinEntry );
void FindAllInstancesOfComponent( SCH_COMPONENT* Component,
LIB_COMPONENT* aEntry,
SCH_SHEET_PATH* Sheet_in );
void EraseDuplicatePins( NETLIST_OBJECT_LIST& aPinList );
};
/** /**
...@@ -136,8 +176,9 @@ static UNIQUE_STRINGS s_ReferencesAlreadyFound; ...@@ -136,8 +176,9 @@ static UNIQUE_STRINGS s_ReferencesAlreadyFound;
bool WinEDA_SchematicFrame::WriteNetListFile( int aFormat, const wxString& aFullFileName, bool WinEDA_SchematicFrame::WriteNetListFile( int aFormat, const wxString& aFullFileName,
bool aUse_netnames ) bool aUse_netnames )
{ {
bool ret = true; bool ret = true;
FILE* f = NULL; FILE* f = NULL;
NETLIST_HELP helper;
if( aFormat < NET_TYPE_CUSTOM1 ) if( aFormat < NET_TYPE_CUSTOM1 )
{ {
...@@ -154,22 +195,22 @@ bool WinEDA_SchematicFrame::WriteNetListFile( int aFormat, const wxString& aFull ...@@ -154,22 +195,22 @@ bool WinEDA_SchematicFrame::WriteNetListFile( int aFormat, const wxString& aFull
switch( aFormat ) switch( aFormat )
{ {
case NET_TYPE_PCBNEW: case NET_TYPE_PCBNEW:
ret = WriteNetListPCBNEW( this, f, TRUE ); ret = helper.WriteNetListPCBNEW( this, f, TRUE );
fclose( f ); fclose( f );
break; break;
case NET_TYPE_ORCADPCB2: case NET_TYPE_ORCADPCB2:
ret = WriteNetListPCBNEW( this, f, FALSE ); ret = helper.WriteNetListPCBNEW( this, f, FALSE );
fclose( f ); fclose( f );
break; break;
case NET_TYPE_CADSTAR: case NET_TYPE_CADSTAR:
WriteNetListCADSTAR( this, f ); helper.WriteNetListCADSTAR( this, f );
fclose( f ); fclose( f );
break; break;
case NET_TYPE_SPICE: case NET_TYPE_SPICE:
WriteNetListPspice( this, f, aUse_netnames ); helper.WriteNetListPspice( this, f, aUse_netnames );
fclose( f ); fclose( f );
break; break;
...@@ -178,7 +219,7 @@ bool WinEDA_SchematicFrame::WriteNetListFile( int aFormat, const wxString& aFull ...@@ -178,7 +219,7 @@ bool WinEDA_SchematicFrame::WriteNetListFile( int aFormat, const wxString& aFull
wxFileName tmpFile = aFullFileName; wxFileName tmpFile = aFullFileName;
tmpFile.SetExt( wxT( "tmp" ) ); tmpFile.SetExt( wxT( "tmp" ) );
ret = Write_GENERIC_NetList( this, tmpFile.GetFullPath() ); ret = helper.Write_GENERIC_NetList( this, tmpFile.GetFullPath() );
if( !ret ) if( !ret )
break; break;
...@@ -210,31 +251,76 @@ bool WinEDA_SchematicFrame::WriteNetListFile( int aFormat, const wxString& aFull ...@@ -210,31 +251,76 @@ bool WinEDA_SchematicFrame::WriteNetListFile( int aFormat, const wxString& aFull
} }
/* Find a "suitable" component from the DrawList /*
* build its pin list s_SortedComponentPinList. * Comparison routine for sorting by pin numbers.
* The list is sorted by pin num
* A suitable component is a "new" real component (power symbols are not
* considered)
* Must be deallocated by the user
*/ */
static SCH_COMPONENT* FindNextComponentAndCreatPinList( EDA_BaseStruct* item, static bool sortPinsByNum( NETLIST_OBJECT* Pin1, NETLIST_OBJECT* Pin2 )
SCH_SHEET_PATH* path ) {
// return "lhs < rhs"
return RefDesStringCompare( Pin1->GetPinNumText(), Pin2->GetPinNumText() ) < 0;
}
void NETLIST_HELP::sprintPinNetName( wxString* aResult,
const wxString& aNetNameFormat, NETLIST_OBJECT* aPin )
{
int netcode = aPin->GetNet();
// Not wxString::Clear(), which would free memory. We want the worst
// case wxString memory to grow to avoid reallocation from within the
// caller's loop.
aResult->Empty();
if( netcode != 0 && aPin->m_FlagOfConnection == PAD_CONNECT )
{
NETLIST_OBJECT* netref = aPin->m_NetNameCandidate;
if( netref )
*aResult = netref->m_Label;
if( !aResult->IsEmpty() )
{
// prefix non global label names with the sheet path, to avoid name collisions
if( netref->m_Type != NET_PINLABEL && netref->m_Type != NET_GLOBLABEL )
{
wxString lnet = *aResult;
*aResult = netref->m_SheetList.PathHumanReadable();
// If sheet path is too long, use the time stamp name instead
if( aResult->Length() > 32 )
*aResult = netref->m_SheetList.Path();
*aResult += lnet;
}
}
else
{
aResult->Printf( aNetNameFormat.GetData(), netcode );
}
}
}
SCH_COMPONENT* NETLIST_HELP::findNextComponentAndCreatPinList( EDA_BaseStruct* aItem,
SCH_SHEET_PATH* aSheetPath )
{ {
s_SortedComponentPinList.clear(); wxString ref;
m_SortedComponentPinList.clear();
// continue searching from the middle of a linked list // continue searching from the middle of a linked list (the draw list)
for( ; item; item = item->Next() ) for( ; aItem; aItem = aItem->Next() )
{ {
if( item->Type() != TYPE_SCH_COMPONENT ) if( aItem->Type() != TYPE_SCH_COMPONENT )
continue; continue;
// found next component // found next component
SCH_COMPONENT* comp = (SCH_COMPONENT*) item; SCH_COMPONENT* comp = (SCH_COMPONENT*) aItem;
// Power symbols and other components which have the reference starting // Power symbols and other components which have the reference starting
// with "#" are not included in netlist (pseudo or virtual components) // with "#" are not included in netlist (pseudo or virtual components)
wxString ref = comp->GetRef( path ); ref = comp->GetRef( aSheetPath );
if( ref[0] == wxChar( '#' ) ) // ignore it if( ref[0] == wxChar( '#' ) )
continue; continue;
// if( Component->m_FlagControlMulti == 1 ) // if( Component->m_FlagControlMulti == 1 )
...@@ -247,22 +333,28 @@ static SCH_COMPONENT* FindNextComponentAndCreatPinList( EDA_BaseStruct* item, ...@@ -247,22 +333,28 @@ static SCH_COMPONENT* FindNextComponentAndCreatPinList( EDA_BaseStruct* item,
if( !entry ) if( !entry )
continue; continue;
// If Multi parts per package // If component is a "multi parts per package" type
if( entry->GetPartCount() > 1 ) if( entry->GetPartCount() > 1 )
{ {
// test if already visited, and if so skip // test if already visited, and if so skip
if( s_ReferencesAlreadyFound.Lookup( ref ) ) if( m_ReferencesAlreadyFound.Lookup( ref ) )
continue; continue;
// Collect all parts and pins for this first occurance of reference // Collect all parts and pins for this first occurance of reference.
FindAllInstancesOfComponent( comp, entry, path ); // This is only done once, it would be too expensive otherwise.
FindAllInstancesOfComponent( comp, entry, aSheetPath );
if( ref == wxString( wxT("U1") ) )
{
printf("U1 m_SortedComponentPinList.size():%zu\n", m_SortedComponentPinList.size() );
}
} }
else // entry->GetPartCount() <= 1 means one part per package else // entry->GetPartCount() <= 1 means one part per package
{ {
LIB_PIN_LIST pins; LIB_PIN_LIST pins; // constructed once here
entry->GetPins( pins, comp->GetUnitSelection( path ), comp->m_Convert ); entry->GetPins( pins, comp->GetUnitSelection( aSheetPath ), comp->m_Convert );
for( size_t i = 0; i < pins.size(); i++ ) for( size_t i = 0; i < pins.size(); i++ )
{ {
...@@ -270,16 +362,16 @@ static SCH_COMPONENT* FindNextComponentAndCreatPinList( EDA_BaseStruct* item, ...@@ -270,16 +362,16 @@ static SCH_COMPONENT* FindNextComponentAndCreatPinList( EDA_BaseStruct* item,
wxASSERT( pin->Type() == COMPONENT_PIN_DRAW_TYPE ); wxASSERT( pin->Type() == COMPONENT_PIN_DRAW_TYPE );
AddPinToComponentPinList( comp, path, pin ); AddPinToComponentPinList( comp, aSheetPath, pin );
} }
} }
// Sort pins in s_SortedComponentPinList by pin number // Sort pins in m_SortedComponentPinList by pin number
sort( s_SortedComponentPinList.begin(), sort( m_SortedComponentPinList.begin(),
s_SortedComponentPinList.end(), SortPinsByNum ); m_SortedComponentPinList.end(), sortPinsByNum );
// Remove duplicate Pins in s_SortedComponentPinList // Remove duplicate Pins in m_SortedComponentPinList
EraseDuplicatePins( s_SortedComponentPinList ); EraseDuplicatePins( m_SortedComponentPinList );
return comp; return comp;
} }
...@@ -288,48 +380,6 @@ static SCH_COMPONENT* FindNextComponentAndCreatPinList( EDA_BaseStruct* item, ...@@ -288,48 +380,6 @@ static SCH_COMPONENT* FindNextComponentAndCreatPinList( EDA_BaseStruct* item,
} }
/* Return the net name for the pin Pin.
* Net name is:
* "?" if pin not connected
* "netname" for global net (like gnd, vcc ..
* "netname_sheetnumber" for the usual nets
*/
static wxString ReturnPinNetName( NETLIST_OBJECT* Pin, const wxString& DefaultFormatNetname )
{
int netcode = Pin->GetNet();
wxString NetName;
if( ( netcode == 0 ) || ( Pin->m_FlagOfConnection != PAD_CONNECT ) )
return NetName;
NETLIST_OBJECT* netref = Pin->m_NetNameCandidate;
if( netref )
NetName = netref->m_Label;
if( !NetName.IsEmpty() )
{
// prefix non global labels names by the sheet path, to avoid names collisions
if( ( netref->m_Type != NET_PINLABEL )
&& ( netref->m_Type != NET_GLOBLABEL ) )
{
wxString lnet = NetName;
NetName = netref->m_SheetList.PathHumanReadable();
// If sheet path is too long, use the time stamp name instead
if( NetName.Length() > 32 )
NetName = netref->m_SheetList.Path();
NetName += lnet;
}
}
else
{
NetName.Printf( DefaultFormatNetname.GetData(), netcode );
}
return NetName;
}
/** /**
* Function Node * Function Node
* is a convenience function that creates a new wxXmlNode with an optional textual child. * is a convenience function that creates a new wxXmlNode with an optional textual child.
...@@ -353,7 +403,7 @@ static wxXmlNode* Node( const wxString& aName, const wxString& aTextualContent = ...@@ -353,7 +403,7 @@ static wxXmlNode* Node( const wxString& aName, const wxString& aTextualContent =
* creates a generic netlist, now in XML. * creates a generic netlist, now in XML.
* @return bool - true if there were no errors, else false. * @return bool - true if there were no errors, else false.
*/ */
bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFileName ) bool NETLIST_HELP::Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFileName )
{ {
#if 1 #if 1
// output the XML format netlist. // output the XML format netlist.
...@@ -391,7 +441,7 @@ bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFi ...@@ -391,7 +441,7 @@ bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFi
const wxString sPart = wxT( "part" ); const wxString sPart = wxT( "part" );
const wxString sNames = wxT( "names" ); const wxString sNames = wxT( "names" );
s_ReferencesAlreadyFound.Clear(); m_ReferencesAlreadyFound.Clear();
xdoc.SetRoot( xroot = Node( wxT( "netlist" ) ) ); xdoc.SetRoot( xroot = Node( wxT( "netlist" ) ) );
xroot->AddProperty( wxT( "version" ), wxT( "B" ) ); xroot->AddProperty( wxT( "version" ), wxT( "B" ) );
...@@ -406,7 +456,7 @@ bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFi ...@@ -406,7 +456,7 @@ bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFi
{ {
for( EDA_BaseStruct* schItem = path->LastDrawList(); schItem; schItem = schItem->Next() ) for( EDA_BaseStruct* schItem = path->LastDrawList(); schItem; schItem = schItem->Next() )
{ {
SCH_COMPONENT* comp = FindNextComponentAndCreatPinList( schItem, path ); SCH_COMPONENT* comp = findNextComponentAndCreatPinList( schItem, path );
if( !comp ) if( !comp )
break; // No component left break; // No component left
...@@ -497,7 +547,7 @@ bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFi ...@@ -497,7 +547,7 @@ bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFi
return false; return false;
} }
s_ReferencesAlreadyFound.Clear(); m_ReferencesAlreadyFound.Clear();
ret |= fprintf( out, "$BeginNetlist\n" ); ret |= fprintf( out, "$BeginNetlist\n" );
...@@ -510,7 +560,7 @@ bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFi ...@@ -510,7 +560,7 @@ bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFi
{ {
for( EDA_BaseStruct* schItem = path->LastDrawList(); schItem; schItem = schItem->Next() ) for( EDA_BaseStruct* schItem = path->LastDrawList(); schItem; schItem = schItem->Next() )
{ {
SCH_COMPONENT* comp = FindNextComponentAndCreatPinList( schItem, path ); SCH_COMPONENT* comp = findNextComponentAndCreatPinList( schItem, path );
if( !comp ) if( !comp )
break; // No component left break; // No component left
...@@ -541,9 +591,9 @@ bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFi ...@@ -541,9 +591,9 @@ bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFi
// Write pin list: // Write pin list:
ret |= fprintf( out, "$BeginPinList\n" ); ret |= fprintf( out, "$BeginPinList\n" );
for( unsigned ii = 0; ii < s_SortedComponentPinList.size(); ii++ ) for( unsigned ii = 0; ii < m_SortedComponentPinList.size(); ii++ )
{ {
NETLIST_OBJECT* Pin = s_SortedComponentPinList[ii]; NETLIST_OBJECT* Pin = m_SortedComponentPinList[ii];
if( !Pin ) if( !Pin )
continue; continue;
...@@ -586,7 +636,7 @@ bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFi ...@@ -586,7 +636,7 @@ bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFi
* [.-] Or PSpice gnucap are beginning * [.-] Or PSpice gnucap are beginning
* + + Gnucap and PSpice are ultimately NetList * + + Gnucap and PSpice are ultimately NetList
*/ */
static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f, bool use_netnames ) void NETLIST_HELP::WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f, bool use_netnames )
{ {
char Line[1024]; char Line[1024];
SCH_SHEET_PATH* sheet; SCH_SHEET_PATH* sheet;
...@@ -596,6 +646,7 @@ static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f, bool use_ ...@@ -596,6 +646,7 @@ static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f, bool use_
wxString text; wxString text;
wxArrayString SpiceCommandAtBeginFile, SpiceCommandAtEndFile; wxArrayString SpiceCommandAtBeginFile, SpiceCommandAtEndFile;
wxString msg; wxString msg;
wxString netName;
#define BUFYPOS_LEN 4 #define BUFYPOS_LEN 4
wxChar bufnum[BUFYPOS_LEN + 1]; wxChar bufnum[BUFYPOS_LEN + 1];
...@@ -623,12 +674,15 @@ static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f, bool use_ ...@@ -623,12 +674,15 @@ static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f, bool use_
wxChar ident; wxChar ident;
if( DrawList->Type() != TYPE_SCH_TEXT ) if( DrawList->Type() != TYPE_SCH_TEXT )
continue; continue;
#define DRAWTEXT ( (SCH_TEXT*) DrawList ) #define DRAWTEXT ( (SCH_TEXT*) DrawList )
text = DRAWTEXT->m_Text; if( text.IsEmpty() ) text = DRAWTEXT->m_Text; if( text.IsEmpty() )
continue; continue;
ident = text.GetChar( 0 ); ident = text.GetChar( 0 );
if( ident != '.' && ident != '-' && ident != '+' ) if( ident != '.' && ident != '-' && ident != '+' )
continue; continue;
text.Remove( 0, 1 ); // Remove the first char. text.Remove( 0, 1 ); // Remove the first char.
text.Remove( 6 ); // text contains 6 char. text.Remove( 6 ); // text contains 6 char.
text.MakeLower(); text.MakeLower();
...@@ -673,34 +727,37 @@ static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f, bool use_ ...@@ -673,34 +727,37 @@ static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f, bool use_
// Create component list // Create component list
s_ReferencesAlreadyFound.Clear(); m_ReferencesAlreadyFound.Clear();
for( sheet = SheetList.GetFirst(); sheet != NULL; sheet = SheetList.GetNext() ) for( sheet = SheetList.GetFirst(); sheet != NULL; sheet = SheetList.GetNext() )
{ {
for( DrawList = sheet->LastDrawList(); DrawList != NULL; DrawList = DrawList->Next() ) for( DrawList = sheet->LastDrawList(); DrawList != NULL; DrawList = DrawList->Next() )
{ {
DrawList = Component = FindNextComponentAndCreatPinList( DrawList, sheet ); DrawList = Component = findNextComponentAndCreatPinList( DrawList, sheet );
if( Component == NULL ) if( Component == NULL )
break; break;
fprintf( f, "%s ", CONV_TO_UTF8( Component->GetRef( sheet ) ) ); fprintf( f, "%s ", CONV_TO_UTF8( Component->GetRef( sheet ) ) );
// Write pin list: // Write pin list:
for( unsigned ii = 0; ii < s_SortedComponentPinList.size(); ii++ ) for( unsigned ii = 0; ii < m_SortedComponentPinList.size(); ii++ )
{ {
NETLIST_OBJECT* Pin = s_SortedComponentPinList[ii]; NETLIST_OBJECT* Pin = m_SortedComponentPinList[ii];
if( !Pin ) if( !Pin )
continue; continue;
wxString NetName = ReturnPinNetName( Pin, wxT( "N-%.6d" ) );
if( NetName.IsEmpty() ) sprintPinNetName( &netName , wxT( "N-%.6d" ), Pin );
NetName = wxT( "?" );
if( netName.IsEmpty() )
netName = wxT( "?" );
if( use_netnames ) if( use_netnames )
fprintf( f, " %s", CONV_TO_UTF8( NetName ) ); fprintf( f, " %s", CONV_TO_UTF8( netName ) );
else // Use number for net names (with net number = 0 for else // Use number for net names (with net number = 0 for
// "GND" // "GND"
{ {
// NetName = "0" is "GND" net for Spice // NetName = "0" is "GND" net for Spice
if( NetName == wxT( "0" ) || NetName == wxT( "GND" ) ) if( netName == wxT( "0" ) || netName == wxT( "GND" ) )
fprintf( f, " 0" ); fprintf( f, " 0" );
else else
fprintf( f, " %d", Pin->GetNet() ); fprintf( f, " %d", Pin->GetNet() );
...@@ -712,7 +769,7 @@ static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f, bool use_ ...@@ -712,7 +769,7 @@ static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f, bool use_
} }
} }
s_SortedComponentPinList.clear(); m_SortedComponentPinList.clear();
/* Print texts starting by [+]pspice , ou [+]gnucap */ /* Print texts starting by [+]pspice , ou [+]gnucap */
nbitems = SpiceCommandAtEndFile.GetCount(); nbitems = SpiceCommandAtEndFile.GetCount();
...@@ -733,18 +790,13 @@ static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f, bool use_ ...@@ -733,18 +790,13 @@ static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f, bool use_
} }
/* Generate net list file (Format 2 improves ORCAD PCB) bool NETLIST_HELP::WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with_pcbnew )
* = TRUE if with_pcbnew
* Format Pcbnew (OrcadPcb2 + reviews and lists of net)
* = FALSE if with_pcbnew
* Format ORCADPCB2 strict
*/
static bool WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with_pcbnew )
{ {
wxString field; wxString field;
wxString footprint; wxString footprint;
char dateBuf[256]; char dateBuf[256];
int ret = 0; // zero now, OR in the sign bit on error int ret = 0; // zero now, OR in the sign bit on error
wxString netName;
std::vector<OBJ_CMP_TO_LIST> cmpList; std::vector<OBJ_CMP_TO_LIST> cmpList;
...@@ -757,7 +809,7 @@ static bool WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with ...@@ -757,7 +809,7 @@ static bool WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with
// Create netlist module section // Create netlist module section
s_ReferencesAlreadyFound.Clear(); m_ReferencesAlreadyFound.Clear();
SCH_SHEET_LIST sheetList; SCH_SHEET_LIST sheetList;
...@@ -765,7 +817,7 @@ static bool WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with ...@@ -765,7 +817,7 @@ static bool WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with
{ {
for( EDA_BaseStruct* item = path->LastDrawList(); item; item = item->Next() ) for( EDA_BaseStruct* item = path->LastDrawList(); item; item = item->Next() )
{ {
SCH_COMPONENT* comp = FindNextComponentAndCreatPinList( item, path ); SCH_COMPONENT* comp = findNextComponentAndCreatPinList( item, path );
if( !comp ) if( !comp )
break; break;
...@@ -815,21 +867,24 @@ static bool WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with ...@@ -815,21 +867,24 @@ static bool WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with
} }
ret |= fprintf( f, "\n" ); ret |= fprintf( f, "\n" );
printf( "%-10s pincount:%zu\n", CONV_TO_UTF8( comp->GetRef( path ) ),
m_SortedComponentPinList.size() );
// Write pin list: // Write pin list:
for( unsigned ii = 0; ii < s_SortedComponentPinList.size(); ii++ ) for( unsigned ii = 0; ii < m_SortedComponentPinList.size(); ii++ )
{ {
NETLIST_OBJECT* pin = s_SortedComponentPinList[ii]; NETLIST_OBJECT* pin = m_SortedComponentPinList[ii];
if( !pin ) if( !pin )
continue; continue;
wxString netname = ReturnPinNetName( pin, wxT( "N-%.6d" ) ); sprintPinNetName( &netName, wxT( "N-%.6d" ), pin );
if( netname.IsEmpty() ) if( netName.IsEmpty() )
netname = wxT( "?" ); netName = wxT( "?" );
netname.Replace( wxT( " " ), wxT( "_" ) ); netName.Replace( wxT( " " ), wxT( "_" ) );
ret |= fprintf( f, " ( %4.4s %s )\n", (char*) &pin->m_PinNum, ret |= fprintf( f, " ( %4.4s %s )\n", (char*) &pin->m_PinNum,
CONV_TO_UTF8( netname ) ); CONV_TO_UTF8( netName ) );
} }
ret |= fprintf( f, " )\n" ); ret |= fprintf( f, " )\n" );
...@@ -838,7 +893,7 @@ static bool WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with ...@@ -838,7 +893,7 @@ static bool WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with
ret |= fprintf( f, ")\n*\n" ); ret |= fprintf( f, ")\n*\n" );
s_SortedComponentPinList.clear(); m_SortedComponentPinList.clear();
// Write the allowed footprint list for each component // Write the allowed footprint list for each component
if( with_pcbnew && cmpList.size() ) if( with_pcbnew && cmpList.size() )
...@@ -887,34 +942,43 @@ static bool WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with ...@@ -887,34 +942,43 @@ static bool WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with
/* /*
* Add a new pin description in the pin list s_SortedComponentPinList * Add a new pin description in the pin list m_SortedComponentPinList
* a pin description is a pointer to the corresponding structure * a pin description is a pointer to the corresponding structure
* created by BuildNetList() in the table g_NetObjectslist * created by BuildNetList() in the table g_NetObjectslist
*/ */
static void AddPinToComponentPinList( SCH_COMPONENT* Component, bool NETLIST_HELP::AddPinToComponentPinList( SCH_COMPONENT* aComponent,
SCH_SHEET_PATH* sheetlist, LIB_PIN* Pin ) SCH_SHEET_PATH* aSheetPath, LIB_PIN* aPin )
{ {
// Search the PIN description for Pin in g_NetObjectslist // Search the PIN description for Pin in g_NetObjectslist
for( unsigned ii = 0; ii < g_NetObjectslist.size(); ii++ ) for( unsigned ii = 0; ii < g_NetObjectslist.size(); ii++ )
{ {
if( g_NetObjectslist[ii]->m_Type != NET_PIN ) NETLIST_OBJECT* pin = g_NetObjectslist[ii];
if( pin->m_Type != NET_PIN )
continue; continue;
if( g_NetObjectslist[ii]->m_Link != Component )
if( pin->m_Link != aComponent )
continue; continue;
if( g_NetObjectslist[ii]->m_SheetList != *sheetlist )
if( pin->m_PinNum != aPin->m_PinNum )
continue; continue;
if( g_NetObjectslist[ii]->m_PinNum != Pin->m_PinNum )
// most expensive test at the end.
if( pin->m_SheetList != *aSheetPath )
continue; continue;
s_SortedComponentPinList.push_back( g_NetObjectslist[ii] ); m_SortedComponentPinList.push_back( pin );
if( s_SortedComponentPinList.size() >= MAXPIN ) if( m_SortedComponentPinList.size() >= MAXPIN )
{ {
// Log message for Internal error // Log message for Internal error
DisplayError( NULL, wxT( "AddPinToComponentPinList err: MAXPIN reached" ) ); DisplayError( NULL, wxT( "AddPinToComponentPinList err: MAXPIN reached" ) );
return;
} }
return true; // we're done, we appended.
} }
return false;
} }
...@@ -932,7 +996,7 @@ static void AddPinToComponentPinList( SCH_COMPONENT* Component, ...@@ -932,7 +996,7 @@ static void AddPinToComponentPinList( SCH_COMPONENT* Component,
* given component. * given component.
* Note: this list *MUST* be sorted by pin number (.m_PinNum member value) * Note: this list *MUST* be sorted by pin number (.m_PinNum member value)
*/ */
static void EraseDuplicatePins( NETLIST_OBJECT_LIST& aPinList ) void NETLIST_HELP::EraseDuplicatePins( NETLIST_OBJECT_LIST& aPinList )
{ {
if( aPinList.size() == 0 ) // Trivial case: component with no pin if( aPinList.size() == 0 ) // Trivial case: component with no pin
return; return;
...@@ -959,6 +1023,7 @@ static void EraseDuplicatePins( NETLIST_OBJECT_LIST& aPinList ) ...@@ -959,6 +1023,7 @@ static void EraseDuplicatePins( NETLIST_OBJECT_LIST& aPinList )
// other pin num end of duplicate list. // other pin num end of duplicate list.
if( aPinList[idxref]->m_PinNum != aPinList[jj]->m_PinNum ) if( aPinList[idxref]->m_PinNum != aPinList[jj]->m_PinNum )
break; break;
if( aPinList[idxref]->m_FlagOfConnection == PAD_CONNECT ) if( aPinList[idxref]->m_FlagOfConnection == PAD_CONNECT )
aPinList[jj] = NULL; aPinList[jj] = NULL;
else /* the reference pin is not connected: remove this pin if the else /* the reference pin is not connected: remove this pin if the
...@@ -980,81 +1045,83 @@ static void EraseDuplicatePins( NETLIST_OBJECT_LIST& aPinList ) ...@@ -980,81 +1045,83 @@ static void EraseDuplicatePins( NETLIST_OBJECT_LIST& aPinList )
/** /**
* Function FindAllInstancesOfComponent * Function FindAllInstancesOfComponent
* is used for multiple parts per package components. * is used for "multiple parts per package" components.
* *
* Search all instances of Component_in, * Search all instances of Component_in,
* Calls AddPinToComponentPinList() to and pins founds to the current * Calls AddPinToComponentPinList() to and pins founds to the current
* component pin list * component pin list
*/ */
static void FindAllInstancesOfComponent( SCH_COMPONENT* Component_in, void NETLIST_HELP::FindAllInstancesOfComponent( SCH_COMPONENT* aComponent,
LIB_COMPONENT* aEntry, LIB_COMPONENT* aEntry,
SCH_SHEET_PATH* Sheet_in ) SCH_SHEET_PATH* aSheetPath )
{ {
EDA_BaseStruct* SchItem; wxString ref = aComponent->GetRef( aSheetPath );
SCH_COMPONENT* Component2; wxString ref2;
LIB_PIN* pin;
SCH_SHEET_PATH* sheet;
wxString str, Reference = Component_in->GetRef( Sheet_in );
SCH_SHEET_LIST SheetList; SCH_SHEET_LIST sheetList;
for( sheet = SheetList.GetFirst(); sheet != NULL; sheet = SheetList.GetNext() ) for( SCH_SHEET_PATH* sheet = sheetList.GetFirst(); sheet; sheet = sheetList.GetNext() )
{ {
for( SchItem = sheet->LastDrawList(); SchItem; SchItem = SchItem->Next() ) for( EDA_BaseStruct* schItem = sheet->LastDrawList(); schItem; schItem = schItem->Next() )
{ {
if( SchItem->Type() != TYPE_SCH_COMPONENT ) if( schItem->Type() != TYPE_SCH_COMPONENT )
continue; continue;
Component2 = (SCH_COMPONENT*) SchItem; SCH_COMPONENT* comp2 = (SCH_COMPONENT*) schItem;
str = Component2->GetRef( sheet ); ref2 = comp2->GetRef( sheet );
if( str.CmpNoCase( Reference ) != 0 ) if( ref2.CmpNoCase( ref ) != 0 )
continue; continue;
if( aEntry == NULL ) if( aEntry == NULL )
continue; continue;
for( pin = aEntry->GetNextPin(); pin != NULL; pin = aEntry->GetNextPin( pin ) ) for( LIB_PIN* pin = aEntry->GetNextPin(); pin; pin = aEntry->GetNextPin( pin ) )
{ {
wxASSERT( pin->Type() == COMPONENT_PIN_DRAW_TYPE ); wxASSERT( pin->Type() == COMPONENT_PIN_DRAW_TYPE );
if( pin->m_Unit if( pin->m_Unit && pin->m_Unit != comp2->GetUnitSelection( aSheetPath ) )
&& ( pin->m_Unit != Component2->GetUnitSelection( sheet ) ) )
continue; continue;
if( pin->m_Convert if( pin->m_Convert && pin->m_Convert != comp2->m_Convert )
&& ( pin->m_Convert != Component2->m_Convert ) )
continue; continue;
// A suitable pin in found: add it to the current list #if defined(DEBUG)
AddPinToComponentPinList( Component2, sheet, pin ); printf( "AddPin %s %s\n", CONV_TO_UTF8(ref), CONV_TO_UTF8( pin->GetNumber() ) );
if( ref == wxString( wxT("U1") ) && pin->GetNumber() == wxString( wxT("A1") ) )
{
int debug = 1;
}
bool rc =
#endif
// A suitable pin is found: add it to the current list
AddPinToComponentPinList( comp2, aSheetPath, pin );
#if defined(DEBUG)
if( !rc )
{
printf("skipped pin %s %s\n",
CONV_TO_UTF8(ref),
CONV_TO_UTF8( pin->GetNumber() ) );
printf( "g_NetObjectslist.size():%zu\n",
g_NetObjectslist.size() );
}
#endif
} }
} }
} }
} }
/*
* Comparison routine for sorting by pin numbers.
*/
static bool SortPinsByNum( NETLIST_OBJECT* Pin1, NETLIST_OBJECT* Pin2 )
{
int Num1, Num2;
char Line[5];
Num1 = Pin1->m_PinNum;
Num2 = Pin2->m_PinNum;
Line[4] = 0;
memcpy( Line, &Num1, 4 ); Num1 = atoi( Line );
memcpy( Line, &Num2, 4 ); Num2 = atoi( Line );
return Num1 < Num2;
}
/* Written in the file / net list (ranked by Netcode), and elements that are /* Written in the file / net list (ranked by Netcode), and elements that are
* connected * connected
*/ */
static bool WriteGENERICListOfNetsTxt( FILE* f, NETLIST_OBJECT_LIST& aObjectsList ) bool NETLIST_HELP::WriteGENERICListOfNetsTxt( FILE* f, NETLIST_OBJECT_LIST& aObjectsList )
{ {
int ret = 0; int ret = 0;
int netCode; int netCode;
...@@ -1144,7 +1211,7 @@ static bool WriteGENERICListOfNetsTxt( FILE* f, NETLIST_OBJECT_LIST& aObjectsLis ...@@ -1144,7 +1211,7 @@ static bool WriteGENERICListOfNetsTxt( FILE* f, NETLIST_OBJECT_LIST& aObjectsLis
* Function WriteGENERICListOfNets * Function WriteGENERICListOfNets
* saves a netlist in xml format. * saves a netlist in xml format.
*/ */
static bool WriteGENERICListOfNets( wxXmlNode* aNode, NETLIST_OBJECT_LIST& aObjectsList ) bool NETLIST_HELP::WriteGENERICListOfNets( wxXmlNode* aNode, NETLIST_OBJECT_LIST& aObjectsList )
{ {
wxString netCodeTxt; wxString netCodeTxt;
wxString netName; wxString netName;
...@@ -1255,7 +1322,7 @@ wxString StartLine( wxT( "." ) ); ...@@ -1255,7 +1322,7 @@ wxString StartLine( wxT( "." ) );
* .. B * T3 1 * .. B * T3 1
*U1 * 14 *U1 * 14
*/ */
static void WriteNetListCADSTAR( WinEDA_SchematicFrame* frame, FILE* f ) void NETLIST_HELP::WriteNetListCADSTAR( WinEDA_SchematicFrame* frame, FILE* f )
{ {
wxString StartCmpDesc = StartLine + wxT( "ADD_COM" ); wxString StartCmpDesc = StartLine + wxT( "ADD_COM" );
wxString msg; wxString msg;
...@@ -1274,7 +1341,7 @@ static void WriteNetListCADSTAR( WinEDA_SchematicFrame* frame, FILE* f ) ...@@ -1274,7 +1341,7 @@ static void WriteNetListCADSTAR( WinEDA_SchematicFrame* frame, FILE* f )
fprintf( f, "\n" ); fprintf( f, "\n" );
// Create netlist module section // Create netlist module section
s_ReferencesAlreadyFound.Clear(); m_ReferencesAlreadyFound.Clear();
SCH_SHEET_LIST SheetList; SCH_SHEET_LIST SheetList;
...@@ -1282,7 +1349,7 @@ static void WriteNetListCADSTAR( WinEDA_SchematicFrame* frame, FILE* f ) ...@@ -1282,7 +1349,7 @@ static void WriteNetListCADSTAR( WinEDA_SchematicFrame* frame, FILE* f )
{ {
for( DrawList = sheet->LastDrawList(); DrawList != NULL; DrawList = DrawList->Next() ) for( DrawList = sheet->LastDrawList(); DrawList != NULL; DrawList = DrawList->Next() )
{ {
DrawList = Component = FindNextComponentAndCreatPinList( DrawList, sheet ); DrawList = Component = findNextComponentAndCreatPinList( DrawList, sheet );
if( Component == NULL ) if( Component == NULL )
break; break;
...@@ -1310,7 +1377,7 @@ static void WriteNetListCADSTAR( WinEDA_SchematicFrame* frame, FILE* f ) ...@@ -1310,7 +1377,7 @@ static void WriteNetListCADSTAR( WinEDA_SchematicFrame* frame, FILE* f )
fprintf( f, "\n" ); fprintf( f, "\n" );
s_SortedComponentPinList.clear(); m_SortedComponentPinList.clear();
WriteListOfNetsCADSTAR( f, g_NetObjectslist ); WriteListOfNetsCADSTAR( f, g_NetObjectslist );
...@@ -1326,7 +1393,7 @@ static void WriteNetListCADSTAR( WinEDA_SchematicFrame* frame, FILE* f ) ...@@ -1326,7 +1393,7 @@ static void WriteNetListCADSTAR( WinEDA_SchematicFrame* frame, FILE* f )
*. B U1 100 *. B U1 100
* 6 CA * 6 CA
*/ */
static void WriteListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjectsList ) void NETLIST_HELP::WriteListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjectsList )
{ {
wxString InitNetDesc = StartLine + wxT( "ADD_TER" ); wxString InitNetDesc = StartLine + wxT( "ADD_TER" );
wxString StartNetDesc = StartLine + wxT( "TER" ); wxString StartNetDesc = StartLine + wxT( "TER" );
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
// Buffer to build the list of items used in netlist and erc calculations // Buffer to build the list of items used in netlist and erc calculations
NETLIST_OBJECT_LIST g_NetObjectslist; NETLIST_OBJECT_LIST g_NetObjectslist;
//#define NETLIST_DEBUG #define NETLIST_DEBUG
static void PropageNetCode( int OldNetCode, int NewNetCode, int IsBus ); static void PropageNetCode( int OldNetCode, int NewNetCode, int IsBus );
static void SheetLabelConnect( NETLIST_OBJECT* SheetLabel ); static void SheetLabelConnect( NETLIST_OBJECT* SheetLabel );
......
...@@ -382,4 +382,4 @@ void MyFree( void* pt_mem ); ...@@ -382,4 +382,4 @@ void MyFree( void* pt_mem );
void* MyZMalloc( size_t nb_octets ); void* MyZMalloc( size_t nb_octets );
void* MyMalloc( size_t nb_octets ); void* MyMalloc( size_t nb_octets );
#endif /* __INCLUDE__COMMON_H__ */ #endif // __INCLUDE__COMMON_H__
...@@ -79,5 +79,27 @@ bool WildCompareString( const wxString& pattern, ...@@ -79,5 +79,27 @@ bool WildCompareString( const wxString& pattern,
*/ */
char* to_point( char* Text ); char* to_point( char* Text );
/**
* Function RefDesStringCompare
* acts just like the strcmp function but treats numbers within the string text
* correctly for sorting. eg. A10 > A2
* return -1 if first string is less than the second
* return 0 if the strings are equal
* return 1 if the first string is greater than the second
*/
int RefDesStringCompare( const wxString& lhs, const wxString& rhs );
/**
* Function SplitString
* breaks a string into three parts.
* The alphabetic preamble
* The numeric part
* Any alphabetic ending
* For example C10A is split to C 10 A
*/
int SplitString( wxString strToSplit,
wxString* strBeginning,
wxString* strDigits,
wxString* strEnd );
#endif /* __INCLUDE__KICAD_STRING_H__ */ #endif // __INCLUDE__KICAD_STRING_H__
...@@ -16,20 +16,22 @@ ...@@ -16,20 +16,22 @@
/** /**
* Function GetChars * Function GetChars
* returns a pointer to the actual character data, either 8 or * returns a wxChar* to the actual character data within a wxString, and is
* 16 bits wide, depending on how the wxWidgets library was compiled. * helpful for passing strings to wxString::Printf(wxT("%s"), GetChars(wxString) )
* <p>
* wxChar is defined to be <ul>
* <li> standard C style char when wxUSE_UNICODE==0 </li>
* <li> wchar_t when wxUSE_UNICODE==1 (the default). </li>
* <ul>
* i.e. it depends on how the wxWidgets library was compiled. There was a period
* during the development of wxWidgets 2.9 when GetData() was missing, so this
* function was used to provide insulation from that design change. It may
* no longer be needed, and is harmless. GetData() seems to be an acceptable
* alternative in all cases now.
*/ */
static inline const wxChar* GetChars( wxString s ) static inline const wxChar* GetChars( const wxString& s )
{ {
#if wxCHECK_VERSION( 2, 9, 0 ) #if wxCHECK_VERSION( 2, 9, 0 )
/* To be Fixed:
* Currently, access to the actual character data in <wxString::Printf
* is a moving target
* So, with wxWidgets 2.9.0 this line is subject to change:
*/
// return (const wxChar*) s.wx_str();
return (const wxChar*) s.c_str(); return (const wxChar*) s.c_str();
#else #else
return s.GetData(); return s.GetData();
......
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