KiCad PCB EDA Suite
KICAD_NETLIST_PARSER Class Reference

Class KICAD_NETLIST_PARSER is the parser for reading the KiCad s-expression netlist format. More...

#include <netlist_reader.h>

Inheritance diagram for KICAD_NETLIST_PARSER:

Public Member Functions

 KICAD_NETLIST_PARSER (LINE_READER *aReader, NETLIST *aNetlist)
 
void SetLineReader (LINE_READER *aLineReader)
 
void SetNetlist (NETLIST *aNetlist)
 
void Parse ()
 Function Parse parse the full netlist. More...
 
const char * getTokenName (NL_T::T aTok)
 

Private Member Functions

void skipCurrent ()
 Function skipCurrent Skip the current token level, i.e search for the RIGHT parenthesis which closes the current description. More...
 
void parseComponent ()
 Function parseComponent parse a component description: (comp (ref P1) (value DB25FEMELLE) (footprint DB25FC) (libsource (lib conn) (part DB25)) (sheetpath (names /) (tstamps /)) (tstamp 3256759C)) More...
 
void parseNet ()
 Function parseNet Parses a section like (net (code 20) (name /PC-A0) (node (ref BUS1) (pin 62)) (node (ref U3) (pin 3)) (node (ref U9) (pin M6))) More...
 
void parseLibPartList ()
 Function parseLibPartList reads the section "libparts" in the netlist: (libparts (libpart (lib device) (part C) (description "Condensateur non polarise") (footprints (fp SM*) (fp C?) (fp C1-1)) (fields (field (name Reference) C) (field (name Value) C)) (pins (pin (num 1) (name ~) (type passive)) (pin (num 2) (name ~) (type passive)))) More...
 

Private Attributes

NL_T::T token
 
LINE_READERm_lineReader
 The line reader used to parse the netlist. Not owned. More...
 
NETLISTm_netlist
 The netlist to parse into. Not owned. More...
 

Detailed Description

Class KICAD_NETLIST_PARSER is the parser for reading the KiCad s-expression netlist format.

Definition at line 294 of file netlist_reader.h.

Constructor & Destructor Documentation

KICAD_NETLIST_PARSER::KICAD_NETLIST_PARSER ( LINE_READER aReader,
NETLIST aNetlist 
)

Definition at line 55 of file kicad_netlist_reader.cpp.

References m_lineReader, m_netlist, and token.

55  :
56  NETLIST_LEXER( aReader )
57 {
58  m_lineReader = aReader;
59  m_netlist = aNetlist;
60  token = T_NONE;
61 }
NETLIST * m_netlist
The netlist to parse into. Not owned.
LINE_READER * m_lineReader
The line reader used to parse the netlist. Not owned.

Member Function Documentation

const char* KICAD_NETLIST_PARSER::getTokenName ( NL_T::T  aTok)
inline

Definition at line 371 of file netlist_reader.h.

372  {
373  return NETLIST_LEXER::TokenName( aTok );
374  }
void KICAD_NETLIST_PARSER::Parse ( )

Function Parse parse the full netlist.

Definition at line 84 of file kicad_netlist_reader.cpp.

References parseComponent(), parseLibPartList(), parseNet(), skipCurrent(), and token.

85 {
86  int plevel = 0; // the count of ')' to read and end of file,
87  // after parsing all sections
88 
89  while( ( token = NextTok() ) != T_EOF )
90  {
91  if( token == T_LEFT )
92  token = NextTok();
93 
94  switch( token )
95  {
96  case T_export: // The netlist starts here.
97  // nothing to do here,
98  // just increment the count of ')' to read and end of file
99  plevel++;
100  break;
101 
102  case T_version: // The netlist starts here.
103  // version id not yet used: read it but does not use it
104  NextTok();
105  NeedRIGHT();
106  break;
107 
108  case T_components: // The section comp starts here.
109  while( ( token = NextTok() ) != T_RIGHT )
110  {
111  if( token == T_LEFT )
112  token = NextTok();
113 
114  if( token == T_comp ) // A component section found. Read it
115  parseComponent();
116  }
117 
118  break;
119 
120  case T_nets: // The section nets starts here.
121  while( ( token = NextTok() ) != T_RIGHT )
122  {
123  if( token == T_LEFT )
124  token = NextTok();
125 
126  if( token == T_net )
127  {
128  // A net section if found. Read it
129  parseNet();
130  }
131  }
132 
133  break;
134 
135  case T_libparts: // The section libparts starts here.
136  while( ( token = NextTok() ) != T_RIGHT )
137  {
138  if( token == T_LEFT )
139  token = NextTok();
140 
141  if( token == T_libpart )
142  {
143  // A libpart section if found. Read it
145  }
146  }
147 
148  break;
149 
150  case T_libraries: // The section libraries starts here.
151  // List of libraries in use.
152  // Not used here, just skip it
153  skipCurrent();
154  break;
155 
156  case T_design: // The section design starts here.
157  // Not used (mainly they are comments), just skip it
158  skipCurrent();
159  break;
160 
161  case T_RIGHT: // The closing parenthesis of the file.
162  // Not used (mainly they are comments), just skip it
163  plevel--;
164  break;
165 
166  default:
167  skipCurrent();
168  break;
169  }
170  }
171 
172  if( plevel != 0 )
173  {
174  wxLogDebug( wxT( "KICAD_NETLIST_PARSER::Parse(): bad parenthesis count (count = %d"),
175  plevel );
176  }
177 }
void parseComponent()
Function parseComponent parse a component description: (comp (ref P1) (value DB25FEMELLE) (footprint ...
void skipCurrent()
Function skipCurrent Skip the current token level, i.e search for the RIGHT parenthesis which closes ...
void parseLibPartList()
Function parseLibPartList reads the section "libparts" in the netlist: (libparts (libpart (lib device...
void parseNet()
Function parseNet Parses a section like (net (code 20) (name /PC-A0) (node (ref BUS1) (pin 62)) (node...
void KICAD_NETLIST_PARSER::parseComponent ( )
private

Function parseComponent parse a component description: (comp (ref P1) (value DB25FEMELLE) (footprint DB25FC) (libsource (lib conn) (part DB25)) (sheetpath (names /) (tstamps /)) (tstamp 3256759C))

Definition at line 271 of file kicad_netlist_reader.cpp.

References NETLIST::AddComponent(), FROM_UTF8(), GetChars(), m_netlist, name, LIB_ID::Parse(), COMPONENT::SetLibrary(), COMPONENT::SetName(), skipCurrent(), THROW_IO_ERROR, and token.

Referenced by Parse().

272 {
273  /* Parses a section like
274  * (comp (ref P1)
275  * (value DB25FEMELLE)
276  * (footprint DB25FC)
277  * (libsource (lib conn) (part DB25))
278  * (sheetpath (names /) (tstamps /))
279  * (tstamp 3256759C))
280  *
281  * other fields (unused) are skipped
282  * A component need a reference, value, footprint name and a full time stamp
283  * The full time stamp is the sheetpath time stamp + the component time stamp
284  */
285  LIB_ID fpid;
286  wxString footprint;
287  wxString ref;
288  wxString value;
289  wxString library;
290  wxString name;
291  wxString pathtimestamp, timestamp;
292 
293  // The token comp was read, so the next data is (ref P1)
294  while( (token = NextTok()) != T_RIGHT )
295  {
296  if( token == T_LEFT )
297  token = NextTok();
298 
299  switch( token )
300  {
301  case T_ref:
302  NeedSYMBOLorNUMBER();
303  ref = FROM_UTF8( CurText() );
304  NeedRIGHT();
305  break;
306 
307  case T_value:
308  NeedSYMBOLorNUMBER();
309  value = FROM_UTF8( CurText() );
310  NeedRIGHT();
311  break;
312 
313  case T_footprint:
314  NeedSYMBOLorNUMBER();
315  footprint = FromUTF8();
316  NeedRIGHT();
317  break;
318 
319  case T_libsource:
320  // Read libsource
321  while( (token = NextTok()) != T_RIGHT )
322  {
323  if( token == T_LEFT )
324  token = NextTok();
325 
326  if( token == T_lib )
327  {
328  NeedSYMBOLorNUMBER();
329  library = FROM_UTF8( CurText() );
330  NeedRIGHT();
331  }
332  else if( token == T_part )
333  {
334  NeedSYMBOLorNUMBER();
335  name = FROM_UTF8( CurText() );
336  NeedRIGHT();
337  }
338  else
339  {
340  Expecting( "part or lib" );
341  }
342  }
343  break;
344 
345  case T_sheetpath:
346  while( ( token = NextTok() ) != T_tstamps );
347  NeedSYMBOLorNUMBER();
348  pathtimestamp = FROM_UTF8( CurText() );
349  NeedRIGHT();
350  NeedRIGHT();
351  break;
352 
353  case T_tstamp:
354  NeedSYMBOLorNUMBER();
355  timestamp = FROM_UTF8( CurText() );
356  NeedRIGHT();
357  break;
358 
359  default:
360  // Skip not used data (i.e all other tokens)
361  skipCurrent();
362  break;
363  }
364  }
365 
366  if( !footprint.IsEmpty() && fpid.Parse( footprint ) >= 0 )
367  {
368  wxString error;
369  error.Printf( _( "invalid footprint ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),
370  GetChars( CurSource() ), CurLineNumber(), CurOffset() );
371 
372  THROW_IO_ERROR( error );
373  }
374 
375  pathtimestamp += timestamp;
376  COMPONENT* component = new COMPONENT( fpid, ref, value, pathtimestamp );
377  component->SetName( name );
378  component->SetLibrary( library );
379  m_netlist->AddComponent( component );
380 }
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes...
Definition: macros.h:53
void SetLibrary(const wxString &aLibrary)
Definition: pcb_netlist.h:148
NETLIST * m_netlist
The netlist to parse into. Not owned.
void skipCurrent()
Function skipCurrent Skip the current token level, i.e search for the RIGHT parenthesis which closes ...
int Parse(const UTF8 &aId)
Parse LIB_ID with the information from aId.
Definition: lib_id.cpp:122
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
void AddComponent(COMPONENT *aComponent)
Function AddComponent adds aComponent to the NETLIST.
Class COMPONENT is used to store components and all of their related information found in a netlist...
Definition: pcb_netlist.h:83
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
const char * name
Definition: DXF_plotter.cpp:61
void SetName(const wxString &aName)
Definition: pcb_netlist.h:145
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
void KICAD_NETLIST_PARSER::parseLibPartList ( )
private

Function parseLibPartList reads the section "libparts" in the netlist: (libparts (libpart (lib device) (part C) (description "Condensateur non polarise") (footprints (fp SM*) (fp C?) (fp C1-1)) (fields (field (name Reference) C) (field (name Value) C)) (pins (pin (num 1) (name ~) (type passive)) (pin (num 2) (name ~) (type passive))))

And add the strings giving the footprint filter (subsection footprints) of the corresponding module info

This section is used by CvPcb, and is not useful in Pcbnew, therefore it it not always read

Definition at line 383 of file kicad_netlist_reader.cpp.

References FROM_UTF8(), NETLIST::GetComponent(), NETLIST::GetCount(), i, COMPONENT::IsLibSource(), m_netlist, COMPONENT::SetFootprintFilters(), COMPONENT::SetPinCount(), skipCurrent(), and token.

Referenced by Parse().

384 {
385  /* Parses a section like
386  * (libpart (lib device) (part C)
387  * (aliases
388  * (alias Cxx)
389  * (alias Cyy))
390  * (description "Condensateur non polarise")
391  * (footprints
392  * (fp SM*)
393  * (fp C?)
394  * (fp C1-1))
395  * (fields
396  * (field (name Reference) C)
397  * (field (name Value) C))
398  * (pins
399  * (pin (num 1) (name ~) (type passive))
400  * (pin (num 2) (name ~) (type passive))))
401  *
402  * Currently footprints section/fp are read and data stored
403  * other fields (unused) are skipped
404  */
405  COMPONENT* component = NULL;
406  wxString libName;
407  wxString libPartName;
408  wxArrayString footprintFilters;
409  wxArrayString aliases;
410  int pinCount = 0;
411 
412  // The last token read was libpart, so read the next token
413  while( (token = NextTok()) != T_RIGHT )
414  {
415  if( token == T_LEFT )
416  token = NextTok();
417 
418  switch( token )
419  {
420  case T_lib:
421  NeedSYMBOLorNUMBER();
422  libName = FROM_UTF8( CurText() );
423  NeedRIGHT();
424  break;
425 
426  case T_part:
427  NeedSYMBOLorNUMBER();
428  libPartName = FROM_UTF8( CurText() );
429  NeedRIGHT();
430  break;
431 
432  case T_footprints:
433  // Read all fp elements (footprint filter item)
434  while( (token = NextTok()) != T_RIGHT )
435  {
436  if( token == T_LEFT )
437  token = NextTok();
438 
439  if( token != T_fp )
440  Expecting( T_fp );
441 
442  NeedSYMBOLorNUMBER();
443  footprintFilters.Add( FROM_UTF8( CurText() ) );
444  NeedRIGHT();
445  }
446  break;
447 
448  case T_aliases:
449  while( (token = NextTok()) != T_RIGHT )
450  {
451  if( token == T_LEFT )
452  token = NextTok();
453 
454  if( token != T_alias )
455  Expecting( T_alias );
456 
457  NeedSYMBOLorNUMBER();
458  aliases.Add( FROM_UTF8( CurText() ) );
459  NeedRIGHT();
460  }
461  break;
462 
463  case T_pins:
464  while( (token = NextTok()) != T_RIGHT )
465  {
466  if( token == T_LEFT )
467  token = NextTok();
468 
469  if( token != T_pin )
470  Expecting( T_pin );
471 
472  pinCount++;
473 
474  skipCurrent();
475  }
476  break;
477 
478  default:
479  // Skip not used data (i.e all other tokens)
480  skipCurrent();
481  break;
482  }
483  }
484 
485  // Find all of the components that reference this component library part definition.
486  for( unsigned i = 0; i < m_netlist->GetCount(); i++ )
487  {
488  component = m_netlist->GetComponent( i );
489 
490  if( component->IsLibSource( libName, libPartName ) )
491  {
492  component->SetFootprintFilters( footprintFilters );
493  component->SetPinCount( pinCount );
494  }
495 
496  for( unsigned jj = 0; jj < aliases.GetCount(); jj++ )
497  {
498  if( component->IsLibSource( libName, aliases[jj] ) )
499  {
500  component->SetFootprintFilters( footprintFilters );
501  component->SetPinCount( pinCount );
502  }
503  }
504 
505  }
506 }
bool IsLibSource(const wxString &aLibrary, const wxString &aName) const
Definition: pcb_netlist.h:193
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes...
Definition: macros.h:53
NETLIST * m_netlist
The netlist to parse into. Not owned.
void skipCurrent()
Function skipCurrent Skip the current token level, i.e search for the RIGHT parenthesis which closes ...
void SetFootprintFilters(const wxArrayString &aFilterList)
Definition: pcb_netlist.h:172
void SetPinCount(int aPinCount)
Definition: pcb_netlist.h:179
Class COMPONENT is used to store components and all of their related information found in a netlist...
Definition: pcb_netlist.h:83
COMPONENT * GetComponent(unsigned aIndex)
Function GetComponent returns the COMPONENT at aIndex.
Definition: pcb_netlist.h:265
size_t i
Definition: json11.cpp:597
unsigned GetCount() const
Function GetCount.
Definition: pcb_netlist.h:256
void KICAD_NETLIST_PARSER::parseNet ( )
private

Function parseNet Parses a section like (net (code 20) (name /PC-A0) (node (ref BUS1) (pin 62)) (node (ref U3) (pin 3)) (node (ref U9) (pin M6)))

and set the corresponding pads netnames

Definition at line 180 of file kicad_netlist_reader.cpp.

References COMPONENT::AddNet(), FROM_UTF8(), GetChars(), NETLIST::GetComponentByReference(), LINE_READER::GetSource(), LINE_READER::Length(), LINE_READER::Line(), LINE_READER::LineNumber(), m_lineReader, m_netlist, name, skipCurrent(), THROW_PARSE_ERROR, and token.

Referenced by Parse().

181 {
182  /* Parses a section like
183  * (net (code 20) (name /PC-A0)
184  * (node (ref BUS1) (pin 62))
185  * (node (ref U3) (pin 3))
186  * (node (ref U9) (pin M6)))
187  */
188 
189  COMPONENT* component = NULL;
190  wxString code;
191  wxString name;
192  wxString reference;
193  wxString pin;
194  int nodecount = 0;
195 
196  // The token net was read, so the next data is (code <number>)
197  while( (token = NextTok()) != T_RIGHT )
198  {
199  if( token == T_LEFT )
200  token = NextTok();
201 
202  switch( token )
203  {
204  case T_code:
205  NeedSYMBOLorNUMBER();
206  code = FROM_UTF8( CurText() );
207  NeedRIGHT();
208  break;
209 
210  case T_name:
211  NeedSYMBOLorNUMBER();
212  name = FROM_UTF8( CurText() );
213  NeedRIGHT();
214 
215  if( name.IsEmpty() ) // Give a dummy net name like N-000109
216  name = wxT("N-00000") + code;
217 
218  break;
219 
220  case T_node:
221  while( (token = NextTok()) != T_RIGHT )
222  {
223  if( token == T_LEFT )
224  token = NextTok();
225 
226  switch( token )
227  {
228  case T_ref:
229  NeedSYMBOLorNUMBER();
230  reference = FROM_UTF8( CurText() );
231  NeedRIGHT();
232  break;
233 
234  case T_pin:
235  NeedSYMBOLorNUMBER();
236  pin = FROM_UTF8( CurText() );
237  NeedRIGHT();
238  break;
239 
240  default:
241  skipCurrent();
242  break;
243  }
244  }
245 
246 
247  component = m_netlist->GetComponentByReference( reference );
248 
249  // Cannot happen if the netlist is valid.
250  if( component == NULL )
251  {
252  wxString msg;
253  msg.Printf( _( "Cannot find component with reference \"%s\" in netlist." ),
254  GetChars( reference ) );
257  }
258 
259  component->AddNet( pin, name );
260  nodecount++;
261  break;
262 
263  default:
264  skipCurrent();
265  break;
266  }
267  }
268 }
virtual unsigned LineNumber() const
Function Line Number returns the line number of the last line read from this LINE_READER.
Definition: richio.h:159
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes...
Definition: macros.h:53
NETLIST * m_netlist
The netlist to parse into. Not owned.
void skipCurrent()
Function skipCurrent Skip the current token level, i.e search for the RIGHT parenthesis which closes ...
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
Definition: ki_exception.h:133
LINE_READER * m_lineReader
The line reader used to parse the netlist. Not owned.
char * Line() const
Function Line returns a pointer to the last line that was read in.
Definition: richio.h:139
unsigned Length() const
Function Length returns the number of bytes in the last line read from this LINE_READER.
Definition: richio.h:168
Class COMPONENT is used to store components and all of their related information found in a netlist...
Definition: pcb_netlist.h:83
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
const char * name
Definition: DXF_plotter.cpp:61
virtual const wxString & GetSource() const
Function GetSource returns the name of the source of the lines in an abstract sense.
Definition: richio.h:130
void AddNet(const wxString &aPinName, const wxString &aNetName)
Definition: pcb_netlist.h:132
COMPONENT * GetComponentByReference(const wxString &aReference)
Function GetComponentByReference returns a COMPONENT by aReference.
void KICAD_NETLIST_PARSER::SetLineReader ( LINE_READER aLineReader)
void KICAD_NETLIST_PARSER::SetNetlist ( NETLIST aNetlist)
inline

Definition at line 362 of file netlist_reader.h.

References numEval::Parse().

362 { m_netlist = aNetlist; }
NETLIST * m_netlist
The netlist to parse into. Not owned.
void KICAD_NETLIST_PARSER::skipCurrent ( )
private

Function skipCurrent Skip the current token level, i.e search for the RIGHT parenthesis which closes the current description.

Definition at line 64 of file kicad_netlist_reader.cpp.

References token.

Referenced by Parse(), parseComponent(), parseLibPartList(), and parseNet().

65 {
66  int curr_level = 0;
67 
68  while( ( token = NextTok() ) != T_EOF )
69  {
70  if( token == T_LEFT )
71  curr_level--;
72 
73  if( token == T_RIGHT )
74  {
75  curr_level++;
76 
77  if( curr_level > 0 )
78  return;
79  }
80  }
81 }

Member Data Documentation

LINE_READER* KICAD_NETLIST_PARSER::m_lineReader
private

The line reader used to parse the netlist. Not owned.

Definition at line 298 of file netlist_reader.h.

Referenced by KICAD_NETLIST_PARSER(), and parseNet().

NETLIST* KICAD_NETLIST_PARSER::m_netlist
private

The netlist to parse into. Not owned.

Definition at line 299 of file netlist_reader.h.

Referenced by KICAD_NETLIST_PARSER(), parseComponent(), parseLibPartList(), and parseNet().

NL_T::T KICAD_NETLIST_PARSER::token
private

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