++eeschema netlist.cpp and netform.cpp:
* Found several speed optimizations in the netlist export code. * Fixed a bug in EXPORT_HELP::FindAllInstancesOfComponent() that I had broke. * Now sort the pins properly if they have pin numbers like A1 and A10, i.e. alphanumerics in them.
This commit is contained in:
commit
d24caad246
|
@ -4,18 +4,25 @@ KiCad ChangeLog 2010
|
|||
Please add newer entries at the top, list the date and your name with
|
||||
email address.
|
||||
|
||||
2010-Jul-30 UPDATE Dick Hollenbeck <dick@softplc.com>
|
||||
2010-Aug-3 UPDATE Dick Hollenbeck <dick@softplc.com>
|
||||
================================================================================
|
||||
++eeschema netlist.cpp and netform.cpp:
|
||||
* Found several speed optimizations in the netlist export code.
|
||||
* Now sort the pins properly if they have pin numbers like A1 and A10,
|
||||
i.e. alphanumerics in them.
|
||||
|
||||
|
||||
2010-Jul-30 & 31 UPDATE Dick Hollenbeck <dick@softplc.com>
|
||||
================================================================================
|
||||
++eeschema:
|
||||
* Now link with XML support within wxWidgets.
|
||||
* Start of export the generic netlist in XML. Still need to rework the chain
|
||||
loaded netlist plugin.
|
||||
* Export the generic netlist in XML. Only the libpart elements are missing now.
|
||||
Still need to rework the chain loaded netlist plugin, but may do that in XSL.
|
||||
* OBJ_CMP_TO_LIST class now uses a std::string to hold the 8 bit string m_Ref,
|
||||
but hides this behind accessors which provide for both Unicode and 8 bit
|
||||
set and get functions.
|
||||
* build_BOM.cpp retains the selected filename on subsequent runs as a default.
|
||||
* Code cleaning, especially in build_BOM.cpp.
|
||||
* Will work tomorrow also.
|
||||
|
||||
|
||||
2010-jul-27, UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
|
||||
|
|
|
@ -320,3 +320,113 @@ char* strupper( char* 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,
|
|||
static void DeleteSubCmp( std::vector <OBJ_CMP_TO_LIST>& 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
|
||||
static char s_ExportSeparatorSymbol;
|
||||
|
@ -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()
|
|||
* (the "normal" path uses the time stamps which do not changes even when
|
||||
* editing sheet parameters)
|
||||
*/
|
||||
wxString SCH_SHEET_PATH::PathHumanReadable()
|
||||
wxString SCH_SHEET_PATH::PathHumanReadable() const
|
||||
{
|
||||
wxString s, t;
|
||||
|
||||
|
@ -355,6 +355,7 @@ SCH_ITEM* SCH_SHEET_PATH::MatchNextItem( wxFindReplaceData& aSearchData,
|
|||
bool SCH_SHEET_PATH::operator=( const SCH_SHEET_PATH& d1 )
|
||||
{
|
||||
m_numSheets = d1.m_numSheets;
|
||||
|
||||
unsigned i;
|
||||
for( i = 0; i < m_numSheets; i++ )
|
||||
{
|
||||
|
@ -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 )
|
||||
return false;
|
||||
|
||||
for( unsigned i = 0; i < m_numSheets; i++ )
|
||||
{
|
||||
if( m_sheets[i] != d1.m_sheets[i] )
|
||||
|
@ -384,15 +386,24 @@ 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 )
|
||||
return true;
|
||||
|
||||
for( unsigned i = 0; i < m_numSheets; 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 false;
|
||||
}
|
||||
|
|
|
@ -150,7 +150,7 @@ public:
|
|||
* stamps in the path. (Time stamps do not change even when editing
|
||||
* sheet parameters).
|
||||
*/
|
||||
wxString PathHumanReadable();
|
||||
wxString PathHumanReadable() const;
|
||||
|
||||
/** Function BuildSheetPathInfoFromSheetPathValue
|
||||
* Fill this with data to access to the hierarchical sheet known by its
|
||||
|
@ -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 ) const;
|
||||
|
||||
bool operator!=( const SCH_SHEET_PATH& d1 );
|
||||
bool operator!=( const SCH_SHEET_PATH& d1 ) const;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
|
||||
#include "class_netlist_object.h"
|
||||
|
||||
|
||||
#if defined(DEBUG)
|
||||
#include <iostream>
|
||||
const char* ShowType( NetObjetType aType )
|
||||
|
@ -84,10 +83,28 @@ void NETLIST_OBJECT::Show( std::ostream& out, int ndx )
|
|||
if( !m_Label.IsEmpty() )
|
||||
out << " <label>" << m_Label.mb_str() << "</label>\n";
|
||||
|
||||
out << " <sheetpath>" << m_SheetList.PathHumanReadable().mb_str() << "</sheetpath>\n";
|
||||
|
||||
switch( m_Type )
|
||||
{
|
||||
case NET_PIN:
|
||||
out << " <refOfComp>" << ((SCH_COMPONENT*)m_Link)->GetRef(&m_SheetList).mb_str() << "</refOfComp>\n";
|
||||
|
||||
if( m_Comp )
|
||||
m_Comp->Show( 1, out );
|
||||
break;
|
||||
|
||||
default:
|
||||
// not all the m_Comp classes have working Show functions.
|
||||
;
|
||||
}
|
||||
|
||||
/* was segfault-ing
|
||||
if( m_Comp )
|
||||
m_Comp->Show( 1, out ); // labels may not have good Show() funcs?
|
||||
else
|
||||
out << " m_Comp==NULL\n";
|
||||
*/
|
||||
|
||||
out << "</netItem>\n";
|
||||
}
|
||||
|
@ -134,3 +151,4 @@ NETLIST_OBJECT::NETLIST_OBJECT( NETLIST_OBJECT& aSource )
|
|||
NETLIST_OBJECT::~NETLIST_OBJECT()
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
#ifndef _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...) */
|
||||
enum NetObjetType {
|
||||
NET_ITEM_UNSPECIFIED, // only for not yet initialized instances
|
||||
|
@ -105,6 +108,17 @@ public:
|
|||
|
||||
void SetNet( int aNetCode ) { m_NetCode = aNetCode; }
|
||||
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_
|
||||
|
|
|
@ -1485,12 +1485,6 @@ wxString LIB_PIN::ReturnPinStringNum( long aPinNum )
|
|||
}
|
||||
|
||||
|
||||
wxString LIB_PIN::GetNumber( void )
|
||||
{
|
||||
return ReturnPinStringNum( m_PinNum );
|
||||
}
|
||||
|
||||
|
||||
/** Function LIB_PIN::SetPinNumFromString()
|
||||
* fill the buffer with pin num as a wxString
|
||||
* Pin num is coded as a long
|
||||
|
@ -1772,3 +1766,16 @@ const char*** LIB_PIN::GetStyleSymbols()
|
|||
return s_icons_Pins_Shapes;
|
||||
}
|
||||
|
||||
#if defined(DEBUG)
|
||||
|
||||
void LIB_PIN::Show( int nestLevel, std::ostream& os )
|
||||
{
|
||||
NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str()
|
||||
<< " num=\"" << GetNumber().mb_str()
|
||||
<< '"' << "/>\n";
|
||||
|
||||
|
||||
// NestedSpace( nestLevel, os ) << "</" << GetClass().Lower().mb_str() << ">\n";
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#ifndef 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
|
||||
* pins */
|
||||
|
@ -114,6 +115,10 @@ public:
|
|||
return wxT( "LIB_PIN" );
|
||||
}
|
||||
|
||||
#if defined(DEBUG)
|
||||
void Show( int nestLevel, std::ostream& os ); // virtual override
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Write pin object to a FILE in "*.lib" format.
|
||||
|
@ -159,7 +164,12 @@ public:
|
|||
*/
|
||||
void ReturnPinStringNum( wxString& aStringBuffer ) const;
|
||||
|
||||
wxString GetNumber();
|
||||
|
||||
wxString GetNumber()
|
||||
{
|
||||
return ReturnPinStringNum( m_PinNum );
|
||||
}
|
||||
|
||||
|
||||
/** Function ReturnPinStringNum (static function)
|
||||
* Pin num is coded as a long or 4 ascii chars
|
||||
|
|
|
@ -934,7 +934,7 @@ void SCH_COMPONENT::Show( int nestLevel, std::ostream& os )
|
|||
<< '"' << " chipName=\""
|
||||
<< CONV_TO_UTF8( m_ChipName ) << '"' << m_Pos
|
||||
<< " layer=\"" << m_Layer
|
||||
<< '"' << "/>\n";
|
||||
<< '"' << ">\n";
|
||||
|
||||
// skip the reference, it's been output already.
|
||||
for( int i = 1; i < GetFieldCount(); ++i )
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#ifndef CLASSES_BODY_ITEMS_H
|
||||
#define CLASSES_BODY_ITEMS_H
|
||||
|
||||
#include "base_struct.h"
|
||||
|
||||
|
||||
class LIB_COMPONENT;
|
||||
class PLOTTER;
|
||||
|
|
|
@ -48,51 +48,22 @@
|
|||
|
||||
#include "build_version.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
/**
|
||||
* @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
|
||||
* 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
|
||||
* 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.
|
||||
*/
|
||||
class UNIQUE_STRINGS
|
||||
{
|
||||
private:
|
||||
std::set<wxString> m_set; ///< set of wxStrings already found
|
||||
|
||||
public:
|
||||
|
@ -119,8 +90,77 @@ bool UNIQUE_STRINGS::Lookup( const wxString& aString )
|
|||
return ret;
|
||||
}
|
||||
|
||||
/// Used for multi part per package components, avoids using a component more than once.
|
||||
static UNIQUE_STRINGS s_ReferencesAlreadyFound;
|
||||
|
||||
/**
|
||||
* Class EXPORT_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 EXPORT_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 );
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
|
@ -138,6 +178,7 @@ bool WinEDA_SchematicFrame::WriteNetListFile( int aFormat, const wxString& aFull
|
|||
{
|
||||
bool ret = true;
|
||||
FILE* f = NULL;
|
||||
EXPORT_HELP helper;
|
||||
|
||||
if( aFormat < NET_TYPE_CUSTOM1 )
|
||||
{
|
||||
|
@ -154,22 +195,22 @@ bool WinEDA_SchematicFrame::WriteNetListFile( int aFormat, const wxString& aFull
|
|||
switch( aFormat )
|
||||
{
|
||||
case NET_TYPE_PCBNEW:
|
||||
ret = WriteNetListPCBNEW( this, f, TRUE );
|
||||
ret = helper.WriteNetListPCBNEW( this, f, TRUE );
|
||||
fclose( f );
|
||||
break;
|
||||
|
||||
case NET_TYPE_ORCADPCB2:
|
||||
ret = WriteNetListPCBNEW( this, f, FALSE );
|
||||
ret = helper.WriteNetListPCBNEW( this, f, FALSE );
|
||||
fclose( f );
|
||||
break;
|
||||
|
||||
case NET_TYPE_CADSTAR:
|
||||
WriteNetListCADSTAR( this, f );
|
||||
helper.WriteNetListCADSTAR( this, f );
|
||||
fclose( f );
|
||||
break;
|
||||
|
||||
case NET_TYPE_SPICE:
|
||||
WriteNetListPspice( this, f, aUse_netnames );
|
||||
helper.WriteNetListPspice( this, f, aUse_netnames );
|
||||
fclose( f );
|
||||
break;
|
||||
|
||||
|
@ -178,7 +219,7 @@ bool WinEDA_SchematicFrame::WriteNetListFile( int aFormat, const wxString& aFull
|
|||
wxFileName tmpFile = aFullFileName;
|
||||
tmpFile.SetExt( wxT( "tmp" ) );
|
||||
|
||||
ret = Write_GENERIC_NetList( this, tmpFile.GetFullPath() );
|
||||
ret = helper.Write_GENERIC_NetList( this, tmpFile.GetFullPath() );
|
||||
if( !ret )
|
||||
break;
|
||||
|
||||
|
@ -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.
|
||||
* 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
|
||||
/*
|
||||
* Comparison routine for sorting by pin numbers.
|
||||
*/
|
||||
static SCH_COMPONENT* FindNextComponentAndCreatPinList( EDA_BaseStruct* item,
|
||||
SCH_SHEET_PATH* path )
|
||||
static bool sortPinsByNum( NETLIST_OBJECT* Pin1, NETLIST_OBJECT* Pin2 )
|
||||
{
|
||||
s_SortedComponentPinList.clear();
|
||||
// return "lhs < rhs"
|
||||
return RefDesStringCompare( Pin1->GetPinNumText(), Pin2->GetPinNumText() ) < 0;
|
||||
}
|
||||
|
||||
// continue searching from the middle of a linked list
|
||||
for( ; item; item = item->Next() )
|
||||
|
||||
void EXPORT_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 )
|
||||
{
|
||||
if( item->Type() != TYPE_SCH_COMPONENT )
|
||||
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* EXPORT_HELP::findNextComponentAndCreatPinList( EDA_BaseStruct* aItem,
|
||||
SCH_SHEET_PATH* aSheetPath )
|
||||
{
|
||||
wxString ref;
|
||||
|
||||
m_SortedComponentPinList.clear();
|
||||
|
||||
// continue searching from the middle of a linked list (the draw list)
|
||||
for( ; aItem; aItem = aItem->Next() )
|
||||
{
|
||||
if( aItem->Type() != TYPE_SCH_COMPONENT )
|
||||
continue;
|
||||
|
||||
// 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
|
||||
// with "#" are not included in netlist (pseudo or virtual components)
|
||||
wxString ref = comp->GetRef( path );
|
||||
if( ref[0] == wxChar( '#' ) ) // ignore it
|
||||
ref = comp->GetRef( aSheetPath );
|
||||
if( ref[0] == wxChar( '#' ) )
|
||||
continue;
|
||||
|
||||
// if( Component->m_FlagControlMulti == 1 )
|
||||
|
@ -247,22 +333,23 @@ static SCH_COMPONENT* FindNextComponentAndCreatPinList( EDA_BaseStruct* item,
|
|||
if( !entry )
|
||||
continue;
|
||||
|
||||
// If Multi parts per package
|
||||
// If component is a "multi parts per package" type
|
||||
if( entry->GetPartCount() > 1 )
|
||||
{
|
||||
// test if already visited, and if so skip
|
||||
if( s_ReferencesAlreadyFound.Lookup( ref ) )
|
||||
if( m_ReferencesAlreadyFound.Lookup( ref ) )
|
||||
continue;
|
||||
|
||||
// Collect all parts and pins for this first occurance of reference
|
||||
FindAllInstancesOfComponent( comp, entry, path );
|
||||
// Collect all parts and pins for this first occurance of reference.
|
||||
// This is only done once, it would be too expensive otherwise.
|
||||
FindAllInstancesOfComponent( comp, entry, aSheetPath );
|
||||
}
|
||||
|
||||
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++ )
|
||||
{
|
||||
|
@ -270,16 +357,16 @@ static SCH_COMPONENT* FindNextComponentAndCreatPinList( EDA_BaseStruct* item,
|
|||
|
||||
wxASSERT( pin->Type() == COMPONENT_PIN_DRAW_TYPE );
|
||||
|
||||
AddPinToComponentPinList( comp, path, pin );
|
||||
AddPinToComponentPinList( comp, aSheetPath, pin );
|
||||
}
|
||||
}
|
||||
|
||||
// Sort pins in s_SortedComponentPinList by pin number
|
||||
sort( s_SortedComponentPinList.begin(),
|
||||
s_SortedComponentPinList.end(), SortPinsByNum );
|
||||
// Sort pins in m_SortedComponentPinList by pin number
|
||||
sort( m_SortedComponentPinList.begin(),
|
||||
m_SortedComponentPinList.end(), sortPinsByNum );
|
||||
|
||||
// Remove duplicate Pins in s_SortedComponentPinList
|
||||
EraseDuplicatePins( s_SortedComponentPinList );
|
||||
// Remove duplicate Pins in m_SortedComponentPinList
|
||||
EraseDuplicatePins( m_SortedComponentPinList );
|
||||
|
||||
return comp;
|
||||
}
|
||||
|
@ -288,48 +375,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
|
||||
* is a convenience function that creates a new wxXmlNode with an optional textual child.
|
||||
|
@ -353,7 +398,7 @@ static wxXmlNode* Node( const wxString& aName, const wxString& aTextualContent =
|
|||
* creates a generic netlist, now in XML.
|
||||
* @return bool - true if there were no errors, else false.
|
||||
*/
|
||||
bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFileName )
|
||||
bool EXPORT_HELP::Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFileName )
|
||||
{
|
||||
#if 1
|
||||
// output the XML format netlist.
|
||||
|
@ -391,7 +436,7 @@ bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFi
|
|||
const wxString sPart = wxT( "part" );
|
||||
const wxString sNames = wxT( "names" );
|
||||
|
||||
s_ReferencesAlreadyFound.Clear();
|
||||
m_ReferencesAlreadyFound.Clear();
|
||||
|
||||
xdoc.SetRoot( xroot = Node( wxT( "netlist" ) ) );
|
||||
xroot->AddProperty( wxT( "version" ), wxT( "B" ) );
|
||||
|
@ -406,7 +451,7 @@ bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFi
|
|||
{
|
||||
for( EDA_BaseStruct* schItem = path->LastDrawList(); schItem; schItem = schItem->Next() )
|
||||
{
|
||||
SCH_COMPONENT* comp = FindNextComponentAndCreatPinList( schItem, path );
|
||||
SCH_COMPONENT* comp = findNextComponentAndCreatPinList( schItem, path );
|
||||
if( !comp )
|
||||
break; // No component left
|
||||
|
||||
|
@ -497,7 +542,7 @@ bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFi
|
|||
return false;
|
||||
}
|
||||
|
||||
s_ReferencesAlreadyFound.Clear();
|
||||
m_ReferencesAlreadyFound.Clear();
|
||||
|
||||
ret |= fprintf( out, "$BeginNetlist\n" );
|
||||
|
||||
|
@ -510,7 +555,7 @@ bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFi
|
|||
{
|
||||
for( EDA_BaseStruct* schItem = path->LastDrawList(); schItem; schItem = schItem->Next() )
|
||||
{
|
||||
SCH_COMPONENT* comp = FindNextComponentAndCreatPinList( schItem, path );
|
||||
SCH_COMPONENT* comp = findNextComponentAndCreatPinList( schItem, path );
|
||||
if( !comp )
|
||||
break; // No component left
|
||||
|
||||
|
@ -541,9 +586,9 @@ bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFi
|
|||
|
||||
// Write pin list:
|
||||
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 )
|
||||
continue;
|
||||
|
||||
|
@ -586,7 +631,7 @@ bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFi
|
|||
* [.-] Or PSpice gnucap are beginning
|
||||
* + + Gnucap and PSpice are ultimately NetList
|
||||
*/
|
||||
static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f, bool use_netnames )
|
||||
void EXPORT_HELP::WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f, bool use_netnames )
|
||||
{
|
||||
char Line[1024];
|
||||
SCH_SHEET_PATH* sheet;
|
||||
|
@ -596,6 +641,7 @@ static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f, bool use_
|
|||
wxString text;
|
||||
wxArrayString SpiceCommandAtBeginFile, SpiceCommandAtEndFile;
|
||||
wxString msg;
|
||||
wxString netName;
|
||||
|
||||
#define BUFYPOS_LEN 4
|
||||
wxChar bufnum[BUFYPOS_LEN + 1];
|
||||
|
@ -623,12 +669,15 @@ static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f, bool use_
|
|||
wxChar ident;
|
||||
if( DrawList->Type() != TYPE_SCH_TEXT )
|
||||
continue;
|
||||
|
||||
#define DRAWTEXT ( (SCH_TEXT*) DrawList )
|
||||
text = DRAWTEXT->m_Text; if( text.IsEmpty() )
|
||||
continue;
|
||||
|
||||
ident = text.GetChar( 0 );
|
||||
if( ident != '.' && ident != '-' && ident != '+' )
|
||||
continue;
|
||||
|
||||
text.Remove( 0, 1 ); // Remove the first char.
|
||||
text.Remove( 6 ); // text contains 6 char.
|
||||
text.MakeLower();
|
||||
|
@ -673,34 +722,37 @@ static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f, bool use_
|
|||
|
||||
// Create component list
|
||||
|
||||
s_ReferencesAlreadyFound.Clear();
|
||||
m_ReferencesAlreadyFound.Clear();
|
||||
|
||||
for( sheet = SheetList.GetFirst(); sheet != NULL; sheet = SheetList.GetNext() )
|
||||
{
|
||||
for( DrawList = sheet->LastDrawList(); DrawList != NULL; DrawList = DrawList->Next() )
|
||||
{
|
||||
DrawList = Component = FindNextComponentAndCreatPinList( DrawList, sheet );
|
||||
DrawList = Component = findNextComponentAndCreatPinList( DrawList, sheet );
|
||||
if( Component == NULL )
|
||||
break;
|
||||
|
||||
fprintf( f, "%s ", CONV_TO_UTF8( Component->GetRef( sheet ) ) );
|
||||
|
||||
// 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 )
|
||||
continue;
|
||||
wxString NetName = ReturnPinNetName( Pin, wxT( "N-%.6d" ) );
|
||||
if( NetName.IsEmpty() )
|
||||
NetName = wxT( "?" );
|
||||
|
||||
sprintPinNetName( &netName , wxT( "N-%.6d" ), Pin );
|
||||
|
||||
if( netName.IsEmpty() )
|
||||
netName = wxT( "?" );
|
||||
|
||||
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
|
||||
// "GND"
|
||||
{
|
||||
// NetName = "0" is "GND" net for Spice
|
||||
if( NetName == wxT( "0" ) || NetName == wxT( "GND" ) )
|
||||
if( netName == wxT( "0" ) || netName == wxT( "GND" ) )
|
||||
fprintf( f, " 0" );
|
||||
else
|
||||
fprintf( f, " %d", Pin->GetNet() );
|
||||
|
@ -712,7 +764,7 @@ static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f, bool use_
|
|||
}
|
||||
}
|
||||
|
||||
s_SortedComponentPinList.clear();
|
||||
m_SortedComponentPinList.clear();
|
||||
|
||||
/* Print texts starting by [+]pspice , ou [+]gnucap */
|
||||
nbitems = SpiceCommandAtEndFile.GetCount();
|
||||
|
@ -733,18 +785,13 @@ static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f, bool use_
|
|||
}
|
||||
|
||||
|
||||
/* Generate 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
|
||||
*/
|
||||
static bool WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with_pcbnew )
|
||||
bool EXPORT_HELP::WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with_pcbnew )
|
||||
{
|
||||
wxString field;
|
||||
wxString footprint;
|
||||
char dateBuf[256];
|
||||
int ret = 0; // zero now, OR in the sign bit on error
|
||||
wxString netName;
|
||||
|
||||
std::vector<OBJ_CMP_TO_LIST> cmpList;
|
||||
|
||||
|
@ -757,7 +804,7 @@ static bool WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with
|
|||
|
||||
// Create netlist module section
|
||||
|
||||
s_ReferencesAlreadyFound.Clear();
|
||||
m_ReferencesAlreadyFound.Clear();
|
||||
|
||||
SCH_SHEET_LIST sheetList;
|
||||
|
||||
|
@ -765,7 +812,7 @@ static bool WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with
|
|||
{
|
||||
for( EDA_BaseStruct* item = path->LastDrawList(); item; item = item->Next() )
|
||||
{
|
||||
SCH_COMPONENT* comp = FindNextComponentAndCreatPinList( item, path );
|
||||
SCH_COMPONENT* comp = findNextComponentAndCreatPinList( item, path );
|
||||
if( !comp )
|
||||
break;
|
||||
|
||||
|
@ -816,20 +863,20 @@ static bool WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with
|
|||
ret |= fprintf( f, "\n" );
|
||||
|
||||
// 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 )
|
||||
continue;
|
||||
|
||||
wxString netname = ReturnPinNetName( pin, wxT( "N-%.6d" ) );
|
||||
if( netname.IsEmpty() )
|
||||
netname = wxT( "?" );
|
||||
sprintPinNetName( &netName, wxT( "N-%.6d" ), pin );
|
||||
if( netName.IsEmpty() )
|
||||
netName = wxT( "?" );
|
||||
|
||||
netname.Replace( wxT( " " ), wxT( "_" ) );
|
||||
netName.Replace( wxT( " " ), wxT( "_" ) );
|
||||
|
||||
ret |= fprintf( f, " ( %4.4s %s )\n", (char*) &pin->m_PinNum,
|
||||
CONV_TO_UTF8( netname ) );
|
||||
CONV_TO_UTF8( netName ) );
|
||||
}
|
||||
|
||||
ret |= fprintf( f, " )\n" );
|
||||
|
@ -838,7 +885,7 @@ static bool WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with
|
|||
|
||||
ret |= fprintf( f, ")\n*\n" );
|
||||
|
||||
s_SortedComponentPinList.clear();
|
||||
m_SortedComponentPinList.clear();
|
||||
|
||||
// Write the allowed footprint list for each component
|
||||
if( with_pcbnew && cmpList.size() )
|
||||
|
@ -887,34 +934,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
|
||||
* created by BuildNetList() in the table g_NetObjectslist
|
||||
*/
|
||||
static void AddPinToComponentPinList( SCH_COMPONENT* Component,
|
||||
SCH_SHEET_PATH* sheetlist, LIB_PIN* Pin )
|
||||
bool EXPORT_HELP::AddPinToComponentPinList( SCH_COMPONENT* aComponent,
|
||||
SCH_SHEET_PATH* aSheetPath, LIB_PIN* aPin )
|
||||
{
|
||||
// Search the PIN description for Pin in g_NetObjectslist
|
||||
for( unsigned ii = 0; ii < g_NetObjectslist.size(); ii++ )
|
||||
{
|
||||
if( g_NetObjectslist[ii]->m_Type != NET_PIN )
|
||||
continue;
|
||||
if( g_NetObjectslist[ii]->m_Link != Component )
|
||||
continue;
|
||||
if( g_NetObjectslist[ii]->m_SheetList != *sheetlist )
|
||||
continue;
|
||||
if( g_NetObjectslist[ii]->m_PinNum != Pin->m_PinNum )
|
||||
NETLIST_OBJECT* pin = g_NetObjectslist[ii];
|
||||
|
||||
if( pin->m_Type != NET_PIN )
|
||||
continue;
|
||||
|
||||
s_SortedComponentPinList.push_back( g_NetObjectslist[ii] );
|
||||
if( pin->m_Link != aComponent )
|
||||
continue;
|
||||
|
||||
if( s_SortedComponentPinList.size() >= MAXPIN )
|
||||
if( pin->m_PinNum != aPin->m_PinNum )
|
||||
continue;
|
||||
|
||||
// most expensive test at the end.
|
||||
if( pin->m_SheetList != *aSheetPath )
|
||||
continue;
|
||||
|
||||
m_SortedComponentPinList.push_back( pin );
|
||||
|
||||
if( m_SortedComponentPinList.size() >= MAXPIN )
|
||||
{
|
||||
// Log message for Internal error
|
||||
DisplayError( NULL, wxT( "AddPinToComponentPinList err: MAXPIN reached" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
return true; // we're done, we appended.
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -932,7 +988,7 @@ static void AddPinToComponentPinList( SCH_COMPONENT* Component,
|
|||
* given component.
|
||||
* Note: this list *MUST* be sorted by pin number (.m_PinNum member value)
|
||||
*/
|
||||
static void EraseDuplicatePins( NETLIST_OBJECT_LIST& aPinList )
|
||||
void EXPORT_HELP::EraseDuplicatePins( NETLIST_OBJECT_LIST& aPinList )
|
||||
{
|
||||
if( aPinList.size() == 0 ) // Trivial case: component with no pin
|
||||
return;
|
||||
|
@ -959,6 +1015,7 @@ static void EraseDuplicatePins( NETLIST_OBJECT_LIST& aPinList )
|
|||
// other pin num end of duplicate list.
|
||||
if( aPinList[idxref]->m_PinNum != aPinList[jj]->m_PinNum )
|
||||
break;
|
||||
|
||||
if( aPinList[idxref]->m_FlagOfConnection == PAD_CONNECT )
|
||||
aPinList[jj] = NULL;
|
||||
else /* the reference pin is not connected: remove this pin if the
|
||||
|
@ -980,81 +1037,59 @@ static void EraseDuplicatePins( NETLIST_OBJECT_LIST& aPinList )
|
|||
|
||||
/**
|
||||
* Function FindAllInstancesOfComponent
|
||||
* is used for multiple parts per package components.
|
||||
* is used for "multiple parts per package" components.
|
||||
*
|
||||
* Search all instances of Component_in,
|
||||
* Calls AddPinToComponentPinList() to and pins founds to the current
|
||||
* component pin list
|
||||
*/
|
||||
static void FindAllInstancesOfComponent( SCH_COMPONENT* Component_in,
|
||||
void EXPORT_HELP::FindAllInstancesOfComponent( SCH_COMPONENT* aComponent,
|
||||
LIB_COMPONENT* aEntry,
|
||||
SCH_SHEET_PATH* Sheet_in )
|
||||
SCH_SHEET_PATH* aSheetPath )
|
||||
{
|
||||
EDA_BaseStruct* SchItem;
|
||||
SCH_COMPONENT* Component2;
|
||||
LIB_PIN* pin;
|
||||
SCH_SHEET_PATH* sheet;
|
||||
wxString str, Reference = Component_in->GetRef( Sheet_in );
|
||||
wxString ref = aComponent->GetRef( aSheetPath );
|
||||
wxString ref2;
|
||||
|
||||
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;
|
||||
|
||||
Component2 = (SCH_COMPONENT*) SchItem;
|
||||
SCH_COMPONENT* comp2 = (SCH_COMPONENT*) schItem;
|
||||
|
||||
str = Component2->GetRef( sheet );
|
||||
if( str.CmpNoCase( Reference ) != 0 )
|
||||
ref2 = comp2->GetRef( sheet );
|
||||
if( ref2.CmpNoCase( ref ) != 0 )
|
||||
continue;
|
||||
|
||||
if( aEntry == NULL )
|
||||
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 );
|
||||
|
||||
if( pin->m_Unit
|
||||
&& ( pin->m_Unit != Component2->GetUnitSelection( sheet ) ) )
|
||||
if( pin->m_Unit && pin->m_Unit != comp2->GetUnitSelection( aSheetPath ) )
|
||||
continue;
|
||||
|
||||
if( pin->m_Convert
|
||||
&& ( pin->m_Convert != Component2->m_Convert ) )
|
||||
if( pin->m_Convert && pin->m_Convert != comp2->m_Convert )
|
||||
continue;
|
||||
|
||||
// A suitable pin in found: add it to the current list
|
||||
AddPinToComponentPinList( Component2, sheet, pin );
|
||||
// A suitable pin is found: add it to the current list
|
||||
AddPinToComponentPinList( comp2, sheet, pin );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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
|
||||
* connected
|
||||
*/
|
||||
static bool WriteGENERICListOfNetsTxt( FILE* f, NETLIST_OBJECT_LIST& aObjectsList )
|
||||
bool EXPORT_HELP::WriteGENERICListOfNetsTxt( FILE* f, NETLIST_OBJECT_LIST& aObjectsList )
|
||||
{
|
||||
int ret = 0;
|
||||
int netCode;
|
||||
|
@ -1144,7 +1179,7 @@ static bool WriteGENERICListOfNetsTxt( FILE* f, NETLIST_OBJECT_LIST& aObjectsLis
|
|||
* Function WriteGENERICListOfNets
|
||||
* saves a netlist in xml format.
|
||||
*/
|
||||
static bool WriteGENERICListOfNets( wxXmlNode* aNode, NETLIST_OBJECT_LIST& aObjectsList )
|
||||
bool EXPORT_HELP::WriteGENERICListOfNets( wxXmlNode* aNode, NETLIST_OBJECT_LIST& aObjectsList )
|
||||
{
|
||||
wxString netCodeTxt;
|
||||
wxString netName;
|
||||
|
@ -1158,7 +1193,7 @@ static bool WriteGENERICListOfNets( wxXmlNode* aNode, NETLIST_OBJECT_LIST& aObje
|
|||
wxString sNode = wxT( "node" );
|
||||
wxString sFmtd = wxT( "%d" );
|
||||
|
||||
wxXmlNode* xnet;
|
||||
wxXmlNode* xnet = 0;
|
||||
int netCode;
|
||||
int lastNetCode = -1;
|
||||
int sameNetcodeCount = 0;
|
||||
|
@ -1255,7 +1290,7 @@ wxString StartLine( wxT( "." ) );
|
|||
* .. B * T3 1
|
||||
*U1 * 14
|
||||
*/
|
||||
static void WriteNetListCADSTAR( WinEDA_SchematicFrame* frame, FILE* f )
|
||||
void EXPORT_HELP::WriteNetListCADSTAR( WinEDA_SchematicFrame* frame, FILE* f )
|
||||
{
|
||||
wxString StartCmpDesc = StartLine + wxT( "ADD_COM" );
|
||||
wxString msg;
|
||||
|
@ -1274,7 +1309,7 @@ static void WriteNetListCADSTAR( WinEDA_SchematicFrame* frame, FILE* f )
|
|||
fprintf( f, "\n" );
|
||||
|
||||
// Create netlist module section
|
||||
s_ReferencesAlreadyFound.Clear();
|
||||
m_ReferencesAlreadyFound.Clear();
|
||||
|
||||
SCH_SHEET_LIST SheetList;
|
||||
|
||||
|
@ -1282,7 +1317,7 @@ static void WriteNetListCADSTAR( WinEDA_SchematicFrame* frame, FILE* f )
|
|||
{
|
||||
for( DrawList = sheet->LastDrawList(); DrawList != NULL; DrawList = DrawList->Next() )
|
||||
{
|
||||
DrawList = Component = FindNextComponentAndCreatPinList( DrawList, sheet );
|
||||
DrawList = Component = findNextComponentAndCreatPinList( DrawList, sheet );
|
||||
if( Component == NULL )
|
||||
break;
|
||||
|
||||
|
@ -1310,7 +1345,7 @@ static void WriteNetListCADSTAR( WinEDA_SchematicFrame* frame, FILE* f )
|
|||
|
||||
fprintf( f, "\n" );
|
||||
|
||||
s_SortedComponentPinList.clear();
|
||||
m_SortedComponentPinList.clear();
|
||||
|
||||
WriteListOfNetsCADSTAR( f, g_NetObjectslist );
|
||||
|
||||
|
@ -1326,7 +1361,7 @@ static void WriteNetListCADSTAR( WinEDA_SchematicFrame* frame, FILE* f )
|
|||
*. B U1 100
|
||||
* 6 CA
|
||||
*/
|
||||
static void WriteListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjectsList )
|
||||
void EXPORT_HELP::WriteListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjectsList )
|
||||
{
|
||||
wxString InitNetDesc = StartLine + wxT( "ADD_TER" );
|
||||
wxString StartNetDesc = StartLine + wxT( "TER" );
|
||||
|
|
|
@ -273,7 +273,7 @@ void WinEDA_SchematicFrame::BuildNetListBase()
|
|||
sort( g_NetObjectslist.begin(), g_NetObjectslist.end(), SortItemsbyNetcode );
|
||||
|
||||
#if defined(NETLIST_DEBUG) && defined(DEBUG)
|
||||
std::cout << "after qsort()\n";
|
||||
std::cout << "\n\nafter qsort()\n";
|
||||
dumpNetTable();
|
||||
#endif
|
||||
|
||||
|
@ -467,7 +467,6 @@ static void AddConnectedObjects( SCH_SHEET_PATH* sheetlist,
|
|||
NETLIST_OBJECT* new_item;
|
||||
SCH_COMPONENT* DrawLibItem;
|
||||
LIB_COMPONENT* Entry;
|
||||
LIB_PIN* pin;
|
||||
SCH_SHEET_PATH list;
|
||||
|
||||
DrawList = sheetlist->LastScreen()->EEDrawList;
|
||||
|
@ -587,24 +586,20 @@ static void AddConnectedObjects( SCH_SHEET_PATH* sheetlist,
|
|||
case TYPE_SCH_COMPONENT:
|
||||
DrawLibItem = (SCH_COMPONENT*) DrawList;
|
||||
|
||||
Entry =
|
||||
CMP_LIBRARY::FindLibraryComponent( DrawLibItem->m_ChipName );
|
||||
|
||||
Entry = CMP_LIBRARY::FindLibraryComponent( DrawLibItem->m_ChipName );
|
||||
if( Entry == NULL )
|
||||
break;
|
||||
|
||||
for( pin = Entry->GetNextPin(); pin != NULL;
|
||||
pin = Entry->GetNextPin( pin ) )
|
||||
for( LIB_PIN* pin = Entry->GetNextPin(); pin; pin = Entry->GetNextPin( pin ) )
|
||||
{
|
||||
wxASSERT( pin->Type() == COMPONENT_PIN_DRAW_TYPE );
|
||||
|
||||
if( pin->m_Unit
|
||||
&& ( pin->m_Unit !=
|
||||
DrawLibItem->GetUnitSelection( sheetlist ) ) )
|
||||
if( pin->m_Unit &&
|
||||
( pin->m_Unit != DrawLibItem->GetUnitSelection( sheetlist ) ) )
|
||||
continue;
|
||||
|
||||
if( pin->m_Convert
|
||||
&& ( pin->m_Convert != DrawLibItem->m_Convert ) )
|
||||
if( pin->m_Convert &&
|
||||
( pin->m_Convert != DrawLibItem->m_Convert ) )
|
||||
continue;
|
||||
|
||||
wxPoint pos2 =
|
||||
|
@ -640,7 +635,6 @@ static void AddConnectedObjects( SCH_SHEET_PATH* sheetlist,
|
|||
aNetItemBuffer.push_back( new_item );
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case DRAW_POLYLINE_STRUCT_TYPE:
|
||||
|
|
|
@ -382,4 +382,4 @@ void MyFree( void* pt_mem );
|
|||
void* MyZMalloc( 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,
|
|||
*/
|
||||
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 );
|
||||
|
||||
#endif /* __INCLUDE__KICAD_STRING_H__ */
|
||||
/**
|
||||
* 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__
|
||||
|
|
|
@ -16,20 +16,22 @@
|
|||
|
||||
/**
|
||||
* Function GetChars
|
||||
* returns a pointer to the actual character data, either 8 or
|
||||
* 16 bits wide, depending on how the wxWidgets library was compiled.
|
||||
* returns a wxChar* to the actual character data within a wxString, and is
|
||||
* 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 )
|
||||
|
||||
/* 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();
|
||||
#else
|
||||
return s.GetData();
|
||||
|
|
Loading…
Reference in New Issue