Commit a2b3a4cf authored by Dick Hollenbeck's avatar Dick Hollenbeck

more work on generic netlist export

parent 81bcc8d7
...@@ -99,7 +99,7 @@ public: ...@@ -99,7 +99,7 @@ public:
* returns a pointer to the last sheet of the list * returns a pointer to the last sheet of the list
* One can see the others sheet as the "path" to reach this last sheet * One can see the others sheet as the "path" to reach this last sheet
*/ */
SCH_SHEET* Last(); SCH_SHEET* Last();
/** Function LastScreen /** Function LastScreen
* @return the SCH_SCREEN relative to the last sheet in list * @return the SCH_SCREEN relative to the last sheet in list
...@@ -143,11 +143,12 @@ public: ...@@ -143,11 +143,12 @@ public:
*/ */
wxString Path(); wxString Path();
/** Function PathHumanReadable /**
* Return the sheet path in a readable form, i.e. * Function PathHumanReadable
* as a path made from sheet names. * returns the sheet path in a human readable form, i.e. as a path made
* (the "normal" path uses the time stamps which do not changes even when * from sheet names. The the "normal" path instead uses the time
* editing sheet parameters) * stamps in the path. (Time stamps do not change even when editing
* sheet parameters).
*/ */
wxString PathHumanReadable(); wxString PathHumanReadable();
......
...@@ -32,25 +32,25 @@ enum LibrEntryOptions ...@@ -32,25 +32,25 @@ enum LibrEntryOptions
/** /**
* Base class to describe library components and aliases. * Class CMP_LIB_ENTRY
* is a base class to describe library components and aliases.
* *
* This class is not to be used directly. * This class is not to be used directly.
*/ */
class CMP_LIB_ENTRY : public EDA_BaseStruct class CMP_LIB_ENTRY : public EDA_BaseStruct
{ {
protected: protected:
wxString name; wxString name;
/** Library object that entry is attached to. */ /// Library object that entry is attached to.
CMP_LIBRARY* library; CMP_LIBRARY* library;
/** Entry type, either ROOT or ALIAS. */ /// Entry type, either ROOT or ALIAS.
LibrEntryType type; LibrEntryType type;
wxString description; /* documentation for info */ wxString description; ///< documentation for info
wxString keyWords; /* keyword list (used for search for components by keyword) */ wxString keyWords; ///< keyword list (used for search for components by keyword)
wxString docFileName; /* Associate doc file name */ wxString docFileName; ///< Associate doc file name
public: public:
CMP_LIB_ENTRY( LibrEntryType aType, const wxString& aName, CMP_LIBRARY* aLibrary = NULL ); CMP_LIB_ENTRY( LibrEntryType aType, const wxString& aName, CMP_LIBRARY* aLibrary = NULL );
...@@ -65,7 +65,7 @@ public: ...@@ -65,7 +65,7 @@ public:
wxString GetLibraryName(); wxString GetLibraryName();
CMP_LIBRARY* GetLibrary() {return library;} CMP_LIBRARY* GetLibrary() { return library; }
virtual const wxString& GetName() const { return name; } virtual const wxString& GetName() const { return name; }
......
...@@ -51,27 +51,25 @@ extern bool operator<( const CMP_LIBRARY& item1, const CMP_LIBRARY& item2 ); ...@@ -51,27 +51,25 @@ extern bool operator<( const CMP_LIBRARY& item1, const CMP_LIBRARY& item2 );
/** /**
* Component library object. * Class CMP_LIBRARY
* * is used to load, save, search, and otherwise manipulate
* Component libraries are used to load, save, search, and otherwise manipulate
* component library files. * component library files.
*/ */
class CMP_LIBRARY class CMP_LIBRARY
{ {
public: public:
int m_Type; /* type indicator */ int m_Type; ///< type indicator
int m_Flags; int m_Flags;
protected: protected:
wxFileName fileName; /* Library file name. */ wxFileName fileName; ///< Library file name.
wxDateTime timeStamp; /* Library save time and date. */ wxDateTime timeStamp; ///< Library save time and date.
int versionMajor; /* Library major version number. */ int versionMajor; ///< Library major version number.
int versionMinor; /* Library minor version number. */ int versionMinor; ///< Library minor version number.
LIB_ENTRY_LIST entries; /* Parts themselves are saved here. */ LIB_ENTRY_LIST entries; ///< Parts themselves are saved here.
bool isCache; /* False for the "standard" libraries, bool isCache; /**< False for the "standard" libraries,
* True for the library cache */ True for the library cache */
wxString header; /* first line of loaded library. */ wxString header; ///< first line of loaded library.
static CMP_LIBRARY_LIST libraryList; static CMP_LIBRARY_LIST libraryList;
static wxArrayString libraryListSortOrder; static wxArrayString libraryListSortOrder;
...@@ -79,7 +77,7 @@ protected: ...@@ -79,7 +77,7 @@ protected:
friend class CMP_LIB_ENTRY; friend class CMP_LIB_ENTRY;
private: private:
bool isModified; /* Library modification status. */ bool isModified; ///< Library modification status.
public: public:
CMP_LIBRARY( int aType, const wxFileName& aFileName ); CMP_LIBRARY( int aType, const wxFileName& aFileName );
...@@ -96,8 +94,9 @@ public: ...@@ -96,8 +94,9 @@ public:
bool getModifyFlag( ) { return isModified;} bool getModifyFlag( ) { return isModified;}
/** /**
* Save library to file. * Function Save
* * saves library to a file.
* <p>
* Prior to component library version 3.0, two files were created. The * Prior to component library version 3.0, two files were created. The
* component objects are wer as component library (*.lib) files. The * component objects are wer as component library (*.lib) files. The
* library entry ojbect document strings were save in library document * library entry ojbect document strings were save in library document
...@@ -142,8 +141,9 @@ private: ...@@ -142,8 +141,9 @@ private:
bool LoadHeader( FILE* aFile, int* aLineNum ); bool LoadHeader( FILE* aFile, int* aLineNum );
void LoadAliases( LIB_COMPONENT* aComponent ); void LoadAliases( LIB_COMPONENT* aComponent );
/** function RemoveEntryName /**
* Remove an /a aName entry from the library list names. * Function RemoveEntryName
* removes an /a aName entry from the library list names.
* Warning: this is a partiel remove, because if aname is an alias * Warning: this is a partiel remove, because if aname is an alias
* it is not removed from its root component. * it is not removed from its root component.
* this is for internal use only * this is for internal use only
...@@ -164,7 +164,8 @@ public: ...@@ -164,7 +164,8 @@ public:
} }
/** /**
* Get the number of entries in the library. * Function GetCount
* returns the number of entries in the library.
* *
* @return The number of component and alias entries. * @return The number of component and alias entries.
*/ */
...@@ -350,14 +351,25 @@ public: ...@@ -350,14 +351,25 @@ public:
wxString GetName() const { return fileName.GetName(); } wxString GetName() const { return fileName.GetName(); }
/** /**
* Return the full file library name with path and extension. * Function GetFullFileName
* returns the full file library name with path and extension.
* *
* @return Full library file name with path and extension. * @return wxString - Full library file name with path and extension.
*/ */
wxString GetFullFileName() { return fileName.GetFullPath(); } wxString GetFullFileName() { return fileName.GetFullPath(); }
/** /**
* Set the component library file name. * Function GetLogicalName
* returns the logical name of the library, which for now is the filename
* without path or extension.
* wxString - The logical library name.
*/
wxString GetLogicalName() { return fileName.GetName(); }
/**
* Function SetFileName
* sets the component library file name.
* *
* @param aFileName - New library file name. * @param aFileName - New library file name.
*/ */
...@@ -374,16 +386,19 @@ public: ...@@ -374,16 +386,19 @@ public:
* of safety from abusing the library list. * of safety from abusing the library list.
*/ */
/** /**
* Test for an existing library. * Function LibraryExists
* tests for existence of a library.
* *
* @param aLibptr - aLibptr. * @param aLibptr - aLibptr.
* @return true found. false if not found. * @return bool - true if exists, else false
*/ */
static bool LibraryExists( const CMP_LIBRARY* aLibptr ); static bool LibraryExists( const CMP_LIBRARY* aLibptr );
/** /**
* Load a component library file. * Function LoadLibrary
* loads a component library file.
* *
* @param aFileName - File name of the component library to load. * @param aFileName - File name of the component library to load.
* @param aErrorMsg - Error message if the component library failed to load. * @param aErrorMsg - Error message if the component library failed to load.
...@@ -394,7 +409,8 @@ public: ...@@ -394,7 +409,8 @@ public:
wxString& aErrorMsg ); wxString& aErrorMsg );
/** /**
* Add a compnent library to the library list. * Function AddLibrary
* adds a compnent library to the library list.
* *
* @param aFileName - File name object of component library. * @param aFileName - File name object of component library.
* @param aErrorMsg - Error message if the component library failed to load. * @param aErrorMsg - Error message if the component library failed to load.
...@@ -403,7 +419,8 @@ public: ...@@ -403,7 +419,8 @@ public:
static bool AddLibrary( const wxFileName& aFileName, wxString& aErrorMsg ); static bool AddLibrary( const wxFileName& aFileName, wxString& aErrorMsg );
/** /**
* Insert a compnent library to the library list. * Function AddLibrary
* inserts a compnent library into the library list.
* *
* @param aFileName - File name object of component library. * @param aFileName - File name object of component library.
* @param aErrerMsg - Error message if the component library failed to load. * @param aErrerMsg - Error message if the component library failed to load.
...@@ -414,14 +431,16 @@ public: ...@@ -414,14 +431,16 @@ public:
CMP_LIBRARY_LIST::iterator& aIterator ); CMP_LIBRARY_LIST::iterator& aIterator );
/** /**
* Remove component library from the library list. * Function RemoveLibrary
* removes a component library from the library list.
* *
* @param aName - Name of component library to remove. * @param aName - Name of component library to remove.
*/ */
static void RemoveLibrary( const wxString& aName ); static void RemoveLibrary( const wxString& aName );
/** /**
* Find component library by /a aName. * Function FindLibrary
* finds a component library by \a aName.
* *
* @param aName - Library file name without path or extension to find. * @param aName - Library file name without path or extension to find.
* @return Component library if found, otherwise NULL. * @return Component library if found, otherwise NULL.
...@@ -429,7 +448,8 @@ public: ...@@ -429,7 +448,8 @@ public:
static CMP_LIBRARY* FindLibrary( const wxString& aName ); static CMP_LIBRARY* FindLibrary( const wxString& aName );
/** /**
* Get the list of component library file names without path and extension. * Function GetLibraryNames
* returns the list of component library file names without path and extension.
* *
* @param aSorted - Sort the list of name if true. Otherwise use the * @param aSorted - Sort the list of name if true. Otherwise use the
* library load order. * library load order.
...@@ -438,7 +458,8 @@ public: ...@@ -438,7 +458,8 @@ public:
static wxArrayString GetLibraryNames( bool aSorted = true ); static wxArrayString GetLibraryNames( bool aSorted = true );
/** /**
* Search all libraries in the list for a component. * Function FindLibraryComponent
* searches all libraries in the list for a component.
* *
* A component object will always be returned. If the entry found * A component object will always be returned. If the entry found
* is an alias. The root component will be found and returned. * is an alias. The root component will be found and returned.
...@@ -451,7 +472,8 @@ public: ...@@ -451,7 +472,8 @@ public:
const wxString& aLibraryName = wxEmptyString ); const wxString& aLibraryName = wxEmptyString );
/** /**
* Search all libraries in the list for an entry. * Function FindLibraryEntry
* searches all libraries in the list for an entry.
* *
* The object can be either a component or an alias. * The object can be either a component or an alias.
* *
...@@ -463,7 +485,8 @@ public: ...@@ -463,7 +485,8 @@ public:
const wxString& aLibraryName = wxEmptyString ); const wxString& aLibraryName = wxEmptyString );
/** /**
* Remove all cache libraries from library list. * Function RemoveCacheLibrary
* removes all cache libraries from library list.
*/ */
static void RemoveCacheLibrary(); static void RemoveCacheLibrary();
......
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 1992-2009 jean-pierre.charras@gipsa-lab.inpg.fr
* Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 1992-2010 Kicad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/*****************************/ /*****************************/
/* Net list generation code. */ /* Net list generation code. */
/*****************************/ /*****************************/
#include "fctsys.h" #include "fctsys.h"
#include <wx/xml/xml.h> #include <wx/xml/xml.h>
...@@ -39,13 +65,14 @@ static void WriteListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjectsList ) ...@@ -39,13 +65,14 @@ static void WriteListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjectsList )
static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f, static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f,
bool use_netnames ); bool use_netnames );
static bool WriteGENERICListOfNets( FILE* f, NETLIST_OBJECT_LIST& aObjectsList ); static bool WriteGENERICListOfNetsTxt( FILE* f, NETLIST_OBJECT_LIST& aObjectsList );
static bool WriteGENERICListOfNets( wxXmlNode* aNode, NETLIST_OBJECT_LIST& aObjectsList );
static void AddPinToComponentPinList( SCH_COMPONENT* Component, static void AddPinToComponentPinList( SCH_COMPONENT* Component,
SCH_SHEET_PATH* sheet, SCH_SHEET_PATH* sheet,
LIB_PIN* PinEntry ); LIB_PIN* PinEntry );
static void FindAllsInstancesOfComponent( SCH_COMPONENT* Component, static void FindAllInstancesOfComponent( SCH_COMPONENT* Component,
LIB_COMPONENT* aEntry, LIB_COMPONENT* aEntry,
SCH_SHEET_PATH* Sheet_in ); SCH_SHEET_PATH* Sheet_in );
...@@ -220,14 +247,18 @@ static SCH_COMPONENT* FindNextComponentAndCreatPinList( EDA_BaseStruct* item, ...@@ -220,14 +247,18 @@ static SCH_COMPONENT* FindNextComponentAndCreatPinList( EDA_BaseStruct* item,
if( !entry ) if( !entry )
continue; continue;
// Multi parts per package: test if already visited: // If Multi parts per package
if( entry->GetPartCount() > 1 ) if( entry->GetPartCount() > 1 )
{ {
// test if already visited, and if so skip
if( s_ReferencesAlreadyFound.Lookup( ref ) ) if( s_ReferencesAlreadyFound.Lookup( ref ) )
continue; continue;
// Collect all parts and pins for this first occurance of reference
FindAllInstancesOfComponent( comp, entry, path );
} }
if( entry->GetPartCount() <= 1 ) // One part per package else // entry->GetPartCount() <= 1 means one part per package
{ {
LIB_PIN_LIST pins; LIB_PIN_LIST pins;
...@@ -242,9 +273,6 @@ static SCH_COMPONENT* FindNextComponentAndCreatPinList( EDA_BaseStruct* item, ...@@ -242,9 +273,6 @@ static SCH_COMPONENT* FindNextComponentAndCreatPinList( EDA_BaseStruct* item,
AddPinToComponentPinList( comp, path, pin ); AddPinToComponentPinList( comp, path, pin );
} }
} }
else // Multiple parts per package: Collect all parts and pins for
// this reference
FindAllsInstancesOfComponent( comp, entry, path );
// Sort pins in s_SortedComponentPinList by pin number // Sort pins in s_SortedComponentPinList by pin number
sort( s_SortedComponentPinList.begin(), sort( s_SortedComponentPinList.begin(),
...@@ -302,19 +330,28 @@ static wxString ReturnPinNetName( NETLIST_OBJECT* Pin, const wxString& DefaultFo ...@@ -302,19 +330,28 @@ static wxString ReturnPinNetName( NETLIST_OBJECT* Pin, const wxString& DefaultFo
} }
static wxXmlNode* Node( const wxString& name, const wxString& content=wxEmptyString ) /**
* Function Node
* is a convenience function that creates a new wxXmlNode with an optional textual child.
* @param aName is the name to associate with a new node of type wxXML_ELEMENT_NODE.
* @param aContent is optional, and if given is the text to include in a child
* of the returned node, and has type wxXML_TEXT_NODE.
*/
static wxXmlNode* Node( const wxString& aName, const wxString& aTextualContent = wxEmptyString )
{ {
wxXmlNode* n = new wxXmlNode( 0, wxXML_ELEMENT_NODE, name ); wxXmlNode* n = new wxXmlNode( 0, wxXML_ELEMENT_NODE, aName );
if( content.Len() > 0 ) // excludes wxEmptyString if( aTextualContent.Len() > 0 ) // excludes wxEmptyString, the default textual content
n->AddChild( new wxXmlNode( 0, wxXML_TEXT_NODE, wxEmptyString, content ) ); n->AddChild( new wxXmlNode( 0, wxXML_TEXT_NODE, wxEmptyString, aTextualContent ) );
return n; return n;
} }
/* Create a generic netlist, and call an external netlister /**
* to change the netlist syntax and create the file * Function Write_GENERIC_NetList
* 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 Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFileName )
{ {
...@@ -325,30 +362,41 @@ bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFi ...@@ -325,30 +362,41 @@ bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFi
wxXmlNode* xroot; // root node wxXmlNode* xroot; // root node
wxXmlNode* xcomps; // start of components wxXmlNode* xcomps; // start of components
wxString timeStamp;
// some strings we need many times, but don't want to construct more // some strings we need many times, but don't want to construct more
// than once for performance. These are used within loops so the // than once for performance. These are used within loops so the
// enclosing wxString constructor would fire on each usage. // enclosing wxString constructor would fire on each loop iteration if
const wxString sFields = wxT("fields"); // they were in a nested scope.
const wxString sField = wxT("field");
const wxString sComponent = wxT("comp"); // use "part" ? wxString timeStamp;
const wxString sName = wxT("name"); wxString logicalLibName;
const wxString sRef = wxT("ref");
const wxString sPins = wxT("pins"); // these are actually constructor invocations, not assignments as it appears:
const wxString sPin = wxT("pin"); const wxString sFields = wxT( "fields" );
const wxString sValue = wxT("value"); const wxString sField = wxT( "field" );
const wxString sFootprint = wxT("footprint"); const wxString sComponent = wxT( "comp" ); // use "part" ?
const wxString sDatasheet = wxT("datasheet"); const wxString sName = wxT( "name" );
const wxString sTStamp = wxT("tstamp"); const wxString sRef = wxT( "ref" );
const wxString sTSFmt = wxT("%8.8lX"); // comp->m_TimeStamp const wxString sPins = wxT( "pins" );
const wxString sPin = wxT( "pin" );
const wxString sValue = wxT( "value" );
const wxString sSheetPath = wxT( "sheetpath" );
const wxString sFootprint = wxT( "footprint" );
const wxString sDatasheet = wxT( "datasheet" );
const wxString sTStamp = wxT( "tstamp" );
const wxString sTStamps = wxT( "tstamps" );
const wxString sTSFmt = wxT( "%8.8lX" ); // comp->m_TimeStamp
const wxString sLibSource = wxT( "libsource" );
const wxString sLibPart = wxT( "libpart" );
const wxString sLib = wxT( "lib" );
const wxString sPart = wxT( "part" );
const wxString sNames = wxT( "names" );
s_ReferencesAlreadyFound.Clear(); s_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" ) );
xroot->AddChild( xcomps = Node( wxT("components") ) ); xroot->AddChild( xcomps = Node( wxT( "components" ) ) );
SCH_SHEET_LIST sheetList; SCH_SHEET_LIST sheetList;
...@@ -364,16 +412,17 @@ bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFi ...@@ -364,16 +412,17 @@ bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFi
schItem = comp; schItem = comp;
// current component being constructed wxXmlNode* xcomp; // current component being constructed
wxXmlNode* xcomp = Node( sComponent );
xcomps->AddChild( xcomp );
xcomp->AddProperty( sRef, comp->GetRef( path ) );
xcomp->AddChild( Node( sValue, comp->GetField( VALUE )->m_Text ) ); // Output the component's elments in order of expected access frequency.
// This may not always look best, but it will allow faster execution
// under XSL processing systems which do sequential searching within
// an element.
timeStamp.Printf( sTSFmt, comp->m_TimeStamp ); xcomps->AddChild( xcomp = Node( sComponent ) );
xcomp->AddProperty( sRef, comp->GetRef( path ) );
xcomp->AddChild( Node( sTStamp, timeStamp ) ); xcomp->AddChild( Node( sValue, comp->GetField( VALUE )->m_Text ) );
if( !comp->GetField( FOOTPRINT )->m_Text.IsEmpty() ) if( !comp->GetField( FOOTPRINT )->m_Text.IsEmpty() )
xcomp->AddChild( Node( sFootprint, comp->GetField( FOOTPRINT )->m_Text ) ); xcomp->AddChild( Node( sFootprint, comp->GetField( FOOTPRINT )->m_Text ) );
...@@ -381,37 +430,60 @@ bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFi ...@@ -381,37 +430,60 @@ bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFi
if( !comp->GetField( DATASHEET )->m_Text.IsEmpty() ) if( !comp->GetField( DATASHEET )->m_Text.IsEmpty() )
xcomp->AddChild( Node( sDatasheet, comp->GetField( DATASHEET )->m_Text ) ); xcomp->AddChild( Node( sDatasheet, comp->GetField( DATASHEET )->m_Text ) );
// all fields within the component, starting with the MANDATORY_FIELDS // Export all user defined fields within the component,
// which start at field index MANDATORY_FIELDS. Only output the <fields>
// container element if there are any <field>s.
if( comp->GetFieldCount() > MANDATORY_FIELDS ) if( comp->GetFieldCount() > MANDATORY_FIELDS )
{ {
wxXmlNode* xfields = Node( sFields ); wxXmlNode* xfields;
xcomp->AddChild( xfields ); xcomp->AddChild( xfields = Node( sFields ) );
for( int fldNdx = MANDATORY_FIELDS; fldNdx < comp->GetFieldCount(); ++fldNdx ) for( int fldNdx = MANDATORY_FIELDS; fldNdx < comp->GetFieldCount(); ++fldNdx )
{ {
SCH_FIELD* f = comp->GetField( fldNdx ); SCH_FIELD* f = comp->GetField( fldNdx );
wxXmlNode* xfield = Node( sField, f->m_Text );
xfield->AddProperty( sName, f->m_Name ); // only output a field if non empty
xfields->AddChild( xfield ); if( !f->m_Text.IsEmpty() )
{
wxXmlNode* xfield;
xfields->AddChild( xfield = Node( sField, f->m_Text ) );
xfield->AddProperty( sName, f->m_Name );
}
} }
} }
// @todo add: libsource + sheetpath wxXmlNode* xlibsource;
xcomp->AddChild( xlibsource = Node( sLibSource ) );
// "logical" library name, which is in anticipation of a better search
// algorithm for parts based on "logical_lib.part" and where logical_lib
// is merely the library name minus path and extension.
LIB_COMPONENT* entry = CMP_LIBRARY::FindLibraryComponent( comp->m_ChipName );
if( entry )
xlibsource->AddProperty( sLib, entry->GetLibrary()->GetLogicalName() );
xlibsource->AddProperty( sPart, comp->m_ChipName );
wxXmlNode* xsheetpath;
xcomp->AddChild( xsheetpath = Node( sSheetPath ) );
xsheetpath->AddProperty( sTStamps, path->Path() );
xsheetpath->AddProperty( sNames, path->PathHumanReadable() );
timeStamp.Printf( sTSFmt, comp->m_TimeStamp );
xcomp->AddChild( Node( sTStamp, timeStamp ) );
} }
} }
// @todo generate the nested <libpart> s // @todo generate the nested <libpart> s
xroot->AddChild( Node( wxT("libparts") ) ); xroot->AddChild( Node( wxT( "libparts" ) ) );
// @todo generate the nested <net>s wxXmlNode* xnets;
xroot->AddChild( Node( wxT("nets") ) ); xroot->AddChild( xnets = Node( wxT( "nets" ) ) );
WriteGENERICListOfNets( xnets, g_NetObjectslist );
return xdoc.Save( aOutFileName, 2 /* indent bug, today was ignored by wxXml lib */ ); return xdoc.Save( aOutFileName, 2 /* indent bug, today was ignored by wxXml lib */ );
#else #else // ouput the well established/old net list format which was not XML.
// ouput the well established/old net list format
wxString field; wxString field;
wxString footprint; wxString footprint;
wxString netname; wxString netname;
...@@ -491,7 +563,7 @@ bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFi ...@@ -491,7 +563,7 @@ bool Write_GENERIC_NetList( WinEDA_SchematicFrame* frame, const wxString& aOutFi
ret |= fprintf( out, "\n$BeginNets\n" ); ret |= fprintf( out, "\n$BeginNets\n" );
if( !WriteGENERICListOfNets( out, g_NetObjectslist ) ) if( !WriteGENERICListOfNetsTxt( out, g_NetObjectslist ) )
ret = -1; ret = -1;
ret |= fprintf( out, "$EndNets\n" ); ret |= fprintf( out, "$EndNets\n" );
...@@ -669,7 +741,7 @@ static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f, bool use_ ...@@ -669,7 +741,7 @@ static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f, bool use_
*/ */
static bool WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with_pcbnew ) static bool WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with_pcbnew )
{ {
wxString Line; 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
...@@ -723,23 +795,23 @@ static bool WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with ...@@ -723,23 +795,23 @@ static bool WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with
else else
footprint = wxT( "$noname" ); footprint = wxT( "$noname" );
Line = comp->GetRef( path ); field = comp->GetRef( path );
ret |= fprintf( f, " ( %s %s", ret |= fprintf( f, " ( %s %s",
CONV_TO_UTF8( comp->GetPath( path ) ), CONV_TO_UTF8( comp->GetPath( path ) ),
CONV_TO_UTF8( footprint ) ); CONV_TO_UTF8( footprint ) );
ret |= fprintf( f, " %s", CONV_TO_UTF8( Line ) ); ret |= fprintf( f, " %s", CONV_TO_UTF8( field ) );
Line = comp->GetField( VALUE )->m_Text; field = comp->GetField( VALUE )->m_Text;
Line.Replace( wxT( " " ), wxT( "_" ) ); field.Replace( wxT( " " ), wxT( "_" ) );
ret |= fprintf( f, " %s", CONV_TO_UTF8( Line ) ); ret |= fprintf( f, " %s", CONV_TO_UTF8( field ) );
if( with_pcbnew ) // Add the lib name for this component if( with_pcbnew ) // Add the lib name for this component
{ {
Line = comp->m_ChipName; field = comp->m_ChipName;
Line.Replace( wxT( " " ), wxT( "_" ) ); field.Replace( wxT( " " ), wxT( "_" ) );
ret |= fprintf( f, " {Lib=%s}", CONV_TO_UTF8( Line ) ); ret |= fprintf( f, " {Lib=%s}", CONV_TO_UTF8( field ) );
} }
ret |= fprintf( f, "\n" ); ret |= fprintf( f, "\n" );
...@@ -803,7 +875,7 @@ static bool WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with ...@@ -803,7 +875,7 @@ static bool WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with
{ {
ret |= fprintf( f, "{ Pin List by Nets\n" ); ret |= fprintf( f, "{ Pin List by Nets\n" );
if( !WriteGENERICListOfNets( f, g_NetObjectslist ) ) if( !WriteGENERICListOfNetsTxt( f, g_NetObjectslist ) )
ret = -1; ret = -1;
ret |= fprintf( f, "}\n" ); ret |= fprintf( f, "}\n" );
...@@ -907,13 +979,14 @@ static void EraseDuplicatePins( NETLIST_OBJECT_LIST& aPinList ) ...@@ -907,13 +979,14 @@ static void EraseDuplicatePins( NETLIST_OBJECT_LIST& aPinList )
/** /**
* Used for multiple parts per package components. * Function FindAllInstancesOfComponent
* 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 FindAllsInstancesOfComponent( SCH_COMPONENT* Component_in, static void FindAllInstancesOfComponent( SCH_COMPONENT* Component_in,
LIB_COMPONENT* aEntry, LIB_COMPONENT* aEntry,
SCH_SHEET_PATH* Sheet_in ) SCH_SHEET_PATH* Sheet_in )
{ {
...@@ -981,7 +1054,7 @@ static bool SortPinsByNum( NETLIST_OBJECT* Pin1, NETLIST_OBJECT* Pin2 ) ...@@ -981,7 +1054,7 @@ static bool SortPinsByNum( NETLIST_OBJECT* Pin1, NETLIST_OBJECT* Pin2 )
/* 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 WriteGENERICListOfNets( FILE* f, NETLIST_OBJECT_LIST& aObjectsList ) static bool WriteGENERICListOfNetsTxt( FILE* f, NETLIST_OBJECT_LIST& aObjectsList )
{ {
int ret = 0; int ret = 0;
int netCode; int netCode;
...@@ -1067,6 +1140,91 @@ static bool WriteGENERICListOfNets( FILE* f, NETLIST_OBJECT_LIST& aObjectsList ) ...@@ -1067,6 +1140,91 @@ static bool WriteGENERICListOfNets( FILE* f, NETLIST_OBJECT_LIST& aObjectsList )
} }
/**
* Function WriteGENERICListOfNets
* saves a netlist in xml format.
*/
static bool WriteGENERICListOfNets( wxXmlNode* aNode, NETLIST_OBJECT_LIST& aObjectsList )
{
wxString netCodeTxt;
wxString netName;
wxString ref;
wxString sNet = wxT( "net" );
wxString sName = wxT( "name" );
wxString sCode = wxT( "code" );
wxString sRef = wxT( "ref" );
wxString sPin = wxT( "pin" );
wxString sNode = wxT( "node" );
wxString sFmtd = wxT( "%d" );
wxXmlNode* xnet;
int netCode;
int lastNetCode = -1;
int sameNetcodeCount = 0;
/* output:
<net code="123" name="/cfcard.sch/WAIT#">
<node ref="R23" pin="1"/>
<node ref="U18" pin="12"/>
</net>
*/
for( unsigned ii = 0; ii < aObjectsList.size(); ii++ )
{
SCH_COMPONENT* comp;
// New net found, write net id;
if( ( netCode = aObjectsList[ii]->GetNet() ) != lastNetCode )
{
sameNetcodeCount = 0; // item count for this net
netName.Empty();
// Find a label for this net, if it exists.
NETLIST_OBJECT* netref = aObjectsList[ii]->m_NetNameCandidate;
if( netref )
{
if( netref->m_Type != NET_PINLABEL && netref->m_Type != NET_GLOBLABEL )
{
// usual net name, prefix it by the sheet path
netName = netref->m_SheetList.PathHumanReadable();
}
netName += netref->m_Label;
}
lastNetCode = netCode;
}
if( aObjectsList[ii]->m_Type != NET_PIN )
continue;
comp = (SCH_COMPONENT*) aObjectsList[ii]->m_Link;
// Get the reference for the net name and the main parent component
ref = comp->GetRef( &aObjectsList[ii]->m_SheetList );
if( ref[0] == wxChar( '#' ) )
continue;
if( ++sameNetcodeCount == 1 )
{
aNode->AddChild( xnet = Node( sNet ) );
netCodeTxt.Printf( sFmtd, netCode );
xnet->AddProperty( sCode, netCodeTxt );
xnet->AddProperty( sName, netName );
}
wxXmlNode* xnode;
xnet->AddChild( xnode = Node( sNode ) );
xnode->AddProperty( sRef, ref );
xnode->AddProperty( sPin, LIB_PIN::ReturnPinStringNum( aObjectsList[ii]->m_PinNum ) );
}
return true;
}
/* Generate CADSTAR net list. */ /* Generate CADSTAR net list. */
wxString StartLine( wxT( "." ) ); wxString StartLine( wxT( "." ) );
......
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