KiCad PCB EDA Suite
NETLIST_EXPORTER_KICAD Class Reference

Generate the KiCad netlist format supported by Pcbnew. More...

#include <netlist_exporter_kicad.h>

Inheritance diagram for NETLIST_EXPORTER_KICAD:
NETLIST_EXPORTER_XML NETLIST_EXPORTER_BASE

Public Member Functions

 NETLIST_EXPORTER_KICAD (SCHEMATIC *aSchematic)
 
bool WriteNetlist (const wxString &aOutFileName, unsigned aNetlistOptions) override
 Write netlist to aOutFileName. More...
 
void Format (OUTPUTFORMATTER *aOutputFormatter, int aCtl)
 Output 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)
 A convenience function that creates a new XNODE with an optional textual child. More...
 
XNODEmakeRoot (unsigned aCtl=GNL_ALL)
 Build the entire document tree for the generic export. More...
 
XNODEmakeSymbols (unsigned aCtl)
 
XNODEmakeDesignHeader ()
 Fills out a project "design" header into an XML node. More...
 
XNODEmakeLibParts ()
 Fill out an XML node with the unique library parts and returns it. More...
 
XNODEmakeListOfNets (unsigned aCtl)
 Fill out an XML node with a list of nets and returns it. More...
 
XNODEmakeLibraries ()
 Fill out an XML node with a list of used libraries and returns it. More...
 
void addSymbolFields (XNODE *aNode, SCH_COMPONENT *aSymbol, SCH_SHEET_PATH *aSheet)
 
void CreatePinList (SCH_COMPONENT *aSymbol, SCH_SHEET_PATH *aSheetPath)
 Function findNextSymbolAndCreatePinList finds a symbol from the DrawList and builds its pin list in m_sortedSymbolPinList. More...
 
SCH_COMPONENTfindNextSymbol (EDA_ITEM *aItem, SCH_SHEET_PATH *aSheetPath)
 Checks if the given symbol should be processed for netlisting. More...
 
void eraseDuplicatePins ()
 Function eraseDuplicatePins erase duplicate Pins from m_sortedSymbolPinList (i.e. More...
 
void findAllUnitsOfSymbol (SCH_COMPONENT *aSymbol, LIB_PART *aPart, SCH_SHEET_PATH *aSheetPath)
 Function findAllUnitsOfSymbol is used for "multiple parts per package" symbols. More...
 

Protected Attributes

bool m_resolveTextVars
 
std::vector< PIN_INFOm_sortedSymbolPinList
 Used to temporarily store and filter the list of pins of a schematic symbol when generating schematic symbol data in netlist (comp section). More...
 
UNIQUE_STRINGS m_referencesAlreadyFound
 Used for "multiple parts per package" symbols to avoid processing a lib part 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...
 
SCHEMATICm_schematic
 The schematic we're generating a netlist for. More...
 
SCH_SHEET_PATH m_savedCurrentSheet
 The schematic's CurrentSheet when we entered. Restore on exiting. More...
 

Detailed Description

Generate the KiCad netlist format supported by Pcbnew.

It is basically the XML netlist just formatted slightly different.

Definition at line 37 of file netlist_exporter_kicad.h.

Constructor & Destructor Documentation

◆ NETLIST_EXPORTER_KICAD()

NETLIST_EXPORTER_KICAD::NETLIST_EXPORTER_KICAD ( SCHEMATIC aSchematic)
inline

Definition at line 40 of file netlist_exporter_kicad.h.

40  :
41  NETLIST_EXPORTER_XML( aSchematic )
42  {
43  m_resolveTextVars = false;
44  }
NETLIST_EXPORTER_XML(SCHEMATIC *aSchematic)

References NETLIST_EXPORTER_XML::m_resolveTextVars.

Member Function Documentation

◆ addSymbolFields()

void NETLIST_EXPORTER_XML::addSymbolFields ( XNODE aNode,
SCH_COMPONENT aSymbol,
SCH_SHEET_PATH aSheet 
)
protectedinherited

Definition at line 89 of file netlist_exporter_xml.cpp.

91 {
92  COMP_FIELDS fields;
93 
94  if( aSymbol->GetUnitCount() > 1 )
95  {
96  // Sadly, each unit of a component can have its own unique fields. This
97  // block finds the unit with the lowest number having a non blank field
98  // value and records it. Therefore user is best off setting fields
99  // into only the first unit. But this scavenger algorithm will find
100  // any non blank fields in all units and use the first non-blank field
101  // for each unique field name.
102 
103  wxString ref = aSymbol->GetRef( aSheet );
104 
105  SCH_SHEET_LIST sheetList = m_schematic->GetSheets();
106  int minUnit = aSymbol->GetUnit();
107 
108  for( unsigned i = 0; i < sheetList.size(); i++ )
109  {
110  for( auto item : sheetList[i].LastScreen()->Items().OfType( SCH_COMPONENT_T ) )
111  {
112  SCH_COMPONENT* comp2 = (SCH_COMPONENT*) item;
113 
114  wxString ref2 = comp2->GetRef( &sheetList[i] );
115 
116  if( ref2.CmpNoCase( ref ) != 0 )
117  continue;
118 
119  int unit = comp2->GetUnit();
120 
121  // The lowest unit number wins. User should only set fields in any one unit.
122  // remark: IsVoid() returns true for empty strings or the "~" string (empty
123  // field value)
124  if( !comp2->GetValue( &sheetList[i], m_resolveTextVars ).IsEmpty()
125  && ( unit < minUnit || fields.value.IsEmpty() ) )
126  {
127  fields.value = comp2->GetValue( &sheetList[i], m_resolveTextVars );
128  }
129 
130  if( !comp2->GetFootprint( &sheetList[i], m_resolveTextVars ).IsEmpty()
131  && ( unit < minUnit || fields.footprint.IsEmpty() ) )
132  {
133  fields.footprint = comp2->GetFootprint( &sheetList[i], m_resolveTextVars );
134  }
135 
136  if( !comp2->GetField( DATASHEET_FIELD )->IsVoid()
137  && ( unit < minUnit || fields.datasheet.IsEmpty() ) )
138  {
139  if( m_resolveTextVars )
140  fields.datasheet = comp2->GetField( DATASHEET_FIELD )->GetShownText();
141  else
142  fields.datasheet = comp2->GetField( DATASHEET_FIELD )->GetText();
143  }
144 
145  for( int fldNdx = MANDATORY_FIELDS; fldNdx < comp2->GetFieldCount(); ++fldNdx )
146  {
147  SCH_FIELD* f = comp2->GetField( fldNdx );
148 
149  if( f->GetText().size()
150  && ( unit < minUnit || fields.f.count( f->GetName() ) == 0 ) )
151  {
152  if( m_resolveTextVars )
153  fields.f[ f->GetName() ] = f->GetShownText();
154  else
155  fields.f[ f->GetName() ] = f->GetText();
156  }
157  }
158 
159  minUnit = std::min( unit, minUnit );
160  }
161  }
162  }
163  else
164  {
165  fields.value = aSymbol->GetValue( aSheet, m_resolveTextVars );
166  fields.footprint = aSymbol->GetFootprint( aSheet, m_resolveTextVars );
167 
168  if( m_resolveTextVars )
169  fields.datasheet = aSymbol->GetField( DATASHEET_FIELD )->GetShownText();
170  else
171  fields.datasheet = aSymbol->GetField( DATASHEET_FIELD )->GetText();
172 
173  for( int fldNdx = MANDATORY_FIELDS; fldNdx < aSymbol->GetFieldCount(); ++fldNdx )
174  {
175  SCH_FIELD* f = aSymbol->GetField( fldNdx );
176 
177  if( f->GetText().size() )
178  {
179  if( m_resolveTextVars )
180  fields.f[ f->GetName() ] = f->GetShownText();
181  else
182  fields.f[ f->GetName() ] = f->GetText();
183  }
184  }
185  }
186 
187  // Do not output field values blank in netlist:
188  if( fields.value.size() )
189  aNode->AddChild( node( "value", fields.value ) );
190  else // value field always written in netlist
191  aNode->AddChild( node( "value", "~" ) );
192 
193  if( fields.footprint.size() )
194  aNode->AddChild( node( "footprint", fields.footprint ) );
195 
196  if( fields.datasheet.size() )
197  aNode->AddChild( node( "datasheet", fields.datasheet ) );
198 
199  if( fields.f.size() )
200  {
201  XNODE* xfields;
202  aNode->AddChild( xfields = node( "fields" ) );
203 
204  // non MANDATORY fields are output alphabetically
205  for( std::map< wxString, wxString >::const_iterator it = fields.f.begin();
206  it != fields.f.end(); ++it )
207  {
208  XNODE* xfield;
209  xfields->AddChild( xfield = node( "field", it->second ) );
210  xfield->AddAttribute( "name", it->first );
211  }
212  }
213 }
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
SCH_FIELD instances are attached to a component and provide a place for the component's value,...
Definition: sch_field.h:51
SCH_SHEET_LIST GetSheets() const
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:97
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.
wxString GetShownText(int aDepth=0) const override
Return the string actually shown after processing of the base text.
Definition: sch_field.cpp:104
bool IsVoid() const
Function IsVoid returns true if the field is either empty or holds "~".
Definition: sch_field.cpp:321
name of datasheet
XNODE * node(const wxString &aName, const wxString &aTextualContent=wxEmptyString)
A convenience function that creates a new XNODE with an optional textual child.
const wxString GetFootprint(const SCH_SHEET_PATH *sheet, bool aResolve) const
SCHEMATIC * m_schematic
The schematic we're generating a netlist for.
int GetUnit() const
const wxString GetValue(const SCH_SHEET_PATH *sheet, bool aResolve) const
Holder for multi-unit component fields.
int GetFieldCount() const
Return the number of fields in this symbol.
Hold an XML or S-expression element.
Definition: xnode.h:43
SCH_FIELD * GetField(int aFieldNdx)
Returns a field in this symbol.
wxString GetName(bool aUseDefaultName=true) const
Function GetName returns the field name.
Definition: sch_field.cpp:505
Schematic symbol object.
Definition: sch_component.h:79
std::map< wxString, wxString > f
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:133
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const
Return the reference for the given sheet path.

References COMP_FIELDS::datasheet, DATASHEET_FIELD, COMP_FIELDS::f, COMP_FIELDS::footprint, SCH_COMPONENT::GetField(), SCH_COMPONENT::GetFieldCount(), SCH_COMPONENT::GetFootprint(), SCH_FIELD::GetName(), SCH_COMPONENT::GetRef(), SCHEMATIC::GetSheets(), SCH_FIELD::GetShownText(), EDA_TEXT::GetText(), SCH_COMPONENT::GetUnit(), SCH_COMPONENT::GetUnitCount(), SCH_COMPONENT::GetValue(), SCH_FIELD::IsVoid(), NETLIST_EXPORTER_XML::m_resolveTextVars, NETLIST_EXPORTER_BASE::m_schematic, MANDATORY_FIELDS, NETLIST_EXPORTER_XML::node(), SCH_COMPONENT_T, and COMP_FIELDS::value.

Referenced by NETLIST_EXPORTER_XML::makeSymbols().

◆ CreatePinList()

void NETLIST_EXPORTER_BASE::CreatePinList ( SCH_COMPONENT aSymbol,
SCH_SHEET_PATH aSheetPath 
)
protectedinherited

Function findNextSymbolAndCreatePinList finds a symbol from the DrawList and builds its pin list in m_sortedSymbolPinList.

This list is sorted by pin num. The symbol is the next actual symbol after aSymbol.

Power symbols and virtual symbols that have their reference designators starting with '#' are skipped.

Definition at line 122 of file netlist_exporter_base.cpp.

123 {
124  wxString ref( aSymbol->GetRef( aSheetPath ) );
125 
126  // Power symbols and other symbols which have the reference starting with "#" are not
127  // included in netlist (pseudo or virtual symbols)
128 
129  if( ref[0] == wxChar( '#' ) )
130  return;
131 
132  // if( aSymbol->m_FlagControlMulti == 1 )
133  // continue; /* yes */
134  // removed because with multiple instances of one schematic (several sheets pointing to
135  // 1 screen), this will be erroneously be toggled.
136 
137  if( !aSymbol->GetPartRef() )
138  return;
139 
140  m_sortedSymbolPinList.clear();
141 
142  // If symbol is a "multi parts per package" type
143  if( aSymbol->GetPartRef()->GetUnitCount() > 1 )
144  {
145  // Collect all pins for this reference designator by searching the entire design for
146  // other parts with the same reference designator.
147  // This is only done once, it would be too expensive otherwise.
148  findAllUnitsOfSymbol( aSymbol, aSymbol->GetPartRef().get(), aSheetPath );
149  }
150 
151  else // GetUnitCount() <= 1 means one part per package
152  {
154 
155  for( const SCH_PIN* pin : aSymbol->GetPins( aSheetPath ) )
156  {
157  if( SCH_CONNECTION* conn = pin->Connection( aSheetPath ) )
158  {
159  const wxString& netName = conn->Name();
160 
161  // Skip unconnected pins
162  CONNECTION_SUBGRAPH* sg = graph->FindSubgraphByName( netName, *aSheetPath );
163 
164  if( !sg || sg->m_no_connect || sg->m_items.size() < 2 )
165  continue;
166 
167  m_sortedSymbolPinList.emplace_back( pin->GetNumber(), netName );
168  }
169  }
170  }
171 
172  // Sort pins in m_SortedComponentPinList by pin number
174 
175  // Remove duplicate Pins in m_SortedComponentPinList
177 
178  // record the usage of this library component entry.
179  m_libParts.insert( aSymbol->GetPartRef().get() ); // rejects non-unique pointers
180 }
CONNECTION_SUBGRAPH * FindSubgraphByName(const wxString &aNetName, const SCH_SHEET_PATH &aPath)
Returns the subgraph for a given net name on a given sheet.
std::vector< PIN_INFO > m_sortedSymbolPinList
Used to temporarily store and filter the list of pins of a schematic symbol when generating schematic...
CONNECTION_GRAPH * ConnectionGraph() const
Definition: schematic.h:137
Calculates the connectivity of a schematic and generates netlists.
void eraseDuplicatePins()
Function eraseDuplicatePins erase duplicate Pins from m_sortedSymbolPinList (i.e.
static bool sortPinsByNum(PIN_INFO &aPin1, PIN_INFO &aPin2)
Comparison routine for sorting by pin numbers.
void findAllUnitsOfSymbol(SCH_COMPONENT *aSymbol, LIB_PART *aPart, SCH_SHEET_PATH *aSheetPath)
Function findAllUnitsOfSymbol is used for "multiple parts per package" symbols.
std::set< LIB_PART *, LIB_PART_LESS_THAN > m_libParts
unique library parts used. LIB_PART items are sorted by names
A subgraph is a set of items that are electrically connected on a single sheet.
SCHEMATIC * m_schematic
The schematic we're generating a netlist for.
std::vector< SCH_ITEM * > m_items
std::unique_ptr< LIB_PART > & GetPartRef()
std::vector< SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieves a list of the SCH_PINs for the given sheet path.
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
SCH_ITEM * m_no_connect
No-connect item in graph, if any.
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const
Return the reference for the given sheet path.

References SCHEMATIC::ConnectionGraph(), NETLIST_EXPORTER_BASE::eraseDuplicatePins(), NETLIST_EXPORTER_BASE::findAllUnitsOfSymbol(), CONNECTION_GRAPH::FindSubgraphByName(), SCH_COMPONENT::GetPartRef(), SCH_COMPONENT::GetPins(), SCH_COMPONENT::GetRef(), CONNECTION_SUBGRAPH::m_items, NETLIST_EXPORTER_BASE::m_libParts, CONNECTION_SUBGRAPH::m_no_connect, NETLIST_EXPORTER_BASE::m_schematic, NETLIST_EXPORTER_BASE::m_sortedSymbolPinList, and sortPinsByNum().

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

◆ eraseDuplicatePins()

void NETLIST_EXPORTER_BASE::eraseDuplicatePins ( )
protectedinherited

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

set pointer in this list to NULL). (This is a list of pins found in the whole schematic, for a single symbol.) These duplicate pins were put in list because some pins (power pins...) are found more than once when in "multiple parts per package" symbols. 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 183 of file netlist_exporter_base.cpp.

184 {
185  for( unsigned ii = 0; ii < m_sortedSymbolPinList.size(); ii++ )
186  {
187  if( m_sortedSymbolPinList[ii].num.empty() ) /* already deleted */
188  continue;
189 
190  /* Search for duplicated pins
191  * If found, remove duplicates. The priority is to keep connected pins
192  * and remove unconnected
193  * - So this allows (for instance when using multi op amps per package
194  * - to connect only one op amp to power
195  * Because the pin list is sorted by m_PinNum value, duplicated pins
196  * are necessary successive in list
197  */
198  int idxref = ii;
199 
200  for( unsigned jj = ii + 1; jj < m_sortedSymbolPinList.size(); jj++ )
201  {
202  if( m_sortedSymbolPinList[jj].num.empty() ) // Already removed
203  continue;
204 
205  // if other pin num, stop search,
206  // because all pins having the same number are consecutive in list.
207  if( m_sortedSymbolPinList[idxref].num != m_sortedSymbolPinList[jj].num )
208  break;
209 
210  m_sortedSymbolPinList[jj].num.clear();
211  }
212  }
213 }
std::vector< PIN_INFO > m_sortedSymbolPinList
Used to temporarily store and filter the list of pins of a schematic symbol when generating schematic...

References NETLIST_EXPORTER_BASE::m_sortedSymbolPinList.

Referenced by NETLIST_EXPORTER_BASE::CreatePinList().

◆ findAllUnitsOfSymbol()

void NETLIST_EXPORTER_BASE::findAllUnitsOfSymbol ( SCH_COMPONENT aSymbol,
LIB_PART aPart,
SCH_SHEET_PATH aSheetPath 
)
protectedinherited

Function findAllUnitsOfSymbol is used for "multiple parts per package" symbols.

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

Definition at line 216 of file netlist_exporter_base.cpp.

218 {
219  wxString ref = aSymbol->GetRef( aSheetPath );
220  wxString ref2;
221 
222  SCH_SHEET_LIST sheetList = m_schematic->GetSheets();
224 
225  for( unsigned i = 0; i < sheetList.size(); i++ )
226  {
227  for( SCH_ITEM* item : sheetList[i].LastScreen()->Items().OfType( SCH_COMPONENT_T ) )
228  {
229  SCH_COMPONENT* comp2 = static_cast<SCH_COMPONENT*>( item );
230 
231  ref2 = comp2->GetRef( &sheetList[i] );
232 
233  if( ref2.CmpNoCase( ref ) != 0 )
234  continue;
235 
236  for( const SCH_PIN* pin : comp2->GetPins( aSheetPath ) )
237  {
238  if( SCH_CONNECTION* conn = pin->Connection( aSheetPath ) )
239  {
240  const wxString& netName = conn->Name();
241 
242  // Skip unconnected pins
243  CONNECTION_SUBGRAPH* sg = graph->FindSubgraphByName( netName, *aSheetPath );
244 
245  if( !sg || sg->m_no_connect || sg->m_items.size() < 2 )
246  continue;
247 
248  m_sortedSymbolPinList.emplace_back( pin->GetNumber(), netName );
249  }
250  }
251  }
252  }
253 }
CONNECTION_SUBGRAPH * FindSubgraphByName(const wxString &aNetName, const SCH_SHEET_PATH &aPath)
Returns the subgraph for a given net name on a given sheet.
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
SCH_SHEET_LIST GetSheets() const
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:97
std::vector< PIN_INFO > m_sortedSymbolPinList
Used to temporarily store and filter the list of pins of a schematic symbol when generating schematic...
CONNECTION_GRAPH * ConnectionGraph() const
Definition: schematic.h:137
Calculates the connectivity of a schematic and generates netlists.
A subgraph is a set of items that are electrically connected on a single sheet.
SCHEMATIC * m_schematic
The schematic we're generating a netlist for.
std::vector< SCH_ITEM * > m_items
std::vector< SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieves a list of the SCH_PINs for the given sheet path.
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
Schematic symbol object.
Definition: sch_component.h:79
SCH_ITEM * m_no_connect
No-connect item in graph, if any.
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:194
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const
Return the reference for the given sheet path.

References SCHEMATIC::ConnectionGraph(), CONNECTION_GRAPH::FindSubgraphByName(), SCH_COMPONENT::GetPins(), SCH_COMPONENT::GetRef(), SCHEMATIC::GetSheets(), CONNECTION_SUBGRAPH::m_items, CONNECTION_SUBGRAPH::m_no_connect, NETLIST_EXPORTER_BASE::m_schematic, NETLIST_EXPORTER_BASE::m_sortedSymbolPinList, and SCH_COMPONENT_T.

Referenced by NETLIST_EXPORTER_BASE::CreatePinList().

◆ findNextSymbol()

SCH_COMPONENT * NETLIST_EXPORTER_BASE::findNextSymbol ( EDA_ITEM aItem,
SCH_SHEET_PATH aSheetPath 
)
protectedinherited

Checks if the given symbol should be processed for netlisting.

Prevents processing multi-unit symbols more than once, etc.

Parameters
aItemis a symbol to check
aSheetPathis the sheet to check the symbol for
Returns
the symbol if it should be processed, or nullptr

Definition at line 74 of file netlist_exporter_base.cpp.

75 {
76  wxString ref;
77 
78  if( aItem->Type() != SCH_COMPONENT_T )
79  return nullptr;
80 
81  // found next component
82  SCH_COMPONENT* symbol = (SCH_COMPONENT*) aItem;
83 
84  // Power symbols and other symbols which have the reference starting with "#" are not
85  // included in netlist (pseudo or virtual symbols)
86  ref = symbol->GetRef( aSheetPath );
87 
88  if( ref[0] == wxChar( '#' ) )
89  return nullptr;
90 
91  // if( symbol->m_FlagControlMulti == 1 )
92  // continue; /* yes */
93  // removed because with multiple instances of one schematic (several sheets pointing to
94  // 1 screen), this will be erroneously be toggled.
95 
96  if( !symbol->GetPartRef() )
97  return nullptr;
98 
99  // If component is a "multi parts per package" type
100  if( symbol->GetPartRef()->GetUnitCount() > 1 )
101  {
102  // test if this reference has already been processed, and if so skip
103  if( m_referencesAlreadyFound.Lookup( ref ) )
104  return nullptr;
105  }
106 
107  // record the usage of this library component entry.
108  m_libParts.insert( symbol->GetPartRef().get() ); // rejects non-unique pointers
109 
110  return symbol;
111 }
bool Lookup(const wxString &aString)
Function Lookup returns true if aString already exists in the set, otherwise returns false and adds a...
std::set< LIB_PART *, LIB_PART_LESS_THAN > m_libParts
unique library parts used. LIB_PART items are sorted by names
UNIQUE_STRINGS m_referencesAlreadyFound
Used for "multiple parts per package" symbols to avoid processing a lib part more than once.
std::unique_ptr< LIB_PART > & GetPartRef()
Schematic symbol object.
Definition: sch_component.h:79
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:161
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const
Return the reference for the given sheet path.

References SCH_COMPONENT::GetPartRef(), SCH_COMPONENT::GetRef(), UNIQUE_STRINGS::Lookup(), NETLIST_EXPORTER_BASE::m_libParts, NETLIST_EXPORTER_BASE::m_referencesAlreadyFound, SCH_COMPONENT_T, and EDA_ITEM::Type().

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

◆ Format()

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

Output 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 56 of file netlist_exporter_kicad.cpp.

57 {
58  std::unique_ptr<XNODE> xroot( makeRoot( aCtl ) );
59 
60  xroot->Format( aOut, 0 );
61 }
XNODE * makeRoot(unsigned aCtl=GNL_ALL)
Build the entire document tree for the generic export.

References NETLIST_EXPORTER_XML::makeRoot().

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

◆ MakeCommandLine()

wxString NETLIST_EXPORTER_BASE::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 38 of file netlist_exporter_base.cpp.

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

Referenced by SCH_EDIT_FRAME::WriteNetListFile().

◆ makeDesignHeader()

XNODE * NETLIST_EXPORTER_XML::makeDesignHeader ( )
protectedinherited

Fills out a project "design" header into an XML node.

Returns
XNODE* - the design header

Definition at line 334 of file netlist_exporter_xml.cpp.

335 {
336  SCH_SCREEN* screen;
337  XNODE* xdesign = node( "design" );
338  XNODE* xtitleBlock;
339  XNODE* xsheet;
340  XNODE* xcomment;
341  XNODE* xtextvar;
342  wxString sheetTxt;
343  wxFileName sourceFileName;
344 
345  // the root sheet is a special sheet, call it source
346  xdesign->AddChild( node( "source", m_schematic->GetFileName() ) );
347 
348  xdesign->AddChild( node( "date", DateAndTime() ) );
349 
350  // which Eeschema tool
351  xdesign->AddChild( node( "tool", wxString( "Eeschema " ) + GetBuildVersion() ) );
352 
353  const std::map<wxString, wxString>& properties = m_schematic->Prj().GetTextVars();
354 
355  for( const std::pair<const wxString, wxString>& prop : properties )
356  {
357  xdesign->AddChild( xtextvar = node( "textvar", prop.second ) );
358  xtextvar->AddAttribute( "name", prop.first );
359  }
360 
361  /*
362  * Export the sheets information
363  */
364  SCH_SHEET_LIST sheetList = m_schematic->GetSheets();
365 
366  for( unsigned i = 0; i < sheetList.size(); i++ )
367  {
368  screen = sheetList[i].LastScreen();
369 
370  xdesign->AddChild( xsheet = node( "sheet" ) );
371 
372  // get the string representation of the sheet index number.
373  // Note that sheet->GetIndex() is zero index base and we need to increment the
374  // number by one to make it human readable
375  sheetTxt.Printf( "%u", i + 1 );
376  xsheet->AddAttribute( "number", sheetTxt );
377  xsheet->AddAttribute( "name", sheetList[i].PathHumanReadable() );
378  xsheet->AddAttribute( "tstamps", sheetList[i].PathAsString() );
379 
380  TITLE_BLOCK tb = screen->GetTitleBlock();
381  PROJECT* prj = &m_schematic->Prj();
382 
383  xsheet->AddChild( xtitleBlock = node( "title_block" ) );
384 
385  xtitleBlock->AddChild( node( "title", ExpandTextVars( tb.GetTitle(), prj ) ) );
386  xtitleBlock->AddChild( node( "company", ExpandTextVars( tb.GetCompany(), prj ) ) );
387  xtitleBlock->AddChild( node( "rev", ExpandTextVars( tb.GetRevision(), prj ) ) );
388  xtitleBlock->AddChild( node( "date", ExpandTextVars( tb.GetDate(), prj ) ) );
389 
390  // We are going to remove the fileName directories.
391  sourceFileName = wxFileName( screen->GetFileName() );
392  xtitleBlock->AddChild( node( "source", sourceFileName.GetFullName() ) );
393 
394  xtitleBlock->AddChild( xcomment = node( "comment" ) );
395  xcomment->AddAttribute( "number", "1" );
396  xcomment->AddAttribute( "value", ExpandTextVars( tb.GetComment( 0 ), prj ) );
397 
398  xtitleBlock->AddChild( xcomment = node( "comment" ) );
399  xcomment->AddAttribute( "number", "2" );
400  xcomment->AddAttribute( "value", ExpandTextVars( tb.GetComment( 1 ), prj ) );
401 
402  xtitleBlock->AddChild( xcomment = node( "comment" ) );
403  xcomment->AddAttribute( "number", "3" );
404  xcomment->AddAttribute( "value", ExpandTextVars( tb.GetComment( 2 ), prj ) );
405 
406  xtitleBlock->AddChild( xcomment = node( "comment" ) );
407  xcomment->AddAttribute( "number", "4" );
408  xcomment->AddAttribute( "value", ExpandTextVars( tb.GetComment( 3 ), prj ) );
409 
410  xtitleBlock->AddChild( xcomment = node( "comment" ) );
411  xcomment->AddAttribute( "number", "5" );
412  xcomment->AddAttribute( "value", ExpandTextVars( tb.GetComment( 4 ), prj ) );
413 
414  xtitleBlock->AddChild( xcomment = node( "comment" ) );
415  xcomment->AddAttribute( "number", "6" );
416  xcomment->AddAttribute( "value", ExpandTextVars( tb.GetComment( 5 ), prj ) );
417 
418  xtitleBlock->AddChild( xcomment = node( "comment" ) );
419  xcomment->AddAttribute( "number", "7" );
420  xcomment->AddAttribute( "value", ExpandTextVars( tb.GetComment( 6 ), prj ) );
421 
422  xtitleBlock->AddChild( xcomment = node( "comment" ) );
423  xcomment->AddAttribute( "number", "8" );
424  xcomment->AddAttribute( "value", ExpandTextVars( tb.GetComment( 7 ), prj ) );
425 
426  xtitleBlock->AddChild( xcomment = node( "comment" ) );
427  xcomment->AddAttribute( "number", "9" );
428  xcomment->AddAttribute( "value", ExpandTextVars( tb.GetComment( 8 ), prj ) );
429  }
430 
431  return xdesign;
432 }
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
virtual std::map< wxString, wxString > & GetTextVars() const
const wxString & GetFileName() const
Definition: sch_screen.h:186
Container for project specific data.
Definition: project.h:62
SCH_SHEET_LIST GetSheets() const
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:97
wxString ExpandTextVars(const wxString &aSource, const PROJECT *aProject)
Definition: common.cpp:58
const wxString & GetComment(int aIdx) const
Definition: title_block.h:108
const TITLE_BLOCK & GetTitleBlock() const
Definition: sch_screen.h:191
wxString GetFileName() const
Helper to retrieve the filename from the root sheet screen.
Definition: schematic.cpp:119
Hold the information shown in the lower right corner of a plot, printout, or editing view.
Definition: title_block.h:40
XNODE * node(const wxString &aName, const wxString &aTextualContent=wxEmptyString)
A convenience function that creates a new XNODE with an optional textual child.
SCHEMATIC * m_schematic
The schematic we're generating a netlist for.
wxString GetBuildVersion()
Get the full KiCad version string.
const wxString & GetRevision() const
Definition: title_block.h:87
const wxString & GetCompany() const
Definition: title_block.h:97
Hold an XML or S-expression element.
Definition: xnode.h:43
const wxString & GetDate() const
Definition: title_block.h:77
PROJECT & Prj() const
Return a reference to the project this schematic is part of.
Definition: schematic.h:85
const wxString & GetTitle() const
Definition: title_block.h:64
wxString DateAndTime()
Definition: string.cpp:411

References DateAndTime(), ExpandTextVars(), GetBuildVersion(), TITLE_BLOCK::GetComment(), TITLE_BLOCK::GetCompany(), TITLE_BLOCK::GetDate(), SCHEMATIC::GetFileName(), SCH_SCREEN::GetFileName(), TITLE_BLOCK::GetRevision(), SCHEMATIC::GetSheets(), PROJECT::GetTextVars(), TITLE_BLOCK::GetTitle(), SCH_SCREEN::GetTitleBlock(), NETLIST_EXPORTER_BASE::m_schematic, NETLIST_EXPORTER_XML::node(), and SCHEMATIC::Prj().

Referenced by NETLIST_EXPORTER_XML::makeRoot().

◆ makeLibParts()

XNODE * NETLIST_EXPORTER_XML::makeLibParts ( )
protectedinherited

Fill out an XML node with the unique library parts and returns it.

Returns
XNODE* - the library parts nodes

Definition at line 459 of file netlist_exporter_xml.cpp.

460 {
461  XNODE* xlibparts = node( "libparts" ); // auto_ptr
462 
463  LIB_PINS pinList;
464  std::vector<LIB_FIELD*> fieldList;
465 
466  m_libraries.clear();
467 
468  for( auto lcomp : m_libParts )
469  {
470  wxString libNickname = lcomp->GetLibId().GetLibNickname();;
471 
472  // The library nickname will be empty if the cache library is used.
473  if( !libNickname.IsEmpty() )
474  m_libraries.insert( libNickname ); // inserts component's library if unique
475 
476  XNODE* xlibpart;
477  xlibparts->AddChild( xlibpart = node( "libpart" ) );
478  xlibpart->AddAttribute( "lib", libNickname );
479  xlibpart->AddAttribute( "part", lcomp->GetName() );
480 
481  //----- show the important properties -------------------------
482  if( !lcomp->GetDescription().IsEmpty() )
483  xlibpart->AddChild( node( "description", lcomp->GetDescription() ) );
484 
485  if( !lcomp->GetDatasheetField().GetText().IsEmpty() )
486  xlibpart->AddChild( node( "docs", lcomp->GetDatasheetField().GetText() ) );
487 
488  // Write the footprint list
489  if( lcomp->GetFPFilters().GetCount() )
490  {
491  XNODE* xfootprints;
492  xlibpart->AddChild( xfootprints = node( "footprints" ) );
493 
494  for( unsigned i = 0; i < lcomp->GetFPFilters().GetCount(); ++i )
495  xfootprints->AddChild( node( "fp", lcomp->GetFPFilters()[i] ) );
496  }
497 
498  //----- show the fields here ----------------------------------
499  fieldList.clear();
500  lcomp->GetFields( fieldList );
501 
502  XNODE* xfields;
503  xlibpart->AddChild( xfields = node( "fields" ) );
504 
505  for( const LIB_FIELD* field : fieldList )
506  {
507  if( !field->GetText().IsEmpty() )
508  {
509  XNODE* xfield;
510  xfields->AddChild( xfield = node( "field", field->GetText() ) );
511  xfield->AddAttribute( "name", field->GetCanonicalName() );
512  }
513  }
514 
515  //----- show the pins here ------------------------------------
516  pinList.clear();
517  lcomp->GetPins( pinList, 0, 0 );
518 
519  /* we must erase redundant Pins references in pinList
520  * These redundant pins exist because some pins
521  * are found more than one time when a component has
522  * multiple parts per package or has 2 representations (DeMorgan conversion)
523  * For instance, a 74ls00 has DeMorgan conversion, with different pin shapes,
524  * and therefore each pin appears 2 times in the list.
525  * Common pins (VCC, GND) can also be found more than once.
526  */
527  sort( pinList.begin(), pinList.end(), sortPinsByNumber );
528  for( int ii = 0; ii < (int)pinList.size()-1; ii++ )
529  {
530  if( pinList[ii]->GetNumber() == pinList[ii+1]->GetNumber() )
531  { // 2 pins have the same number, remove the redundant pin at index i+1
532  pinList.erase(pinList.begin() + ii + 1);
533  ii--;
534  }
535  }
536 
537  if( pinList.size() )
538  {
539  XNODE* pins;
540 
541  xlibpart->AddChild( pins = node( "pins" ) );
542  for( unsigned i=0; i<pinList.size(); ++i )
543  {
544  XNODE* pin;
545 
546  pins->AddChild( pin = node( "pin" ) );
547  pin->AddAttribute( "num", pinList[i]->GetNumber() );
548  pin->AddAttribute( "name", pinList[i]->GetName() );
549  pin->AddAttribute( "type", pinList[i]->GetCanonicalElectricalTypeName() );
550 
551  // caution: construction work site here, drive slowly
552  }
553  }
554  }
555 
556  return xlibparts;
557 }
std::vector< LIB_PIN * > LIB_PINS
Helper for defining a list of pin object pointers.
Definition: lib_item.h:56
Field object used in symbol libraries.
Definition: lib_field.h:59
std::set< LIB_PART *, LIB_PART_LESS_THAN > m_libParts
unique library parts used. LIB_PART items are sorted by names
XNODE * node(const wxString &aName, const wxString &aTextualContent=wxEmptyString)
A convenience function that creates a new XNODE with an optional textual child.
static bool sortPinsByNumber(LIB_PIN *aPin1, LIB_PIN *aPin2)
Hold an XML or S-expression element.
Definition: xnode.h:43
std::set< wxString > m_libraries

References NETLIST_EXPORTER_BASE::m_libParts, NETLIST_EXPORTER_XML::m_libraries, NETLIST_EXPORTER_XML::node(), and sortPinsByNumber().

Referenced by NETLIST_EXPORTER_XML::makeRoot().

◆ makeLibraries()

XNODE * NETLIST_EXPORTER_XML::makeLibraries ( )
protectedinherited

Fill 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 435 of file netlist_exporter_xml.cpp.

436 {
437  XNODE* xlibs = node( "libraries" ); // auto_ptr
438  SYMBOL_LIB_TABLE* symbolLibTable = m_schematic->Prj().SchSymbolLibTable();
439 
440  for( std::set<wxString>::iterator it = m_libraries.begin(); it!=m_libraries.end(); ++it )
441  {
442  wxString libNickname = *it;
443  XNODE* xlibrary;
444 
445  if( symbolLibTable->HasLibrary( libNickname ) )
446  {
447  xlibs->AddChild( xlibrary = node( "library" ) );
448  xlibrary->AddAttribute( "logical", libNickname );
449  xlibrary->AddChild( node( "uri", symbolLibTable->GetFullURI( libNickname ) ) );
450  }
451 
452  // @todo: add more fun stuff here
453  }
454 
455  return xlibs;
456 }
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)
A convenience function that creates a new XNODE with an optional textual child.
SCHEMATIC * m_schematic
The schematic we're generating a netlist for.
wxString GetFullURI(const wxString &aLibNickname, bool aExpandEnvVars=true) const
Return the full URI of the library mapped to aLibNickname.
Hold an XML or S-expression element.
Definition: xnode.h:43
std::set< wxString > m_libraries
PROJECT & Prj() const
Return a reference to the project this schematic is part of.
Definition: schematic.h:85

References LIB_TABLE::GetFullURI(), LIB_TABLE::HasLibrary(), NETLIST_EXPORTER_XML::m_libraries, NETLIST_EXPORTER_BASE::m_schematic, NETLIST_EXPORTER_XML::node(), and SCHEMATIC::Prj().

Referenced by NETLIST_EXPORTER_XML::makeRoot().

◆ makeListOfNets()

XNODE * NETLIST_EXPORTER_XML::makeListOfNets ( unsigned  aCtl)
protectedinherited

Fill out an XML node with a list of nets and returns it.

Returns
XNODE* - the list of nets nodes

Definition at line 563 of file netlist_exporter_xml.cpp.

564 {
565  XNODE* xnets = node( "nets" ); // auto_ptr if exceptions ever get used.
566  wxString netCodeTxt;
567  wxString netName;
568  wxString ref;
569 
570  XNODE* xnet = nullptr;
571 
572  /* output:
573  <net code="123" name="/cfcard.sch/WAIT#">
574  <node ref="R23" pin="1"/>
575  <node ref="U18" pin="12"/>
576  </net>
577  */
578 
579  typedef std::pair<SCH_PIN*, SCH_SHEET_PATH> MEMBER_RECORD;
580  typedef std::pair<wxString, std::vector<MEMBER_RECORD>> NET_RECORD;
581  std::vector<NET_RECORD*> nets;
582 
583  for( const auto& it : m_schematic->ConnectionGraph()->GetNetMap() )
584  {
585  wxString net_name = it.first.first;
586  auto subgraphs = it.second;
587  NET_RECORD* net_record;
588 
589  if( subgraphs.empty() )
590  continue;
591 
592  nets.push_back( new NET_RECORD( net_name, std::vector<MEMBER_RECORD>() ) );
593  net_record = nets.back();
594 
595  for( CONNECTION_SUBGRAPH* subgraph : subgraphs )
596  {
597  const SCH_SHEET_PATH& sheet = subgraph->m_sheet;
598 
599  for( SCH_ITEM* item : subgraph->m_items )
600  {
601  if( item->Type() == SCH_PIN_T )
602  {
603  SCH_PIN* pin = static_cast<SCH_PIN*>( item );
604  SCH_COMPONENT* symbol = pin->GetParentSymbol();
605 
606  if( !symbol
607  || ( ( aCtl & GNL_OPT_BOM ) && !symbol->GetIncludeInBom() )
608  || ( ( aCtl & GNL_OPT_KICAD ) && !symbol->GetIncludeOnBoard() ) )
609  {
610  continue;
611  }
612 
613  net_record->second.emplace_back( pin, sheet );
614  }
615  }
616  }
617  }
618 
619  // Netlist ordering: Net name, then ref des, then pin name
620  std::sort( nets.begin(), nets.end(),
621  []( const NET_RECORD* a, const NET_RECORD*b )
622  {
623  return StrNumCmp( a->first, b->first ) < 0;
624  } );
625 
626  for( int i = 0; i < (int) nets.size(); ++i )
627  {
628  NET_RECORD* net_record = nets[i];
629  bool added = false;
630  XNODE* xnode;
631 
632  // Netlist ordering: Net name, then ref des, then pin name
633  std::sort( net_record->second.begin(), net_record->second.end(),
634  []( const std::pair<SCH_PIN*, SCH_SHEET_PATH>& a,
635  const std::pair<SCH_PIN*, SCH_SHEET_PATH>& b )
636  {
637  SCH_PIN* pinA = a.first;
638  SCH_PIN* pinB = b.first;
639  wxString refA = pinA->GetParentSymbol()->GetRef( &a.second );
640  wxString refB = pinB->GetParentSymbol()->GetRef( &b.second );
641 
642  if( refA == refB )
643  return pinA->GetNumber() < pinB->GetNumber();
644 
645  return refA < refB;
646  } );
647 
648  // Some duplicates can exist, for example on multi-unit parts with duplicated
649  // pins across units. If the user connects the pins on each unit, they will
650  // appear on separate subgraphs. Remove those here:
651  net_record->second.erase(
652  std::unique( net_record->second.begin(), net_record->second.end(),
653  []( const std::pair<SCH_PIN*, SCH_SHEET_PATH>& a,
654  const std::pair<SCH_PIN*, SCH_SHEET_PATH>& b )
655  {
656  SCH_PIN* pinA = a.first;
657  SCH_PIN* pinB = b.first;
658  wxString refA = pinA->GetParentSymbol()->GetRef( &a.second );
659  wxString refB = pinB->GetParentSymbol()->GetRef( &b.second );
660 
661  return refA == refB && pinA->GetNumber() == pinB->GetNumber();
662  } ),
663  net_record->second.end() );
664 
665  for( const std::pair<SCH_PIN*, SCH_SHEET_PATH>& pair : net_record->second )
666  {
667  SCH_PIN* pin = pair.first;
668  SCH_SHEET_PATH sheet = pair.second;
669 
670  wxString refText = pin->GetParentSymbol()->GetRef( &sheet );
671  wxString pinText = pin->GetNumber();
672 
673  // Skip power symbols and virtual components
674  if( refText[0] == wxChar( '#' ) )
675  continue;
676 
677  if( !added )
678  {
679  netCodeTxt.Printf( "%d", i + 1 );
680 
681  if( net_record->first == "no_connect_" )
682  net_record->first += netCodeTxt;
683 
684  xnets->AddChild( xnet = node( "net" ) );
685  xnet->AddAttribute( "code", netCodeTxt );
686  xnet->AddAttribute( "name", net_record->first );
687 
688  added = true;
689  }
690 
691  xnet->AddChild( xnode = node( "node" ) );
692  xnode->AddAttribute( "ref", refText );
693  xnode->AddAttribute( "pin", pinText );
694 
695  wxString pinName;
696 
697  if( pin->GetName() != "~" ) // ~ is a char used to code empty strings in libs.
698  pinName = pin->GetName();
699 
700  if( !pinName.IsEmpty() )
701  xnode->AddAttribute( "pinfunction", pinName );
702  }
703  }
704 
705  for( NET_RECORD* record : nets )
706  delete record;
707 
708  return xnets;
709 }
int StrNumCmp(const wxString &aString1, const wxString &aString2, bool aIgnoreCase)
Compare two strings with alphanumerical content.
Definition: string.cpp:420
CONNECTION_GRAPH * ConnectionGraph() const
Definition: schematic.h:137
bool GetIncludeOnBoard() const
SCH_COMPONENT * GetParentSymbol() const
Definition: sch_pin.cpp:141
wxString GetNumber() const
Definition: sch_pin.h:116
A subgraph is a set of items that are electrically connected on a single sheet.
XNODE * node(const wxString &aName, const wxString &aTextualContent=wxEmptyString)
A convenience function that creates a new XNODE with an optional textual child.
SCHEMATIC * m_schematic
The schematic we're generating a netlist for.
const NET_MAP & GetNetMap() const
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
bool GetIncludeInBom() const
Hold an XML or S-expression element.
Definition: xnode.h:43
Schematic symbol object.
Definition: sch_component.h:79
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:194
wxString GetName() const
Definition: sch_pin.cpp:79
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:161
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const
Return the reference for the given sheet path.

References SCHEMATIC::ConnectionGraph(), SCH_COMPONENT::GetIncludeInBom(), SCH_COMPONENT::GetIncludeOnBoard(), SCH_PIN::GetName(), CONNECTION_GRAPH::GetNetMap(), SCH_PIN::GetNumber(), SCH_PIN::GetParentSymbol(), SCH_COMPONENT::GetRef(), GNL_OPT_BOM, GNL_OPT_KICAD, NETLIST_EXPORTER_BASE::m_schematic, NETLIST_EXPORTER_XML::node(), SCH_PIN_T, StrNumCmp(), and EDA_ITEM::Type().

Referenced by NETLIST_EXPORTER_XML::makeRoot().

◆ makeRoot()

XNODE * NETLIST_EXPORTER_XML::makeRoot ( unsigned  aCtl = GNL_ALL)
protectedinherited

Build 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 51 of file netlist_exporter_xml.cpp.

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

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

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

◆ makeSymbols()

XNODE * NETLIST_EXPORTER_XML::makeSymbols ( unsigned  aCtl)
protectedinherited
Returns
XNODE* - returns a sub-tree holding all the schematic components.

Definition at line 216 of file netlist_exporter_xml.cpp.

217 {
218  XNODE* xcomps = node( "components" );
219 
221  m_libParts.clear();
222 
223  SCH_SHEET_LIST sheetList = m_schematic->GetSheets();
224 
225  // Output is xml, so there is no reason to remove spaces from the field values.
226  // And XML element names need not be translated to various languages.
227 
228  for( unsigned ii = 0; ii < sheetList.size(); ii++ )
229  {
230  SCH_SHEET_PATH sheet = sheetList[ii];
231  m_schematic->SetCurrentSheet( sheet );
232 
233  auto cmp = [sheet]( SCH_COMPONENT* a, SCH_COMPONENT* b )
234  {
235  return ( UTIL::RefDesStringCompare( a->GetRef( &sheet ),
236  b->GetRef( &sheet ) ) < 0 );
237  };
238 
239  std::set<SCH_COMPONENT*, decltype( cmp )> ordered_symbols( cmp );
240 
241  for( SCH_ITEM* item : sheet.LastScreen()->Items().OfType( SCH_COMPONENT_T ) )
242  {
243  SCH_COMPONENT* symbol = static_cast<SCH_COMPONENT*>( item );
244  auto test = ordered_symbols.insert( symbol );
245 
246  if( !test.second )
247  {
248  if( ( *( test.first ) )->GetUnit() > symbol->GetUnit() )
249  {
250  ordered_symbols.erase( test.first );
251  ordered_symbols.insert( symbol );
252  }
253  }
254  }
255 
256  for( EDA_ITEM* item : ordered_symbols )
257  {
258  SCH_COMPONENT* symbol = findNextSymbol( item, &sheet );
259 
260  if( !symbol
261  || ( ( aCtl & GNL_OPT_BOM ) && !symbol->GetIncludeInBom() )
262  || ( ( aCtl & GNL_OPT_KICAD ) && !symbol->GetIncludeOnBoard() ) )
263  {
264  continue;
265  }
266 
267  // Output the symbol's elements in order of expected access frequency. This may
268  // not always look best, but it will allow faster execution under XSL processing
269  // systems which do sequential searching within an element.
270 
271  XNODE* xcomp; // current component being constructed
272  xcomps->AddChild( xcomp = node( "comp" ) );
273 
274  xcomp->AddAttribute( "ref", symbol->GetRef( &sheet ) );
275  addSymbolFields( xcomp, symbol, &sheetList[ ii ] );
276 
277  XNODE* xlibsource;
278  xcomp->AddChild( xlibsource = node( "libsource" ) );
279 
280  // "logical" library name, which is in anticipation of a better search algorithm
281  // for parts based on "logical_lib.part" and where logical_lib is merely the library
282  // name minus path and extension.
283  if( symbol->GetPartRef() )
284  xlibsource->AddAttribute( "lib", symbol->GetPartRef()->GetLibId().GetLibNickname() );
285 
286  // We only want the symbol name, not the full LIB_ID.
287  xlibsource->AddAttribute( "part", symbol->GetLibId().GetLibItemName() );
288 
289  xlibsource->AddAttribute( "description", symbol->GetDescription() );
290 
291  XNODE* xproperty;
292 
293  std::vector<SCH_FIELD>& fields = symbol->GetFields();
294 
295  for( size_t jj = MANDATORY_FIELDS; jj < fields.size(); ++jj )
296  {
297  xcomp->AddChild( xproperty = node( "property" ) );
298  xproperty->AddAttribute( "name", fields[jj].GetName() );
299  xproperty->AddAttribute( "value", fields[jj].GetText() );
300  }
301 
302  for( const SCH_FIELD& sheetField : sheet.Last()->GetFields() )
303  {
304  xcomp->AddChild( xproperty = node( "property" ) );
305  xproperty->AddAttribute( "name", sheetField.GetName() );
306  xproperty->AddAttribute( "value", sheetField.GetText() );
307  }
308 
309  if( !symbol->GetIncludeInBom() )
310  {
311  xcomp->AddChild( xproperty = node( "property" ) );
312  xproperty->AddAttribute( "name", "exclude_from_bom" );
313  }
314 
315  if( !symbol->GetIncludeOnBoard() )
316  {
317  xcomp->AddChild( xproperty = node( "property" ) );
318  xproperty->AddAttribute( "name", "exclude_from_board" );
319  }
320 
321  XNODE* xsheetpath;
322  xcomp->AddChild( xsheetpath = node( "sheetpath" ) );
323 
324  xsheetpath->AddAttribute( "names", sheet.PathHumanReadable() );
325  xsheetpath->AddAttribute( "tstamps", sheet.PathAsString() );
326  xcomp->AddChild( node( "tstamp", symbol->m_Uuid.AsString() ) );
327  }
328  }
329 
330  return xcomps;
331 }
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
EE_TYPE OfType(KICAD_T aType) const
Definition: sch_rtree.h:219
SCH_FIELD instances are attached to a component and provide a place for the component's value,...
Definition: sch_field.h:51
const UTF8 & GetLibItemName() const
Definition: lib_id.h:106
SCH_SHEET_LIST GetSheets() const
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:97
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
bool GetIncludeOnBoard() const
wxString PathHumanReadable(bool aUseShortRootName=true) const
Return the sheet path in a human readable form made from thesheet names.
The first 4 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors.
wxString AsString() const
Definition: kiid.cpp:213
wxString PathAsString() const
Return the path of time stamps which do not changes even when editing sheet parameters.
wxString GetDescription() const
Return information about the aliased parts.
void Clear()
Function Clear erases the record.
std::set< LIB_PART *, LIB_PART_LESS_THAN > m_libParts
unique library parts used. LIB_PART items are sorted by names
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly)
Populates a std::vector with SCH_FIELDs.
XNODE * node(const wxString &aName, const wxString &aTextualContent=wxEmptyString)
A convenience function that creates a new XNODE with an optional textual child.
UNIQUE_STRINGS m_referencesAlreadyFound
Used for "multiple parts per package" symbols to avoid processing a lib part more than once.
int RefDesStringCompare(const wxString &aFirst, const wxString &aSecond)
Acts just like the strcmp function but treats numbers within the string text correctly for sorting.
std::vector< SCH_FIELD > & GetFields()
Definition: sch_sheet.h:270
SCHEMATIC * m_schematic
The schematic we're generating a netlist for.
int GetUnit() const
SCH_COMPONENT * findNextSymbol(EDA_ITEM *aItem, SCH_SHEET_PATH *aSheetPath)
Checks if the given symbol should be processed for netlisting.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
std::unique_ptr< LIB_PART > & GetPartRef()
bool GetIncludeInBom() const
const KIID m_Uuid
Definition: eda_item.h:523
Hold an XML or S-expression element.
Definition: xnode.h:43
SCH_SCREEN * LastScreen()
void addSymbolFields(XNODE *aNode, SCH_COMPONENT *aSymbol, SCH_SHEET_PATH *aSheet)
EE_RTREE & Items()
Definition: sch_screen.h:159
Schematic symbol object.
Definition: sch_component.h:79
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:148
void SetCurrentSheet(const SCH_SHEET_PATH &aPath)
Definition: schematic.h:132
const LIB_ID & GetLibId() const
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:194
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const
Return the reference for the given sheet path.

References NETLIST_EXPORTER_XML::addSymbolFields(), KIID::AsString(), UNIQUE_STRINGS::Clear(), NETLIST_EXPORTER_BASE::findNextSymbol(), SCH_COMPONENT::GetDescription(), SCH_SHEET::GetFields(), SCH_COMPONENT::GetFields(), SCH_COMPONENT::GetIncludeInBom(), SCH_COMPONENT::GetIncludeOnBoard(), SCH_COMPONENT::GetLibId(), LIB_ID::GetLibItemName(), SCH_COMPONENT::GetPartRef(), SCH_COMPONENT::GetRef(), SCHEMATIC::GetSheets(), SCH_COMPONENT::GetUnit(), GNL_OPT_BOM, GNL_OPT_KICAD, SCH_SCREEN::Items(), SCH_SHEET_PATH::Last(), SCH_SHEET_PATH::LastScreen(), NETLIST_EXPORTER_BASE::m_libParts, NETLIST_EXPORTER_BASE::m_referencesAlreadyFound, NETLIST_EXPORTER_BASE::m_schematic, EDA_ITEM::m_Uuid, MANDATORY_FIELDS, NETLIST_EXPORTER_XML::node(), EE_RTREE::OfType(), SCH_SHEET_PATH::PathAsString(), SCH_SHEET_PATH::PathHumanReadable(), UTIL::RefDesStringCompare(), SCH_COMPONENT_T, and SCHEMATIC::SetCurrentSheet().

Referenced by NETLIST_EXPORTER_XML::makeRoot().

◆ node()

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

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 712 of file netlist_exporter_xml.cpp.

714 {
715  XNODE* n = new XNODE( wxXML_ELEMENT_NODE, aName );
716 
717  if( aTextualContent.Len() > 0 ) // excludes wxEmptyString, the parameter's default value
718  n->AddChild( new XNODE( wxXML_TEXT_NODE, wxEmptyString, aTextualContent ) );
719 
720  return n;
721 }
Hold an XML or S-expression element.
Definition: xnode.h:43

Referenced by NETLIST_EXPORTER_XML::addSymbolFields(), NETLIST_EXPORTER_XML::makeDesignHeader(), NETLIST_EXPORTER_XML::makeLibParts(), NETLIST_EXPORTER_XML::makeLibraries(), NETLIST_EXPORTER_XML::makeListOfNets(), NETLIST_EXPORTER_XML::makeRoot(), and NETLIST_EXPORTER_XML::makeSymbols().

◆ WriteNetlist()

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

Write netlist to aOutFileName.

Generate the KiCad netlist format supported by Pcbnew.

It is basically the XML netlist just formatted slightly different.

Reimplemented from NETLIST_EXPORTER_BASE.

Definition at line 38 of file netlist_exporter_kicad.cpp.

39 {
40  try
41  {
42  FILE_OUTPUTFORMATTER formatter( aOutFileName );
43  Format( &formatter, GNL_ALL | GNL_OPT_KICAD );
44  }
45 
46  catch( const IO_ERROR& ioe )
47  {
48  DisplayError( NULL, ioe.What() );
49  return false;
50  }
51 
52  return true;
53 }
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:253
void Format(OUTPUTFORMATTER *aOutputFormatter, int aCtl)
Output this s-expression netlist into aOutputFormatter.
#define NULL
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:29
#define GNL_ALL
Used for text file output.
Definition: richio.h:453
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:75

References DisplayError(), Format(), GNL_ALL, GNL_OPT_KICAD, NULL, and IO_ERROR::What().

Member Data Documentation

◆ m_libParts

std::set<LIB_PART*, LIB_PART_LESS_THAN> NETLIST_EXPORTER_BASE::m_libParts
protectedinherited

◆ m_referencesAlreadyFound

UNIQUE_STRINGS NETLIST_EXPORTER_BASE::m_referencesAlreadyFound
protectedinherited

Used for "multiple parts per package" symbols to avoid processing a lib part more than once.

Definition at line 106 of file netlist_exporter_base.h.

Referenced by NETLIST_EXPORTER_BASE::findNextSymbol(), NETLIST_EXPORTER_XML::makeSymbols(), NETLIST_EXPORTER_PSPICE::ProcessNetlist(), NETLIST_EXPORTER_ORCADPCB2::WriteNetlist(), and NETLIST_EXPORTER_CADSTAR::WriteNetlist().

◆ m_resolveTextVars

bool NETLIST_EXPORTER_XML::m_resolveTextVars
protectedinherited

◆ m_savedCurrentSheet

SCH_SHEET_PATH NETLIST_EXPORTER_BASE::m_savedCurrentSheet
protectedinherited

The schematic's CurrentSheet when we entered. Restore on exiting.

Definition at line 115 of file netlist_exporter_base.h.

Referenced by NETLIST_EXPORTER_BASE::NETLIST_EXPORTER_BASE(), and NETLIST_EXPORTER_BASE::~NETLIST_EXPORTER_BASE().

◆ m_schematic

◆ m_sortedSymbolPinList

std::vector<PIN_INFO> NETLIST_EXPORTER_BASE::m_sortedSymbolPinList
protectedinherited

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

No ownership of members. TODO(snh): Descope this object

Definition at line 102 of file netlist_exporter_base.h.

Referenced by NETLIST_EXPORTER_BASE::CreatePinList(), NETLIST_EXPORTER_BASE::eraseDuplicatePins(), NETLIST_EXPORTER_BASE::findAllUnitsOfSymbol(), NETLIST_EXPORTER_PSPICE::ProcessNetlist(), and NETLIST_EXPORTER_ORCADPCB2::WriteNetlist().


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