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(), LIB_ID::ID_PCB, 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 if( token == T_description )
339  {
340  NeedSYMBOLorNUMBER();
341  NeedRIGHT();
342  }
343  else
344  {
345  Expecting( "part, lib or description" );
346  }
347  }
348  break;
349 
350  case T_sheetpath:
351  while( ( token = NextTok() ) != T_tstamps );
352  NeedSYMBOLorNUMBER();
353  pathtimestamp = FROM_UTF8( CurText() );
354  NeedRIGHT();
355  NeedRIGHT();
356  break;
357 
358  case T_tstamp:
359  NeedSYMBOLorNUMBER();
360  timestamp = FROM_UTF8( CurText() );
361  NeedRIGHT();
362  break;
363 
364  default:
365  // Skip not used data (i.e all other tokens)
366  skipCurrent();
367  break;
368  }
369  }
370 
371  if( !footprint.IsEmpty() && fpid.Parse( footprint, LIB_ID::ID_PCB, true ) >= 0 )
372  {
373  wxString error;
374  error.Printf( _( "invalid footprint ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),
375  GetChars( CurSource() ), CurLineNumber(), CurOffset() );
376 
377  THROW_IO_ERROR( error );
378  }
379 
380  pathtimestamp += timestamp;
381  COMPONENT* component = new COMPONENT( fpid, ref, value, pathtimestamp );
382  component->SetName( name );
383  component->SetLibrary( library );
384  m_netlist->AddComponent( component );
385 }
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 ...
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.
#define THROW_IO_ERROR(msg)
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
int Parse(const UTF8 &aId, LIB_ID_TYPE aType, bool aFix=false)
Parse LIB_ID with the information from aId.
Definition: lib_id.cpp:122
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 388 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().

389 {
390  /* Parses a section like
391  * (libpart (lib device) (part C)
392  * (aliases
393  * (alias Cxx)
394  * (alias Cyy))
395  * (description "Condensateur non polarise")
396  * (footprints
397  * (fp SM*)
398  * (fp C?)
399  * (fp C1-1))
400  * (fields
401  * (field (name Reference) C)
402  * (field (name Value) C))
403  * (pins
404  * (pin (num 1) (name ~) (type passive))
405  * (pin (num 2) (name ~) (type passive))))
406  *
407  * Currently footprints section/fp are read and data stored
408  * other fields (unused) are skipped
409  */
410  COMPONENT* component = NULL;
411  wxString libName;
412  wxString libPartName;
413  wxArrayString footprintFilters;
414  wxArrayString aliases;
415  int pinCount = 0;
416 
417  // The last token read was libpart, so read the next token
418  while( (token = NextTok()) != T_RIGHT )
419  {
420  if( token == T_LEFT )
421  token = NextTok();
422 
423  switch( token )
424  {
425  case T_lib:
426  NeedSYMBOLorNUMBER();
427  libName = FROM_UTF8( CurText() );
428  NeedRIGHT();
429  break;
430 
431  case T_part:
432  NeedSYMBOLorNUMBER();
433  libPartName = FROM_UTF8( CurText() );
434  NeedRIGHT();
435  break;
436 
437  case T_footprints:
438  // Read all fp elements (footprint filter item)
439  while( (token = NextTok()) != T_RIGHT )
440  {
441  if( token == T_LEFT )
442  token = NextTok();
443 
444  if( token != T_fp )
445  Expecting( T_fp );
446 
447  NeedSYMBOLorNUMBER();
448  footprintFilters.Add( FROM_UTF8( CurText() ) );
449  NeedRIGHT();
450  }
451  break;
452 
453  case T_aliases:
454  while( (token = NextTok()) != T_RIGHT )
455  {
456  if( token == T_LEFT )
457  token = NextTok();
458 
459  if( token != T_alias )
460  Expecting( T_alias );
461 
462  NeedSYMBOLorNUMBER();
463  aliases.Add( FROM_UTF8( CurText() ) );
464  NeedRIGHT();
465  }
466  break;
467 
468  case T_pins:
469  while( (token = NextTok()) != T_RIGHT )
470  {
471  if( token == T_LEFT )
472  token = NextTok();
473 
474  if( token != T_pin )
475  Expecting( T_pin );
476 
477  pinCount++;
478 
479  skipCurrent();
480  }
481  break;
482 
483  default:
484  // Skip not used data (i.e all other tokens)
485  skipCurrent();
486  break;
487  }
488  }
489 
490  // Find all of the components that reference this component library part definition.
491  for( unsigned i = 0; i < m_netlist->GetCount(); i++ )
492  {
493  component = m_netlist->GetComponent( i );
494 
495  if( component->IsLibSource( libName, libPartName ) )
496  {
497  component->SetFootprintFilters( footprintFilters );
498  component->SetPinCount( pinCount );
499  }
500 
501  for( unsigned jj = 0; jj < aliases.GetCount(); jj++ )
502  {
503  if( component->IsLibSource( libName, aliases[jj] ) )
504  {
505  component->SetFootprintFilters( footprintFilters );
506  component->SetPinCount( pinCount );
507  }
508  }
509 
510  }
511 }
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 ...
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
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
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: