KiCad PCB EDA Suite
NETLIST_EXPORTER_KICAD Class Reference

Class NETLIST_EXPORTER_KICAD generates the kicad netlist format supported by pcbnew. More...

#include <netlist_exporter_kicad.h>

Inheritance diagram for NETLIST_EXPORTER_KICAD:
NETLIST_EXPORTER_GENERIC NETLIST_EXPORTER

Public Member Functions

 NETLIST_EXPORTER_KICAD (SCH_EDIT_FRAME *aFrame, NETLIST_OBJECT_LIST *aMasterList, CONNECTION_GRAPH *aGraph=nullptr)
 
bool WriteNetlist (const wxString &aOutFileName, unsigned aNetlistOptions) override
 Function WriteNetlist writes to specified output file. More...
 
void Format (OUTPUTFORMATTER *aOutputFormatter, int aCtl)
 Function Format outputs this s-expression netlist into aOutputFormatter. More...
 

Static Public Member Functions

static wxString MakeCommandLine (const wxString &aFormatString, const wxString &aNetlistFile, const wxString &aFinalFile, const wxString &aProjectDirectory)
 Function MakeCommandLine builds up a string that describes a command line for executing a child process. More...
 

Protected Member Functions

XNODEnode (const wxString &aName, const wxString &aTextualContent=wxEmptyString)
 Function node is a convenience function that creates a new XNODE with an optional textual child. More...
 
XNODEmakeRoot (int aCtl=GNL_ALL)
 Function makeGenericRoot builds the entire document tree for the generic export. More...
 
XNODEmakeComponents ()
 Function makeComponents. More...
 
XNODEmakeDesignHeader ()
 Function makeDesignHeader fills out a project "design" header into an XML node. More...
 
XNODEmakeLibParts ()
 Function makeLibParts fills out an XML node with the unique library parts and returns it. More...
 
XNODEmakeListOfNets (bool aUseGraph=true)
 Function makeListOfNets fills out an XML node with a list of nets and returns it. More...
 
XNODEmakeLibraries ()
 Function makeLibraries fills out an XML node with a list of used libraries and returns it. More...
 
void addComponentFields (XNODE *xcomp, SCH_COMPONENT *comp, SCH_SHEET_PATH *aSheet)
 
SCH_COMPONENTfindNextComponentAndCreatePinList (EDA_ITEM *aItem, SCH_SHEET_PATH *aSheetPath)
 Function findNextComponentAndCreatePinList finds a component from the DrawList and builds its pin list in m_SortedComponentPinList. More...
 
SCH_COMPONENTfindNextComponent (EDA_ITEM *aItem, SCH_SHEET_PATH *aSheetPath)
 
void eraseDuplicatePins ()
 Function eraseDuplicatePins erase duplicate Pins from m_SortedComponentPinList (i.e. More...
 
bool addPinToComponentPinList (SCH_COMPONENT *Component, SCH_SHEET_PATH *sheet, LIB_PIN *PinEntry)
 Function addPinToComponentPinList adds a new pin description to the pin list m_SortedComponentPinList. More...
 
void findAllUnitsOfComponent (SCH_COMPONENT *aComponent, LIB_PART *aEntry, SCH_SHEET_PATH *aSheetPath)
 Function findAllUnitsOfComponent is used for "multiple parts per package" components. More...
 

Static Protected Member Functions

static void sprintPinNetName (wxString &aResult, const wxString &aNetNameFormat, NETLIST_OBJECT *aPin, bool aUseNetcodeAsNetName=false)
 Function sprintPinNetName formats the net name for aPin using aNetNameFormat into aResult. More...
 

Protected Attributes

CONNECTION_GRAPHm_graph
 
NETLIST_OBJECT_LISTm_masterList
 
NETLIST_OBJECTS m_SortedComponentPinList
 yes ownership, connected items flat list More...
 
UNIQUE_STRINGS m_ReferencesAlreadyFound
 Used for "multi parts per package" components, avoids processing a lib component more than once. More...
 
std::set< LIB_PART *, LIB_PART_LESS_THANm_LibParts
 unique library parts used. LIB_PART items are sorted by names More...
 

Detailed Description

Class NETLIST_EXPORTER_KICAD generates the kicad netlist format supported by pcbnew.

It is basically the generic netlist format just formatted slightly different.

Definition at line 38 of file netlist_exporter_kicad.h.

Constructor & Destructor Documentation

◆ NETLIST_EXPORTER_KICAD()

NETLIST_EXPORTER_KICAD::NETLIST_EXPORTER_KICAD ( SCH_EDIT_FRAME aFrame,
NETLIST_OBJECT_LIST aMasterList,
CONNECTION_GRAPH aGraph = nullptr 
)
inline

Definition at line 41 of file netlist_exporter_kicad.h.

43  :
44  NETLIST_EXPORTER_GENERIC( aFrame, aMasterList, aGraph )
45  {}
NETLIST_EXPORTER_GENERIC(SCH_EDIT_FRAME *aFrame, NETLIST_OBJECT_LIST *aMasterList, CONNECTION_GRAPH *aGraph=nullptr)

Member Function Documentation

◆ addComponentFields()

void NETLIST_EXPORTER_GENERIC::addComponentFields ( XNODE xcomp,
SCH_COMPONENT comp,
SCH_SHEET_PATH aSheet 
)
protectedinherited

Definition at line 94 of file netlist_exporter_generic.cpp.

95 {
96  COMP_FIELDS fields;
97 
98  if( comp->GetUnitCount() > 1 )
99  {
100  // Sadly, each unit of a component can have its own unique fields. This
101  // block finds the unit with the lowest number having a non blank field
102  // value and records it. Therefore user is best off setting fields
103  // into only the first unit. But this scavenger algorithm will find
104  // any non blank fields in all units and use the first non-blank field
105  // for each unique field name.
106 
107  wxString ref = comp->GetRef( aSheet );
108 
109  SCH_SHEET_LIST sheetList( g_RootSheet );
110  int minUnit = comp->GetUnit();
111 
112  for( unsigned i = 0; i < sheetList.size(); i++ )
113  {
114  for( EDA_ITEM* item = sheetList[i].LastDrawList(); item; item = item->Next() )
115  {
116  if( item->Type() != SCH_COMPONENT_T )
117  continue;
118 
119  SCH_COMPONENT* comp2 = (SCH_COMPONENT*) item;
120 
121  wxString ref2 = comp2->GetRef( &sheetList[i] );
122 
123  if( ref2.CmpNoCase( ref ) != 0 )
124  continue;
125 
126  int unit = comp2->GetUnit();
127 
128  // The lowest unit number wins. User should only set fields in any one unit.
129  // remark: IsVoid() returns true for empty strings or the "~" string (empty field value)
130  if( !comp2->GetField( VALUE )->IsVoid()
131  && ( unit < minUnit || fields.value.IsEmpty() ) )
132  fields.value = comp2->GetField( VALUE )->GetText();
133 
134  if( !comp2->GetField( FOOTPRINT )->IsVoid()
135  && ( unit < minUnit || fields.footprint.IsEmpty() ) )
136  fields.footprint = comp2->GetField( FOOTPRINT )->GetText();
137 
138  if( !comp2->GetField( DATASHEET )->IsVoid()
139  && ( unit < minUnit || fields.datasheet.IsEmpty() ) )
140  fields.datasheet = comp2->GetField( DATASHEET )->GetText();
141 
142  for( int fldNdx = MANDATORY_FIELDS; fldNdx < comp2->GetFieldCount(); ++fldNdx )
143  {
144  SCH_FIELD* f = comp2->GetField( fldNdx );
145 
146  if( f->GetText().size()
147  && ( unit < minUnit || fields.f.count( f->GetName() ) == 0 ) )
148  {
149  fields.f[ f->GetName() ] = f->GetText();
150  }
151  }
152 
153  minUnit = std::min( unit, minUnit );
154  }
155  }
156 
157  }
158  else
159  {
160  fields.value = comp->GetField( VALUE )->GetText();
161  fields.footprint = comp->GetField( FOOTPRINT )->GetText();
162  fields.datasheet = comp->GetField( DATASHEET )->GetText();
163 
164  for( int fldNdx = MANDATORY_FIELDS; fldNdx < comp->GetFieldCount(); ++fldNdx )
165  {
166  SCH_FIELD* f = comp->GetField( fldNdx );
167 
168  if( f->GetText().size() )
169  fields.f[ f->GetName() ] = f->GetText();
170  }
171  }
172 
173  // Do not output field values blank in netlist:
174  if( fields.value.size() )
175  xcomp->AddChild( node( "value", fields.value ) );
176  else // value field always written in netlist
177  xcomp->AddChild( node( "value", "~" ) );
178 
179  if( fields.footprint.size() )
180  xcomp->AddChild( node( "footprint", fields.footprint ) );
181 
182  if( fields.datasheet.size() )
183  xcomp->AddChild( node( "datasheet", fields.datasheet ) );
184 
185  if( fields.f.size() )
186  {
187  XNODE* xfields;
188  xcomp->AddChild( xfields = node( "fields" ) );
189 
190  // non MANDATORY fields are output alphabetically
191  for( std::map< wxString, wxString >::const_iterator it = fields.f.begin();
192  it != fields.f.end(); ++it )
193  {
194  XNODE* xfield;
195  xfields->AddChild( xfield = node( "field", it->second ) );
196  xfield->AddAttribute( "name", it->first );
197  }
198  }
199 
200 }
Class SCH_SHEET_LIST.
Class SCH_FIELD instances are attached to a component and provide a place for the component's value,...
Definition: sch_field.h:52
name of datasheet
XNODE * node(const wxString &aName, const wxString &aTextualContent=wxEmptyString)
Function node is a convenience function that creates a new XNODE with an optional textual child.
The first 4 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors.
int GetUnitCount() const
Return the number of units per package of the symbol.
Field Name Module PCB, i.e. "16DIP300".
bool IsVoid() const
Function IsVoid returns true if the field is either empty or holds "~".
Definition: sch_field.cpp:257
EDA_ITEM * Next() const
Definition: base_struct.h:218
SCH_FIELD * GetField(int aFieldNdx) const
Returns a field in this symbol.
#define VALUE
int GetUnit() const
SCH_SHEET * g_RootSheet
Definition: eeschema.cpp:47
Holder for multi-unit component fields.
const wxString GetRef(const SCH_SHEET_PATH *aSheet)
Return the reference for the given sheet path.
int GetFieldCount() const
Return the number of fields in this symbol.
Class XNODE holds an XML or S-expression element.
Definition: xnode.h:43
wxString GetName(bool aUseDefaultName=true) const
Function GetName returns the field name.
Definition: sch_field.cpp:370
size_t i
Definition: json11.cpp:597
Class SCH_COMPONENT describes a real schematic component.
Definition: sch_component.h:73
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:163
std::map< wxString, wxString > f
virtual const wxString & GetText() const
Function GetText returns the string associated with the text object.
Definition: eda_text.h:124
#define min(a, b)
Definition: auxiliary.h:85

References DATASHEET, COMP_FIELDS::datasheet, COMP_FIELDS::f, FOOTPRINT, COMP_FIELDS::footprint, g_RootSheet, SCH_COMPONENT::GetField(), SCH_COMPONENT::GetFieldCount(), SCH_FIELD::GetName(), SCH_COMPONENT::GetRef(), EDA_TEXT::GetText(), SCH_COMPONENT::GetUnit(), SCH_COMPONENT::GetUnitCount(), i, SCH_FIELD::IsVoid(), MANDATORY_FIELDS, min, NETLIST_EXPORTER_GENERIC::node(), SCH_COMPONENT_T, VALUE, and COMP_FIELDS::value.

Referenced by NETLIST_EXPORTER_GENERIC::makeComponents().

◆ addPinToComponentPinList()

bool NETLIST_EXPORTER::addPinToComponentPinList ( SCH_COMPONENT Component,
SCH_SHEET_PATH sheet,
LIB_PIN PinEntry 
)
protectedinherited

Function addPinToComponentPinList adds a new pin description to the pin list m_SortedComponentPinList.

A pin description is a pointer to the corresponding structure created by BuildNetList() in the table g_NetObjectslist.

Definition at line 238 of file netlist_exporter.cpp.

240 {
241  // Search the PIN description for Pin in g_NetObjectslist
242  for( unsigned ii = 0; ii < m_masterList->size(); ii++ )
243  {
244  NETLIST_OBJECT* pin = m_masterList->GetItem( ii );
245 
246  if( pin->m_Type != NET_PIN )
247  continue;
248 
249  if( pin->m_Link != aComponent )
250  continue;
251 
252  if( pin->m_PinNum != aPin->GetNumber() )
253  continue;
254 
255  // most expensive test at the end.
256  if( pin->m_SheetPath != *aSheetPath )
257  continue;
258 
259  m_SortedComponentPinList.push_back( pin );
260 
261  if( m_SortedComponentPinList.size() >= MAXPIN )
262  {
263  // Log message for Internal error
264  DisplayError( NULL, wxT( "addPinToComponentPinList err: MAXPIN reached" ) );
265  }
266 
267  return true; // we're done, we appended.
268  }
269 
270  return false;
271 }
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:236
#define MAXPIN
Definition: netlist.h:53
SCH_SHEET_PATH m_SheetPath
NETLIST_ITEM_T m_Type
NETLIST_OBJECT_LIST * m_masterList
NETLIST_OBJECTS m_SortedComponentPinList
yes ownership, connected items flat list
NETLIST_OBJECT * GetItem(unsigned aIdx) const
Acces to an item in list.
SCH_ITEM * m_Link

References DisplayError(), NETLIST_OBJECT_LIST::GetItem(), LIB_PIN::GetNumber(), NETLIST_OBJECT::m_Link, NETLIST_EXPORTER::m_masterList, NETLIST_OBJECT::m_PinNum, NETLIST_OBJECT::m_SheetPath, NETLIST_EXPORTER::m_SortedComponentPinList, NETLIST_OBJECT::m_Type, MAXPIN, and NET_PIN.

Referenced by NETLIST_EXPORTER::findAllUnitsOfComponent(), and NETLIST_EXPORTER::findNextComponentAndCreatePinList().

◆ eraseDuplicatePins()

void NETLIST_EXPORTER::eraseDuplicatePins ( )
protectedinherited

Function eraseDuplicatePins erase duplicate Pins from m_SortedComponentPinList (i.e.

set pointer in this list to NULL). (This is a list of pins found in the whole schematic, for a single component.) These duplicate pins were put in list because some pins (powers... ) are found more than one time when we have a multiple parts per package component. For instance, a 74ls00 has 4 parts, and therefore the VCC pin and GND pin appears 4 times in the list. Note: this list MUST be sorted by pin number (.m_PinNum member value) Also set the m_Flag member of "removed" NETLIST_OBJECT pin item to 1

Definition at line 274 of file netlist_exporter.cpp.

275 {
276  for( unsigned ii = 0; ii < m_SortedComponentPinList.size(); ii++ )
277  {
278  if( m_SortedComponentPinList[ii] == NULL ) /* already deleted */
279  continue;
280 
281  /* Search for duplicated pins
282  * If found, remove duplicates. The priority is to keep connected pins
283  * and remove unconnected
284  * - So this allows (for instance when using multi op amps per package
285  * - to connect only one op amp to power
286  * Because the pin list is sorted by m_PinNum value, duplicated pins
287  * are necessary successive in list
288  */
289  int idxref = ii;
290  for( unsigned jj = ii + 1; jj < m_SortedComponentPinList.size(); jj++ )
291  {
292  if( m_SortedComponentPinList[jj] == NULL ) // Already removed
293  continue;
294 
295  // if other pin num, stop search,
296  // because all pins having the same number are consecutive in list.
297  if( m_SortedComponentPinList[idxref]->m_PinNum != m_SortedComponentPinList[jj]->m_PinNum )
298  break;
299 
300  if( m_SortedComponentPinList[idxref]->GetConnectionType() == PAD_CONNECT )
301  {
302  m_SortedComponentPinList[jj]->m_Flag = 1;
303  m_SortedComponentPinList[jj] = NULL;
304  }
305  else /* the reference pin is not connected: remove this pin if the
306  * other pin is connected */
307  {
308  if( m_SortedComponentPinList[jj]->GetConnectionType() == PAD_CONNECT )
309  {
310  m_SortedComponentPinList[idxref]->m_Flag = 1;
311  m_SortedComponentPinList[idxref] = NULL;
312  idxref = jj;
313  }
314  else // the 2 pins are not connected: remove the tested pin,
315  { // and continue ...
316  m_SortedComponentPinList[jj]->m_Flag = 1;
317  m_SortedComponentPinList[jj] = NULL;
318  }
319  }
320  }
321  }
322 }
NETLIST_OBJECTS m_SortedComponentPinList
yes ownership, connected items flat list

References NETLIST_EXPORTER::m_SortedComponentPinList, and PAD_CONNECT.

Referenced by NETLIST_EXPORTER::findNextComponentAndCreatePinList().

◆ findAllUnitsOfComponent()

void NETLIST_EXPORTER::findAllUnitsOfComponent ( SCH_COMPONENT aComponent,
LIB_PART aEntry,
SCH_SHEET_PATH aSheetPath 
)
protectedinherited

Function findAllUnitsOfComponent is used for "multiple parts per package" components.

Search the entire design for all units of aComponent based on matching reference designator, and for each unit, add all its pins to the temporary sorted pin list, m_SortedComponentPinList.

Definition at line 325 of file netlist_exporter.cpp.

327 {
328  wxString ref = aComponent->GetRef( aSheetPath );
329  wxString ref2;
330 
331  SCH_SHEET_LIST sheetList( g_RootSheet );
332 
333  for( unsigned i = 0; i < sheetList.size(); i++ )
334  {
335  for( EDA_ITEM* item = sheetList[i].LastDrawList(); item; item = item->Next() )
336  {
337  if( item->Type() != SCH_COMPONENT_T )
338  continue;
339 
340  SCH_COMPONENT* comp2 = (SCH_COMPONENT*) item;
341 
342  ref2 = comp2->GetRef( &sheetList[i] );
343 
344  if( ref2.CmpNoCase( ref ) != 0 )
345  continue;
346 
347  int unit2 = comp2->GetUnitSelection( &sheetList[i] ); // slow
348 
349  for( LIB_PIN* pin = aEntry->GetNextPin(); pin; pin = aEntry->GetNextPin( pin ) )
350  {
351  wxASSERT( pin->Type() == LIB_PIN_T );
352 
353  if( pin->GetUnit() && pin->GetUnit() != unit2 )
354  continue;
355 
356  if( pin->GetConvert() && pin->GetConvert() != comp2->GetConvert() )
357  continue;
358 
359  // A suitable pin is found: add it to the current list
360  addPinToComponentPinList( comp2, &sheetList[i], pin );
361  }
362  }
363  }
364 }
Class SCH_SHEET_LIST.
int GetUnitSelection(SCH_SHEET_PATH *aSheet)
EDA_ITEM * Next() const
Definition: base_struct.h:218
SCH_SHEET * g_RootSheet
Definition: eeschema.cpp:47
const wxString GetRef(const SCH_SHEET_PATH *aSheet)
Return the reference for the given sheet path.
LIB_PIN * GetNextPin(LIB_PIN *aItem=NULL)
Return the next pin object from the draw list.
size_t i
Definition: json11.cpp:597
Class SCH_COMPONENT describes a real schematic component.
Definition: sch_component.h:73
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:163
bool addPinToComponentPinList(SCH_COMPONENT *Component, SCH_SHEET_PATH *sheet, LIB_PIN *PinEntry)
Function addPinToComponentPinList adds a new pin description to the pin list m_SortedComponentPinList...
int GetConvert() const

References NETLIST_EXPORTER::addPinToComponentPinList(), g_RootSheet, SCH_COMPONENT::GetConvert(), LIB_PART::GetNextPin(), SCH_COMPONENT::GetRef(), SCH_COMPONENT::GetUnitSelection(), i, LIB_PIN_T, and SCH_COMPONENT_T.

Referenced by NETLIST_EXPORTER::findNextComponentAndCreatePinList().

◆ findNextComponent()

SCH_COMPONENT * NETLIST_EXPORTER::findNextComponent ( EDA_ITEM aItem,
SCH_SHEET_PATH aSheetPath 
)
protectedinherited

Definition at line 101 of file netlist_exporter.cpp.

102 {
103  wxString ref;
104 
105  // continue searching from the middle of a linked list (the draw list)
106  for( ; aItem; aItem = aItem->Next() )
107  {
108  if( aItem->Type() != SCH_COMPONENT_T )
109  continue;
110 
111  // found next component
112  SCH_COMPONENT* comp = (SCH_COMPONENT*) aItem;
113 
114  // Power symbols and other components which have the reference starting
115  // with "#" are not included in netlist (pseudo or virtual components)
116  ref = comp->GetRef( aSheetPath );
117 
118  if( ref[0] == wxChar( '#' ) )
119  continue;
120 
121  // if( Component->m_FlagControlMulti == 1 )
122  // continue; /* yes */
123  // removed because with multiple instances of one schematic
124  // (several sheets pointing to 1 screen), this will be erroneously be
125  // toggled.
126 
127  LIB_PART* part = comp->GetPartRef().lock().get();
128 
129  if( !part )
130  continue;
131 
132  // If component is a "multi parts per package" type
133  if( part->GetUnitCount() > 1 )
134  {
135  // test if this reference has already been processed, and if so skip
136  if( m_ReferencesAlreadyFound.Lookup( ref ) )
137  continue;
138  }
139 
140  // record the usage of this library component entry.
141  m_LibParts.insert( part ); // rejects non-unique pointers
142 
143  return comp;
144  }
145 
146  return NULL;
147 }
int GetUnitCount() const
bool Lookup(const wxString &aString)
Function Lookup returns true if aString already exists in the set, otherwise returns false and adds a...
PART_REF & GetPartRef()
UNIQUE_STRINGS m_ReferencesAlreadyFound
Used for "multi parts per package" components, avoids processing a lib component more than once.
EDA_ITEM * Next() const
Definition: base_struct.h:218
std::set< LIB_PART *, LIB_PART_LESS_THAN > m_LibParts
unique library parts used. LIB_PART items are sorted by names
Define a library symbol object.
const wxString GetRef(const SCH_SHEET_PATH *aSheet)
Return the reference for the given sheet path.
Class SCH_COMPONENT describes a real schematic component.
Definition: sch_component.h:73
KICAD_T Type() const
Function Type()
Definition: base_struct.h:210

References SCH_COMPONENT::GetPartRef(), SCH_COMPONENT::GetRef(), LIB_PART::GetUnitCount(), UNIQUE_STRINGS::Lookup(), NETLIST_EXPORTER::m_LibParts, NETLIST_EXPORTER::m_ReferencesAlreadyFound, EDA_ITEM::Next(), SCH_COMPONENT_T, and EDA_ITEM::Type().

Referenced by NETLIST_EXPORTER_GENERIC::makeComponents().

◆ findNextComponentAndCreatePinList()

SCH_COMPONENT * NETLIST_EXPORTER::findNextComponentAndCreatePinList ( EDA_ITEM aItem,
SCH_SHEET_PATH aSheetPath 
)
protectedinherited

Function findNextComponentAndCreatePinList finds a component from the DrawList and builds its pin list in m_SortedComponentPinList.

This list is sorted by pin num. the component is the next actual component after aItem (power symbols and virtual components that have their reference starting by '#'are skipped).

Definition at line 158 of file netlist_exporter.cpp.

160 {
161  wxString ref;
162 
163  m_SortedComponentPinList.clear();
164 
165  // continue searching from the middle of a linked list (the draw list)
166  for( ; aItem; aItem = aItem->Next() )
167  {
168  if( aItem->Type() != SCH_COMPONENT_T )
169  continue;
170 
171  // found next component
172  SCH_COMPONENT* comp = (SCH_COMPONENT*) aItem;
173 
174  // Power symbols and other components which have the reference starting
175  // with "#" are not included in netlist (pseudo or virtual components)
176  ref = comp->GetRef( aSheetPath );
177 
178  if( ref[0] == wxChar( '#' ) )
179  continue;
180 
181  // if( Component->m_FlagControlMulti == 1 )
182  // continue; /* yes */
183  // removed because with multiple instances of one schematic
184  // (several sheets pointing to 1 screen), this will be erroneously be
185  // toggled.
186 
187  LIB_PART* part = comp->GetPartRef().lock().get();
188 
189  if( !part )
190  continue;
191 
192  // If component is a "multi parts per package" type
193  if( part->GetUnitCount() > 1 )
194  {
195  // test if this reference has already been processed, and if so skip
196  if( m_ReferencesAlreadyFound.Lookup( ref ) )
197  continue;
198 
199  // Collect all pins for this reference designator by searching
200  // the entire design for other parts with the same reference designator.
201  // This is only done once, it would be too expensive otherwise.
202  findAllUnitsOfComponent( comp, part, aSheetPath );
203  }
204 
205  else // entry->GetUnitCount() <= 1 means one part per package
206  {
207  LIB_PINS pins; // constructed once here
208 
209  part->GetPins( pins, comp->GetUnitSelection( aSheetPath ), comp->GetConvert() );
210 
211  for( size_t i = 0; i < pins.size(); i++ )
212  {
213  LIB_PIN* pin = pins[i];
214 
215  wxASSERT( pin->Type() == LIB_PIN_T );
216 
217  addPinToComponentPinList( comp, aSheetPath, pin );
218  }
219  }
220 
221  // Sort pins in m_SortedComponentPinList by pin number
222  sort( m_SortedComponentPinList.begin(),
224 
225  // Remove duplicate Pins in m_SortedComponentPinList
227 
228  // record the usage of this library component entry.
229  m_LibParts.insert( part ); // rejects non-unique pointers
230 
231  return comp;
232  }
233 
234  return NULL;
235 }
int GetUnitCount() const
bool Lookup(const wxString &aString)
Function Lookup returns true if aString already exists in the set, otherwise returns false and adds a...
PART_REF & GetPartRef()
UNIQUE_STRINGS m_ReferencesAlreadyFound
Used for "multi parts per package" components, avoids processing a lib component more than once.
std::vector< LIB_PIN * > LIB_PINS
Helper for defining a list of pin object pointers.
Definition: lib_item.h:55
int GetUnitSelection(SCH_SHEET_PATH *aSheet)
void findAllUnitsOfComponent(SCH_COMPONENT *aComponent, LIB_PART *aEntry, SCH_SHEET_PATH *aSheetPath)
Function findAllUnitsOfComponent is used for "multiple parts per package" components.
EDA_ITEM * Next() const
Definition: base_struct.h:218
static bool sortPinsByNum(NETLIST_OBJECT *aPin1, NETLIST_OBJECT *aPin2)
Comparison routine for sorting by pin numbers.
void GetPins(LIB_PINS &aList, int aUnit=0, int aConvert=0)
Return a list of pin object pointers from the draw item list.
std::set< LIB_PART *, LIB_PART_LESS_THAN > m_LibParts
unique library parts used. LIB_PART items are sorted by names
Define a library symbol object.
const wxString GetRef(const SCH_SHEET_PATH *aSheet)
Return the reference for the given sheet path.
NETLIST_OBJECTS m_SortedComponentPinList
yes ownership, connected items flat list
size_t i
Definition: json11.cpp:597
Class SCH_COMPONENT describes a real schematic component.
Definition: sch_component.h:73
bool addPinToComponentPinList(SCH_COMPONENT *Component, SCH_SHEET_PATH *sheet, LIB_PIN *PinEntry)
Function addPinToComponentPinList adds a new pin description to the pin list m_SortedComponentPinList...
int GetConvert() const
KICAD_T Type() const
Function Type()
Definition: base_struct.h:210
void eraseDuplicatePins()
Function eraseDuplicatePins erase duplicate Pins from m_SortedComponentPinList (i....

References NETLIST_EXPORTER::addPinToComponentPinList(), NETLIST_EXPORTER::eraseDuplicatePins(), NETLIST_EXPORTER::findAllUnitsOfComponent(), SCH_COMPONENT::GetConvert(), SCH_COMPONENT::GetPartRef(), LIB_PART::GetPins(), SCH_COMPONENT::GetRef(), LIB_PART::GetUnitCount(), SCH_COMPONENT::GetUnitSelection(), i, LIB_PIN_T, UNIQUE_STRINGS::Lookup(), NETLIST_EXPORTER::m_LibParts, NETLIST_EXPORTER::m_ReferencesAlreadyFound, NETLIST_EXPORTER::m_SortedComponentPinList, EDA_ITEM::Next(), SCH_COMPONENT_T, sortPinsByNum(), and EDA_ITEM::Type().

Referenced by NETLIST_EXPORTER_PSPICE::ProcessNetlist(), NETLIST_EXPORTER_ORCADPCB2::WriteNetlist(), and NETLIST_EXPORTER_CADSTAR::WriteNetlist().

◆ Format()

void NETLIST_EXPORTER_KICAD::Format ( OUTPUTFORMATTER aOutputFormatter,
int  aCtl 
)

Function Format outputs this s-expression netlist into aOutputFormatter.

Parameters
aOutputFormatteris the destination of the serialization to text.
aCtlis bit set composed by OR-ing together enum GNL bits, it allows outputting a subset of the full document model.
Exceptions
IO_ERRORif any problems.

Definition at line 57 of file netlist_exporter_kicad.cpp.

58 {
59  // Prepare list of nets generation
60  for( unsigned ii = 0; ii < m_masterList->size(); ii++ )
61  m_masterList->GetItem( ii )->m_Flag = 0;
62 
63  std::unique_ptr<XNODE> xroot( makeRoot( aCtl ) );
64 
65  xroot->Format( aOut, 0 );
66 }
NETLIST_OBJECT_LIST * m_masterList
XNODE * makeRoot(int aCtl=GNL_ALL)
Function makeGenericRoot builds the entire document tree for the generic export.
NETLIST_OBJECT * GetItem(unsigned aIdx) const
Acces to an item in list.

References NETLIST_OBJECT_LIST::GetItem(), NETLIST_OBJECT::m_Flag, NETLIST_EXPORTER::m_masterList, and NETLIST_EXPORTER_GENERIC::makeRoot().

Referenced by SCH_EDIT_FRAME::KiwayMailIn(), SCH_EDIT_FRAME::sendNetlistToCvpcb(), and WriteNetlist().

◆ MakeCommandLine()

wxString NETLIST_EXPORTER::MakeCommandLine ( const wxString &  aFormatString,
const wxString &  aNetlistFile,
const wxString &  aFinalFile,
const wxString &  aProjectDirectory 
)
staticinherited

Function MakeCommandLine builds up a string that describes a command line for executing a child process.

The input and output file names along with any options to the executable are all possibly in the returned string.

Parameters
aFormatStringholds:
  • the name of the external program
  • any options needed by that program
  • formatting sequences, see below.
aNetlistFileis the name of the input file for the external program, that is a intermediate netlist file in xml format.
aFinalFileis the name of the output file that the user expects.
aProjectDirectoryis used for P replacement, it should omit the trailing '/'.

Supported formatting sequences and their meaning:

  • B => base filename of selected output file, minus path and extension.
  • I => complete filename and path of the temporary input file.
  • O => complete filename and path of the user chosen output file.
  • P => project directory, without name and without trailing '/'

Definition at line 39 of file netlist_exporter.cpp.

41 {
42  // Expand format symbols in the command line:
43  // %B => base filename of selected output file, minus path and extension.
44  // %P => project directory name, without trailing '/' or '\'.
45  // %I => full filename of the input file (the intermediate net file).
46  // %O => complete filename and path (but without extension) of the user chosen output file.
47 
48  wxString ret = aFormatString;
49  wxFileName in = aNetlistFile;
50  wxFileName out = aFinalFile;
51  wxString str_out = out.GetFullPath();
52 
53  ret.Replace( "%P", aProjectPath, true );
54  ret.Replace( "%B", out.GetName(), true );
55  ret.Replace( "%I", in.GetFullPath(), true );
56 
57 #ifdef __WINDOWS__
58  // A ugly hack to run xsltproc that has a serious bug on Window since a long time:
59  // the filename given after -o option (output filename) cannot use '\' in filename
60  // so replace if by '/' if possible (I mean if the filename does not start by "\\"
61  // that is a filename on a Windows server)
62 
63  if( !str_out.StartsWith( "\\\\" ) )
64  str_out.Replace( "\\", "/" );
65 #endif
66 
67  ret.Replace( "%O", str_out, true );
68 
69  return ret;
70 }

Referenced by SCH_EDIT_FRAME::WriteNetListFile().

◆ makeComponents()

XNODE * NETLIST_EXPORTER_GENERIC::makeComponents ( )
protectedinherited

Function makeComponents.

Returns
XNODE* - returns a sub-tree holding all the schematic components.

Definition at line 203 of file netlist_exporter_generic.cpp.

204 {
205  XNODE* xcomps = node( "components" );
206 
207  wxString timeStamp;
208 
210 
211  SCH_SHEET_LIST sheetList( g_RootSheet );
212 
213  // Output is xml, so there is no reason to remove spaces from the field values.
214  // And XML element names need not be translated to various languages.
215 
216  for( unsigned i = 0; i < sheetList.size(); i++ )
217  {
218  for( EDA_ITEM* schItem = sheetList[i].LastDrawList(); schItem; schItem = schItem->Next() )
219  {
220  SCH_COMPONENT* comp = findNextComponent( schItem, &sheetList[i] );
221 
222  if( !comp )
223  break; // No component left
224 
225  schItem = comp;
226 
227  XNODE* xcomp; // current component being constructed
228 
229  // Output the component's elements in order of expected access frequency.
230  // This may not always look best, but it will allow faster execution
231  // under XSL processing systems which do sequential searching within
232  // an element.
233 
234  xcomps->AddChild( xcomp = node( "comp" ) );
235  xcomp->AddAttribute( "ref", comp->GetRef( &sheetList[i] ) );
236 
237  addComponentFields( xcomp, comp, &sheetList[i] );
238 
239  XNODE* xlibsource;
240  xcomp->AddChild( xlibsource = node( "libsource" ) );
241 
242  // "logical" library name, which is in anticipation of a better search
243  // algorithm for parts based on "logical_lib.part" and where logical_lib
244  // is merely the library name minus path and extension.
245  PART_SPTR part = comp->GetPartRef().lock();
246 
247  if( part )
248  xlibsource->AddAttribute( "lib", part->GetLibId().GetLibNickname() );
249 
250  // We only want the symbol name, not the full LIB_ID.
251  xlibsource->AddAttribute( "part", comp->GetLibId().GetLibItemName() );
252 
253  xlibsource->AddAttribute( "description", comp->GetDescription() );
254 
255  XNODE* xsheetpath;
256 
257  xcomp->AddChild( xsheetpath = node( "sheetpath" ) );
258  xsheetpath->AddAttribute( "names", sheetList[i].PathHumanReadable() );
259  xsheetpath->AddAttribute( "tstamps", sheetList[i].Path() );
260 
261  timeStamp.Printf( "%8.8lX", (unsigned long)comp->GetTimeStamp() );
262  xcomp->AddChild( node( "tstamp", timeStamp ) );
263  }
264  }
265 
266  return xcomps;
267 }
Class SCH_SHEET_LIST.
const UTF8 & GetLibItemName() const
Definition: lib_id.h:114
PART_REF & GetPartRef()
UNIQUE_STRINGS m_ReferencesAlreadyFound
Used for "multi parts per package" components, avoids processing a lib component more than once.
XNODE * node(const wxString &aName, const wxString &aTextualContent=wxEmptyString)
Function node is a convenience function that creates a new XNODE with an optional textual child.
wxString GetDescription() const
Return information about the aliased parts.
void Clear()
Function Clear erases the record.
SCH_COMPONENT * findNextComponent(EDA_ITEM *aItem, SCH_SHEET_PATH *aSheetPath)
EDA_ITEM * Next() const
Definition: base_struct.h:218
SCH_SHEET * g_RootSheet
Definition: eeschema.cpp:47
void addComponentFields(XNODE *xcomp, SCH_COMPONENT *comp, SCH_SHEET_PATH *aSheet)
std::shared_ptr< LIB_PART > PART_SPTR
shared pointer to LIB_PART
timestamp_t GetTimeStamp() const
Definition: base_struct.h:216
const wxString GetRef(const SCH_SHEET_PATH *aSheet)
Return the reference for the given sheet path.
Class XNODE holds an XML or S-expression element.
Definition: xnode.h:43
size_t i
Definition: json11.cpp:597
Class SCH_COMPONENT describes a real schematic component.
Definition: sch_component.h:73
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:163
const LIB_ID & GetLibId() const

References NETLIST_EXPORTER_GENERIC::addComponentFields(), UNIQUE_STRINGS::Clear(), NETLIST_EXPORTER::findNextComponent(), g_RootSheet, SCH_COMPONENT::GetDescription(), SCH_COMPONENT::GetLibId(), LIB_ID::GetLibItemName(), SCH_COMPONENT::GetPartRef(), SCH_COMPONENT::GetRef(), EDA_ITEM::GetTimeStamp(), i, NETLIST_EXPORTER::m_ReferencesAlreadyFound, and NETLIST_EXPORTER_GENERIC::node().

Referenced by NETLIST_EXPORTER_GENERIC::makeRoot().

◆ makeDesignHeader()

XNODE * NETLIST_EXPORTER_GENERIC::makeDesignHeader ( )
protectedinherited

Function makeDesignHeader fills out a project "design" header into an XML node.

Returns
XNODE* - the design header

Definition at line 270 of file netlist_exporter_generic.cpp.

271 {
272  SCH_SCREEN* screen;
273  XNODE* xdesign = node( "design" );
274  XNODE* xtitleBlock;
275  XNODE* xsheet;
276  XNODE* xcomment;
277  wxString sheetTxt;
278  wxFileName sourceFileName;
279 
280  // the root sheet is a special sheet, call it source
281  xdesign->AddChild( node( "source", g_RootSheet->GetScreen()->GetFileName() ) );
282 
283  xdesign->AddChild( node( "date", DateAndTime() ) );
284 
285  // which Eeschema tool
286  xdesign->AddChild( node( "tool", wxString( "Eeschema " ) + GetBuildVersion() ) );
287 
288  /*
289  Export the sheets information
290  */
291  SCH_SHEET_LIST sheetList( g_RootSheet );
292 
293  for( unsigned i = 0; i < sheetList.size(); i++ )
294  {
295  screen = sheetList[i].LastScreen();
296 
297  xdesign->AddChild( xsheet = node( "sheet" ) );
298 
299  // get the string representation of the sheet index number.
300  // Note that sheet->GetIndex() is zero index base and we need to increment the
301  // number by one to make it human readable
302  sheetTxt.Printf( "%u", i + 1 );
303  xsheet->AddAttribute( "number", sheetTxt );
304  xsheet->AddAttribute( "name", sheetList[i].PathHumanReadable() );
305  xsheet->AddAttribute( "tstamps", sheetList[i].Path() );
306 
307 
308  TITLE_BLOCK tb = screen->GetTitleBlock();
309 
310  xsheet->AddChild( xtitleBlock = node( "title_block" ) );
311 
312  xtitleBlock->AddChild( node( "title", tb.GetTitle() ) );
313  xtitleBlock->AddChild( node( "company", tb.GetCompany() ) );
314  xtitleBlock->AddChild( node( "rev", tb.GetRevision() ) );
315  xtitleBlock->AddChild( node( "date", tb.GetDate() ) );
316 
317  // We are going to remove the fileName directories.
318  sourceFileName = wxFileName( screen->GetFileName() );
319  xtitleBlock->AddChild( node( "source", sourceFileName.GetFullName() ) );
320 
321  xtitleBlock->AddChild( xcomment = node( "comment" ) );
322  xcomment->AddAttribute( "number", "1" );
323  xcomment->AddAttribute( "value", tb.GetComment( 0 ) );
324 
325  xtitleBlock->AddChild( xcomment = node( "comment" ) );
326  xcomment->AddAttribute( "number", "2" );
327  xcomment->AddAttribute( "value", tb.GetComment( 1 ) );
328 
329  xtitleBlock->AddChild( xcomment = node( "comment" ) );
330  xcomment->AddAttribute( "number", "3" );
331  xcomment->AddAttribute( "value", tb.GetComment( 2 ) );
332 
333  xtitleBlock->AddChild( xcomment = node( "comment" ) );
334  xcomment->AddAttribute( "number", "4" );
335  xcomment->AddAttribute( "value", tb.GetComment( 3 ) );
336 
337  xtitleBlock->AddChild( xcomment = node( "comment" ) );
338  xcomment->AddAttribute( "number", "5" );
339  xcomment->AddAttribute( "value", tb.GetComment( 4 ) );
340 
341  xtitleBlock->AddChild( xcomment = node( "comment" ) );
342  xcomment->AddAttribute( "number", "6" );
343  xcomment->AddAttribute( "value", tb.GetComment( 5 ) );
344 
345  xtitleBlock->AddChild( xcomment = node( "comment" ) );
346  xcomment->AddAttribute( "number", "7" );
347  xcomment->AddAttribute( "value", tb.GetComment( 6 ) );
348 
349  xtitleBlock->AddChild( xcomment = node( "comment" ) );
350  xcomment->AddAttribute( "number", "8" );
351  xcomment->AddAttribute( "value", tb.GetComment( 7 ) );
352 
353  xtitleBlock->AddChild( xcomment = node( "comment" ) );
354  xcomment->AddAttribute( "number", "9" );
355  xcomment->AddAttribute( "value", tb.GetComment( 8 ) );
356  }
357 
358  return xdesign;
359 }
Class SCH_SHEET_LIST.
const wxString & GetFileName() const
Definition: sch_screen.h:123
XNODE * node(const wxString &aName, const wxString &aTextualContent=wxEmptyString)
Function node is a convenience function that creates a new XNODE with an optional textual child.
const wxString & GetComment(int aIdx) const
Definition: title_block.h:110
const TITLE_BLOCK & GetTitleBlock() const
Definition: sch_screen.h:128
SCH_SCREEN * GetScreen()
Definition: sch_sheet.h:281
Class TITLE_BLOCK holds the information shown in the lower right corner of a plot,...
Definition: title_block.h:40
SCH_SHEET * g_RootSheet
Definition: eeschema.cpp:47
wxString GetBuildVersion()
Function GetBuildVersion Return the build version string.
const wxString & GetRevision() const
Definition: title_block.h:89
const wxString & GetCompany() const
Definition: title_block.h:99
Class XNODE holds an XML or S-expression element.
Definition: xnode.h:43
const wxString & GetDate() const
Definition: title_block.h:79
size_t i
Definition: json11.cpp:597
const wxString & GetTitle() const
Definition: title_block.h:65
wxString DateAndTime()
Definition: string.cpp:345

References DateAndTime(), g_RootSheet, GetBuildVersion(), TITLE_BLOCK::GetComment(), TITLE_BLOCK::GetCompany(), TITLE_BLOCK::GetDate(), SCH_SCREEN::GetFileName(), TITLE_BLOCK::GetRevision(), SCH_SHEET::GetScreen(), TITLE_BLOCK::GetTitle(), SCH_SCREEN::GetTitleBlock(), i, and NETLIST_EXPORTER_GENERIC::node().

Referenced by NETLIST_EXPORTER_GENERIC::makeRoot().

◆ makeLibParts()

XNODE * NETLIST_EXPORTER_GENERIC::makeLibParts ( )
protectedinherited

Function makeLibParts fills out an XML node with the unique library parts and returns it.

Returns
XNODE* - the library parts nodes

Definition at line 385 of file netlist_exporter_generic.cpp.

386 {
387  XNODE* xlibparts = node( "libparts" ); // auto_ptr
388 
389  LIB_PINS pinList;
390  LIB_FIELDS fieldList;
391 
392  m_libraries.clear();
393 
394  for( auto lcomp : m_LibParts )
395  {
396  wxString libNickname = lcomp->GetLibId().GetLibNickname();;
397 
398  // The library nickname will be empty if the cache library is used.
399  if( !libNickname.IsEmpty() )
400  m_libraries.insert( libNickname ); // inserts component's library if unique
401 
402  XNODE* xlibpart;
403  xlibparts->AddChild( xlibpart = node( "libpart" ) );
404  xlibpart->AddAttribute( "lib", libNickname );
405  xlibpart->AddAttribute( "part", lcomp->GetName() );
406 
407  if( lcomp->GetAliasCount() )
408  {
409  wxArrayString aliases = lcomp->GetAliasNames( false );
410  if( aliases.GetCount() )
411  {
412  XNODE* xaliases = node( "aliases" );
413  xlibpart->AddChild( xaliases );
414  for( unsigned i=0; i<aliases.GetCount(); ++i )
415  {
416  xaliases->AddChild( node( "alias", aliases[i] ) );
417  }
418  }
419  }
420 
421  //----- show the important properties -------------------------
422  if( !lcomp->GetAlias( 0 )->GetDescription().IsEmpty() )
423  xlibpart->AddChild( node( "description", lcomp->GetAlias( 0 )->GetDescription() ) );
424 
425  if( !lcomp->GetAlias( 0 )->GetDocFileName().IsEmpty() )
426  xlibpart->AddChild( node( "docs", lcomp->GetAlias( 0 )->GetDocFileName() ) );
427 
428  // Write the footprint list
429  if( lcomp->GetFootprints().GetCount() )
430  {
431  XNODE* xfootprints;
432  xlibpart->AddChild( xfootprints = node( "footprints" ) );
433 
434  for( unsigned i=0; i<lcomp->GetFootprints().GetCount(); ++i )
435  {
436  xfootprints->AddChild( node( "fp", lcomp->GetFootprints()[i] ) );
437  }
438  }
439 
440  //----- show the fields here ----------------------------------
441  fieldList.clear();
442  lcomp->GetFields( fieldList );
443 
444  XNODE* xfields;
445  xlibpart->AddChild( xfields = node( "fields" ) );
446 
447  for( unsigned i=0; i<fieldList.size(); ++i )
448  {
449  if( !fieldList[i].GetText().IsEmpty() )
450  {
451  XNODE* xfield;
452  xfields->AddChild( xfield = node( "field", fieldList[i].GetText() ) );
453  xfield->AddAttribute( "name", fieldList[i].GetName(false) );
454  }
455  }
456 
457  //----- show the pins here ------------------------------------
458  pinList.clear();
459  lcomp->GetPins( pinList, 0, 0 );
460 
461  /* we must erase redundant Pins references in pinList
462  * These redundant pins exist because some pins
463  * are found more than one time when a component has
464  * multiple parts per package or has 2 representations (DeMorgan conversion)
465  * For instance, a 74ls00 has DeMorgan conversion, with different pin shapes,
466  * and therefore each pin appears 2 times in the list.
467  * Common pins (VCC, GND) can also be found more than once.
468  */
469  sort( pinList.begin(), pinList.end(), sortPinsByNumber );
470  for( int ii = 0; ii < (int)pinList.size()-1; ii++ )
471  {
472  if( pinList[ii]->GetNumber() == pinList[ii+1]->GetNumber() )
473  { // 2 pins have the same number, remove the redundant pin at index i+1
474  pinList.erase(pinList.begin() + ii + 1);
475  ii--;
476  }
477  }
478 
479  if( pinList.size() )
480  {
481  XNODE* pins;
482 
483  xlibpart->AddChild( pins = node( "pins" ) );
484  for( unsigned i=0; i<pinList.size(); ++i )
485  {
486  XNODE* pin;
487 
488  pins->AddChild( pin = node( "pin" ) );
489  pin->AddAttribute( "num", pinList[i]->GetNumber() );
490  pin->AddAttribute( "name", pinList[i]->GetName() );
491  pin->AddAttribute( "type", pinList[i]->GetCanonicalElectricalTypeName() );
492 
493  // caution: construction work site here, drive slowly
494  }
495  }
496  }
497 
498  return xlibparts;
499 }
XNODE * node(const wxString &aName, const wxString &aTextualContent=wxEmptyString)
Function node is a convenience function that creates a new XNODE with an optional textual child.
std::vector< LIB_PIN * > LIB_PINS
Helper for defining a list of pin object pointers.
Definition: lib_item.h:55
std::set< LIB_PART *, LIB_PART_LESS_THAN > m_LibParts
unique library parts used. LIB_PART items are sorted by names
std::set< wxString > m_libraries
Set of library nicknames.
wxString GetText(GRAPHIC_PINSHAPE shape)
Definition: pin_shape.cpp:33
Class XNODE holds an XML or S-expression element.
Definition: xnode.h:43
std::vector< LIB_FIELD > LIB_FIELDS
Definition: lib_field.h:214
size_t i
Definition: json11.cpp:597
static bool sortPinsByNumber(LIB_PIN *aPin1, LIB_PIN *aPin2)

References GetText(), i, NETLIST_EXPORTER::m_LibParts, NETLIST_EXPORTER_GENERIC::m_libraries, NETLIST_EXPORTER_GENERIC::node(), and sortPinsByNumber().

Referenced by NETLIST_EXPORTER_GENERIC::makeRoot().

◆ makeLibraries()

XNODE * NETLIST_EXPORTER_GENERIC::makeLibraries ( )
protectedinherited

Function makeLibraries fills out an XML node with a list of used libraries and returns it.

Must have called makeGenericLibParts() before this function.

Returns
XNODE* - the library nodes

Definition at line 362 of file netlist_exporter_generic.cpp.

363 {
364  XNODE* xlibs = node( "libraries" ); // auto_ptr
365 
366  for( std::set<wxString>::iterator it = m_libraries.begin(); it!=m_libraries.end(); ++it )
367  {
368  wxString libNickname = *it;
369  XNODE* xlibrary;
370 
371  if( m_libTable->HasLibrary( libNickname ) )
372  {
373  xlibs->AddChild( xlibrary = node( "library" ) );
374  xlibrary->AddAttribute( "logical", libNickname );
375  xlibrary->AddChild( node( "uri", m_libTable->GetFullURI( libNickname ) ) );
376  }
377 
378  // @todo: add more fun stuff here
379  }
380 
381  return xlibs;
382 }
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library table.
XNODE * node(const wxString &aName, const wxString &aTextualContent=wxEmptyString)
Function node is a convenience function that creates a new XNODE with an optional textual child.
std::set< wxString > m_libraries
Set of library nicknames.
wxString GetFullURI(const wxString &aLibNickname, bool aExpandEnvVars=true) const
Return the full URI of the library mapped to aLibNickname.
Class XNODE holds an XML or S-expression element.
Definition: xnode.h:43

References LIB_TABLE::GetFullURI(), LIB_TABLE::HasLibrary(), NETLIST_EXPORTER_GENERIC::m_libraries, NETLIST_EXPORTER_GENERIC::m_libTable, and NETLIST_EXPORTER_GENERIC::node().

Referenced by NETLIST_EXPORTER_GENERIC::makeRoot().

◆ makeListOfNets()

XNODE * NETLIST_EXPORTER_GENERIC::makeListOfNets ( bool  aUseGraph = true)
protectedinherited

Function makeListOfNets fills out an XML node with a list of nets and returns it.

Returns
XNODE* - the list of nets nodes

Definition at line 502 of file netlist_exporter_generic.cpp.

503 {
504  XNODE* xnets = node( "nets" ); // auto_ptr if exceptions ever get used.
505  wxString netCodeTxt;
506  wxString netName;
507  wxString ref;
508 
509  XNODE* xnet = 0;
510  int netCode;
511  int lastNetCode = -1;
512  int sameNetcodeCount = 0;
513 
514 
515  /* output:
516  <net code="123" name="/cfcard.sch/WAIT#">
517  <node ref="R23" pin="1"/>
518  <node ref="U18" pin="12"/>
519  </net>
520  */
521 
522  m_LibParts.clear(); // must call this function before using m_LibParts.
523 
524  if( aUseGraph )
525  {
526  wxASSERT( m_graph );
527 
528  for( const auto& it : m_graph->m_net_code_to_subgraphs_map )
529  {
530  bool added = false;
531 
532  auto code = it.first;
533  auto subgraphs = it.second;
534  auto net_name = subgraphs[0]->GetNetName();
535 
536  XNODE* xnode;
537 
538  for( auto subgraph : subgraphs )
539  {
540  auto sheet = subgraph->m_sheet;
541 
542  for( auto item : subgraph->m_items )
543  {
544  if( item->Type() == SCH_PIN_T )
545  {
546  auto pin = static_cast<SCH_PIN*>( item );
547 
548  auto refText = pin->GetParentComponent()->GetRef( &sheet );
549  auto pinText = pin->GetNumber();
550 
551  // Skip power symbols and virtual components
552  if( refText[0] == wxChar( '#' ) )
553  continue;
554 
555  if( !added )
556  {
557  xnets->AddChild( xnet = node( "net" ) );
558  netCodeTxt.Printf( "%d", code );
559  xnet->AddAttribute( "code", netCodeTxt );
560  xnet->AddAttribute( "name", net_name );
561 
562  added = true;
563  }
564 
565  xnet->AddChild( xnode = node( "node" ) );
566  xnode->AddAttribute( "ref", refText );
567  xnode->AddAttribute( "pin", pinText );
568  }
569  }
570  }
571  }
572  }
573  else
574  {
575  for( unsigned ii = 0; ii < m_masterList->size(); ii++ )
576  {
577  NETLIST_OBJECT* nitem = m_masterList->GetItem( ii );
578  SCH_COMPONENT* comp;
579 
580  // New net found, write net id;
581  if( ( netCode = nitem->GetNet() ) != lastNetCode )
582  {
583  sameNetcodeCount = 0; // item count for this net
584  netName = nitem->GetNetName();
585  lastNetCode = netCode;
586  }
587 
588  if( nitem->m_Type != NET_PIN )
589  continue;
590 
591  if( nitem->m_Flag != 0 ) // Redundant pin, skip it
592  continue;
593 
594  comp = nitem->GetComponentParent();
595 
596  // Get the reference for the net name and the main parent component
597  ref = comp->GetRef( &nitem->m_SheetPath );
598  if( ref[0] == wxChar( '#' ) )
599  continue;
600 
601  if( ++sameNetcodeCount == 1 )
602  {
603  xnets->AddChild( xnet = node( "net" ) );
604  netCodeTxt.Printf( "%d", netCode );
605  xnet->AddAttribute( "code", netCodeTxt );
606  xnet->AddAttribute( "name", netName );
607  }
608 
609  XNODE* xnode;
610  xnet->AddChild( xnode = node( "node" ) );
611  xnode->AddAttribute( "ref", ref );
612  xnode->AddAttribute( "pin", nitem->GetPinNumText() );
613  }
614  }
615 
616  return xnets;
617 }
SCH_COMPONENT * GetComponentParent() const
For Pins (NET_PINS):
XNODE * node(const wxString &aName, const wxString &aTextualContent=wxEmptyString)
Function node is a convenience function that creates a new XNODE with an optional textual child.
int GetNet() const
SCH_SHEET_PATH m_SheetPath
NETLIST_ITEM_T m_Type
std::map< int, std::vector< CONNECTION_SUBGRAPH * > > m_net_code_to_subgraphs_map
NETLIST_OBJECT_LIST * m_masterList
std::set< LIB_PART *, LIB_PART_LESS_THAN > m_LibParts
unique library parts used. LIB_PART items are sorted by names
const wxString GetRef(const SCH_SHEET_PATH *aSheet)
Return the reference for the given sheet path.
const wxString & GetPinNumText() const
Function GetPinNum returns a pin number in wxString form.
Class XNODE holds an XML or S-expression element.
Definition: xnode.h:43
NETLIST_OBJECT * GetItem(unsigned aIdx) const
Acces to an item in list.
wxString GetNetName(bool adoptTimestamp=false) const
Function GetNetName.
Class SCH_COMPONENT describes a real schematic component.
Definition: sch_component.h:73

References NETLIST_OBJECT::GetComponentParent(), NETLIST_OBJECT_LIST::GetItem(), NETLIST_OBJECT::GetNet(), NETLIST_OBJECT::GetNetName(), NETLIST_OBJECT::GetPinNumText(), SCH_COMPONENT::GetRef(), NETLIST_OBJECT::m_Flag, NETLIST_EXPORTER_GENERIC::m_graph, NETLIST_EXPORTER::m_LibParts, NETLIST_EXPORTER::m_masterList, CONNECTION_GRAPH::m_net_code_to_subgraphs_map, NETLIST_OBJECT::m_SheetPath, NETLIST_OBJECT::m_Type, NET_PIN, NETLIST_EXPORTER_GENERIC::node(), and SCH_PIN_T.

Referenced by NETLIST_EXPORTER_GENERIC::makeRoot().

◆ makeRoot()

XNODE * NETLIST_EXPORTER_GENERIC::makeRoot ( int  aCtl = GNL_ALL)
protectedinherited

Function makeGenericRoot builds the entire document tree for the generic export.

This is factored out here so we can write the tree in either S-expression file format or in XML if we put the tree built here into a wxXmlDocument.

Parameters
aCtl- a bitset or-ed together from GNL_ENUM values
Returns
XNODE* - the root nodes

Definition at line 56 of file netlist_exporter_generic.cpp.

57 {
58  XNODE* xroot = node( "export" );
59 
60  xroot->AddAttribute( "version", "D" );
61 
62  if( aCtl & GNL_HEADER )
63  // add the "design" header
64  xroot->AddChild( makeDesignHeader() );
65 
66  if( aCtl & GNL_COMPONENTS )
67  xroot->AddChild( makeComponents() );
68 
69  if( aCtl & GNL_PARTS )
70  xroot->AddChild( makeLibParts() );
71 
72  if( aCtl & GNL_LIBRARIES )
73  // must follow makeGenericLibParts()
74  xroot->AddChild( makeLibraries() );
75 
76  if( aCtl & GNL_NETS )
77  xroot->AddChild( makeListOfNets() );
78 
79  return xroot;
80 }
XNODE * makeComponents()
Function makeComponents.
XNODE * node(const wxString &aName, const wxString &aTextualContent=wxEmptyString)
Function node is a convenience function that creates a new XNODE with an optional textual child.
XNODE * makeListOfNets(bool aUseGraph=true)
Function makeListOfNets fills out an XML node with a list of nets and returns it.
XNODE * makeDesignHeader()
Function makeDesignHeader fills out a project "design" header into an XML node.
Class XNODE holds an XML or S-expression element.
Definition: xnode.h:43
XNODE * makeLibraries()
Function makeLibraries fills out an XML node with a list of used libraries and returns it.
XNODE * makeLibParts()
Function makeLibParts fills out an XML node with the unique library parts and returns it.

References GNL_COMPONENTS, GNL_HEADER, GNL_LIBRARIES, GNL_NETS, GNL_PARTS, NETLIST_EXPORTER_GENERIC::makeComponents(), NETLIST_EXPORTER_GENERIC::makeDesignHeader(), NETLIST_EXPORTER_GENERIC::makeLibParts(), NETLIST_EXPORTER_GENERIC::makeLibraries(), NETLIST_EXPORTER_GENERIC::makeListOfNets(), and NETLIST_EXPORTER_GENERIC::node().

Referenced by Format(), and NETLIST_EXPORTER_GENERIC::WriteNetlist().

◆ node()

XNODE * NETLIST_EXPORTER_GENERIC::node ( const wxString &  aName,
const wxString &  aTextualContent = wxEmptyString 
)
protectedinherited

Function node is a convenience function that creates a new XNODE with an optional textual child.

It also provides some insulation from a possible change in XML library.

Parameters
aNameis the name to associate with a new node of type wxXML_ELEMENT_NODE.
aTextualContentis optional, and if given is the text to include in a child of the returned node, and has type wxXML_TEXT_NODE.

Definition at line 620 of file netlist_exporter_generic.cpp.

621 {
622  XNODE* n = new XNODE( wxXML_ELEMENT_NODE, aName );
623 
624  if( aTextualContent.Len() > 0 ) // excludes wxEmptyString, the parameter's default value
625  n->AddChild( new XNODE( wxXML_TEXT_NODE, wxEmptyString, aTextualContent ) );
626 
627  return n;
628 }
Class XNODE holds an XML or S-expression element.
Definition: xnode.h:43

Referenced by NETLIST_EXPORTER_GENERIC::addComponentFields(), NETLIST_EXPORTER_GENERIC::makeComponents(), NETLIST_EXPORTER_GENERIC::makeDesignHeader(), NETLIST_EXPORTER_GENERIC::makeLibParts(), NETLIST_EXPORTER_GENERIC::makeLibraries(), NETLIST_EXPORTER_GENERIC::makeListOfNets(), and NETLIST_EXPORTER_GENERIC::makeRoot().

◆ sprintPinNetName()

void NETLIST_EXPORTER::sprintPinNetName ( wxString &  aResult,
const wxString &  aNetNameFormat,
NETLIST_OBJECT aPin,
bool  aUseNetcodeAsNetName = false 
)
staticprotectedinherited

Function sprintPinNetName formats the net name for aPin using aNetNameFormat into aResult.

Net name is:

  • "?" if pin not connected
  • "netname" for global net (like gnd, vcc ..
  • "/path/netname" for the usual nets

if aUseNetcodeAsNetName is true, the net name is just the net code (SPICE only)

Definition at line 73 of file netlist_exporter.cpp.

76 {
77  int netcode = aPin->GetNet();
78 
79  // Not wxString::Clear(), which would free memory. We want the worst
80  // case wxString memory to grow to avoid reallocation from within the
81  // caller's loop.
82  aResult.Empty();
83 
84  if( netcode != 0 && aPin->GetConnectionType() == PAD_CONNECT )
85  {
86  if( aUseNetcodeAsNetName )
87  {
88  aResult.Printf( "%d", netcode );
89  }
90  else
91  {
92  aResult = aPin->GetNetName();
93 
94  if( aResult.IsEmpty() ) // No net name: give a name from net code
95  aResult.Printf( aNetNameFormat.GetData(), netcode );
96  }
97  }
98 }
NET_CONNECTION_T GetConnectionType() const
int GetNet() const
wxString GetNetName(bool adoptTimestamp=false) const
Function GetNetName.

References NETLIST_OBJECT::GetConnectionType(), NETLIST_OBJECT::GetNet(), NETLIST_OBJECT::GetNetName(), and PAD_CONNECT.

Referenced by NETLIST_EXPORTER_PSPICE::Format(), and NETLIST_EXPORTER_ORCADPCB2::WriteNetlist().

◆ WriteNetlist()

bool NETLIST_EXPORTER_KICAD::WriteNetlist ( const wxString &  aOutFileName,
unsigned  aNetlistOptions 
)
overridevirtual

Function WriteNetlist writes to specified output file.

Reimplemented from NETLIST_EXPORTER_GENERIC.

Definition at line 37 of file netlist_exporter_kicad.cpp.

38 {
39  wxASSERT( m_graph );
40 
41  try
42  {
43  FILE_OUTPUTFORMATTER formatter( aOutFileName );
44  Format( &formatter, GNL_ALL );
45  }
46 
47  catch( const IO_ERROR& ioe )
48  {
49  DisplayError( NULL, ioe.What() );
50  return false;
51  }
52 
53  return true;
54 }
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:236
void Format(OUTPUTFORMATTER *aOutputFormatter, int aCtl)
Function Format outputs this s-expression netlist into aOutputFormatter.
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:33
#define GNL_ALL
Class FILE_OUTPUTFORMATTER may be used for text file output.
Definition: richio.h:492
Struct IO_ERROR is a class used to hold an error message and may be used when throwing exceptions con...
Definition: ki_exception.h:76

References DisplayError(), Format(), GNL_ALL, NETLIST_EXPORTER_GENERIC::m_graph, and IO_ERROR::What().

Member Data Documentation

◆ m_graph

CONNECTION_GRAPH* NETLIST_EXPORTER_GENERIC::m_graph
protectedinherited

◆ m_LibParts

std::set<LIB_PART*, LIB_PART_LESS_THAN> NETLIST_EXPORTER::m_LibParts
protectedinherited

◆ m_masterList

◆ m_ReferencesAlreadyFound

UNIQUE_STRINGS NETLIST_EXPORTER::m_ReferencesAlreadyFound
protectedinherited

◆ m_SortedComponentPinList

NETLIST_OBJECTS NETLIST_EXPORTER::m_SortedComponentPinList
protectedinherited

yes ownership, connected items flat list

Used to temporarily store and filter the list of pins of a schematic component when generating schematic component data in netlist (comp section). No ownership of members.

Definition at line 95 of file netlist_exporter.h.

Referenced by NETLIST_EXPORTER::addPinToComponentPinList(), NETLIST_EXPORTER::eraseDuplicatePins(), NETLIST_EXPORTER::findNextComponentAndCreatePinList(), NETLIST_EXPORTER_PSPICE::ProcessNetlist(), NETLIST_EXPORTER_ORCADPCB2::WriteNetlist(), and NETLIST_EXPORTER_CADSTAR::WriteNetlist().


The documentation for this class was generated from the following files: