KiCad PCB EDA Suite
KICAD_NETLIST_PARSER Class Reference

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

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::KICAD_NETLIST_PARSER ( LINE_READER aReader,
NETLIST aNetlist 
)

Definition at line 55 of file kicad_netlist_reader.cpp.

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.

References m_lineReader, m_netlist, DRCRULE_T::T_NONE, and token.

Member Function Documentation

◆ getTokenName()

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  }

◆ Parse()

void KICAD_NETLIST_PARSER::Parse ( )

Function Parse parse the full netlist.

Definition at line 84 of file kicad_netlist_reader.cpp.

85 {
86  int plevel = 0; // the count of ')' to read at end of file after parsing all sections
87 
88  while( ( token = NextTok() ) != T_EOF )
89  {
90  if( token == T_LEFT )
91  token = NextTok();
92 
93  switch( token )
94  {
95  case T_export: // The netlist starts here.
96  // nothing to do here, just increment the count of ')' to read at end of file
97  plevel++;
98  break;
99 
100  case T_version: // The netlist starts here.
101  // version id not yet used: read it but does not use it
102  NextTok();
103  NeedRIGHT();
104  break;
105 
106  case T_components: // The section comp starts here.
107  while( ( token = NextTok() ) != T_EOF )
108  {
109  if( token == T_RIGHT )
110  break;
111  else 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_EOF )
122  {
123  if( token == T_RIGHT )
124  break;
125  else if( token == T_LEFT )
126  token = NextTok();
127 
128  if( token == T_net ) // A net section if found. Read it
129  parseNet();
130  }
131 
132  break;
133 
134  case T_libparts: // The section libparts starts here.
135  while( ( token = NextTok() ) != T_EOF )
136  {
137  if( token == T_RIGHT )
138  break;
139  else if( token == T_LEFT )
140  token = NextTok();
141 
142  if( token == T_libpart ) // A libpart section if found. Read it
144  }
145 
146  break;
147 
148  case T_libraries: // The section libraries starts here.
149  // List of libraries in use.
150  // Not used here, just skip it
151  skipCurrent();
152  break;
153 
154  case T_design: // The section design starts here.
155  // Not used (mainly they are comments), just skip it
156  skipCurrent();
157  break;
158 
159  case T_RIGHT: // The closing parenthesis of the file.
160  plevel--;
161  break;
162 
163  default:
164  skipCurrent();
165  break;
166  }
167  }
168 
169  if( plevel != 0 )
170  {
171  wxLogDebug( wxT( "KICAD_NETLIST_PARSER::Parse(): bad parenthesis count (count = %d"),
172  plevel );
173  }
174 }
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...

References parseComponent(), parseLibPartList(), parseNet(), skipCurrent(), DRCRULE_T::T_EOF, DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, DRCRULE_T::T_version, and token.

◆ parseComponent()

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 281 of file kicad_netlist_reader.cpp.

282 {
283  /* Parses a section like
284  * (comp (ref P1)
285  * (value DB25FEMALE)
286  * (footprint DB25FC)
287  * (libsource (lib conn) (part DB25))
288  * (sheetpath (names /) (tstamps /))
289  * (tstamp 68183921-93a5-49ac-91b0-49d05a0e1647))
290  *
291  * other fields (unused) are skipped
292  * A component need a reference, value, footprint name and a full time stamp
293  * The full time stamp is the sheetpath time stamp + the component time stamp
294  */
295  LIB_ID fpid;
296  wxString footprint;
297  wxString ref;
298  wxString value;
299  wxString library;
300  wxString name;
301  KIID_PATH path;
302  KIID uuid;
303 
304  // The token comp was read, so the next data is (ref P1)
305  while( (token = NextTok()) != T_RIGHT )
306  {
307  if( token == T_LEFT )
308  token = NextTok();
309 
310  switch( token )
311  {
312  case T_ref:
313  NeedSYMBOLorNUMBER();
314  ref = FROM_UTF8( CurText() );
315  NeedRIGHT();
316  break;
317 
318  case T_value:
319  NeedSYMBOLorNUMBER();
320  value = FROM_UTF8( CurText() );
321  NeedRIGHT();
322  break;
323 
324  case T_footprint:
325  NeedSYMBOLorNUMBER();
326  footprint = FromUTF8();
327  NeedRIGHT();
328  break;
329 
330  case T_libsource:
331  // Read libsource
332  while( (token = NextTok()) != T_RIGHT )
333  {
334  if( token == T_LEFT )
335  token = NextTok();
336 
337  if( token == T_lib )
338  {
339  NeedSYMBOLorNUMBER();
340  library = FROM_UTF8( CurText() );
341  NeedRIGHT();
342  }
343  else if( token == T_part )
344  {
345  NeedSYMBOLorNUMBER();
346  name = FROM_UTF8( CurText() );
347  NeedRIGHT();
348  }
349  else if( token == T_description )
350  {
351  NeedSYMBOLorNUMBER();
352  NeedRIGHT();
353  }
354  else
355  {
356  Expecting( "part, lib or description" );
357  }
358  }
359  break;
360 
361  case T_sheetpath:
362  while( ( token = NextTok() ) != T_EOF )
363  {
364  if( token == T_tstamps )
365  break;
366  }
367 
368  NeedSYMBOLorNUMBER();
369  path = KIID_PATH( FROM_UTF8( CurText() ) );
370  NeedRIGHT();
371  NeedRIGHT();
372  break;
373 
374  case T_tstamp:
375  NeedSYMBOLorNUMBER();
376  uuid = KIID( FROM_UTF8( CurText() ) );
377  NeedRIGHT();
378  break;
379 
380  default:
381  // Skip not used data (i.e all other tokens)
382  skipCurrent();
383  break;
384  }
385  }
386 
387  if( !footprint.IsEmpty() && fpid.Parse( footprint, LIB_ID::ID_PCB, true ) >= 0 )
388  {
389  wxString error;
390  error.Printf( _( "Invalid footprint ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),
391  CurSource(), CurLineNumber(), CurOffset() );
392 
393  THROW_IO_ERROR( error );
394  }
395 
396  path.push_back( uuid );
397  COMPONENT* component = new COMPONENT( fpid, ref, value, path );
398  component->SetName( name );
399  component->SetLibrary( library );
400  m_netlist->AddComponent( component );
401 }
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:114
void SetLibrary(const wxString &aLibrary)
Definition: pcb_netlist.h:141
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.
Definition: common.h:68
#define THROW_IO_ERROR(msg)
COMPONENT is used to store components and all of their related information found in a netlist.
Definition: pcb_netlist.h:80
const char * name
Definition: DXF_plotter.cpp:60
#define _(s)
Definition: 3d_actions.cpp:33
void SetName(const wxString &aName)
Definition: pcb_netlist.h:138
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

References _, NETLIST::AddComponent(), FROM_UTF8(), LIB_ID::ID_PCB, m_netlist, name, LIB_ID::Parse(), COMPONENT::SetLibrary(), COMPONENT::SetName(), skipCurrent(), DRCRULE_T::T_EOF, DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, THROW_IO_ERROR, and token.

Referenced by Parse().

◆ parseLibPartList()

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 404 of file kicad_netlist_reader.cpp.

405 {
406  /* Parses a section like
407  * (libpart (lib device) (part C)
408  * (aliases
409  * (alias Cxx)
410  * (alias Cyy))
411  * (description "Condensateur non polarise")
412  * (footprints
413  * (fp SM*)
414  * (fp C?)
415  * (fp C1-1))
416  * (fields
417  * (field (name Reference) C)
418  * (field (name Value) C))
419  * (pins
420  * (pin (num 1) (name ~) (type passive))
421  * (pin (num 2) (name ~) (type passive))))
422  *
423  * Currently footprints section/fp are read and data stored
424  * other fields (unused) are skipped
425  */
426  COMPONENT* component = NULL;
427  wxString libName;
428  wxString libPartName;
429  wxArrayString footprintFilters;
430  wxArrayString aliases;
431  int pinCount = 0;
432 
433  // The last token read was libpart, so read the next token
434  while( (token = NextTok()) != T_RIGHT )
435  {
436  if( token == T_LEFT )
437  token = NextTok();
438 
439  switch( token )
440  {
441  case T_lib:
442  NeedSYMBOLorNUMBER();
443  libName = FROM_UTF8( CurText() );
444  NeedRIGHT();
445  break;
446 
447  case T_part:
448  NeedSYMBOLorNUMBER();
449  libPartName = FROM_UTF8( CurText() );
450  NeedRIGHT();
451  break;
452 
453  case T_footprints:
454  // Read all fp elements (footprint filter item)
455  while( (token = NextTok()) != T_RIGHT )
456  {
457  if( token == T_LEFT )
458  token = NextTok();
459 
460  if( token != T_fp )
461  Expecting( T_fp );
462 
463  NeedSYMBOLorNUMBER();
464  footprintFilters.Add( FROM_UTF8( CurText() ) );
465  NeedRIGHT();
466  }
467  break;
468 
469  case T_aliases:
470  while( (token = NextTok()) != T_RIGHT )
471  {
472  if( token == T_LEFT )
473  token = NextTok();
474 
475  if( token != T_alias )
476  Expecting( T_alias );
477 
478  NeedSYMBOLorNUMBER();
479  aliases.Add( FROM_UTF8( CurText() ) );
480  NeedRIGHT();
481  }
482  break;
483 
484  case T_pins:
485  while( (token = NextTok()) != T_RIGHT )
486  {
487  if( token == T_LEFT )
488  token = NextTok();
489 
490  if( token != T_pin )
491  Expecting( T_pin );
492 
493  pinCount++;
494 
495  skipCurrent();
496  }
497  break;
498 
499  default:
500  // Skip not used data (i.e all other tokens)
501  skipCurrent();
502  break;
503  }
504  }
505 
506  // Find all of the components that reference this component library part definition.
507  for( unsigned i = 0; i < m_netlist->GetCount(); i++ )
508  {
509  component = m_netlist->GetComponent( i );
510 
511  if( component->IsLibSource( libName, libPartName ) )
512  {
513  component->SetFootprintFilters( footprintFilters );
514  component->SetPinCount( pinCount );
515  }
516 
517  for( unsigned jj = 0; jj < aliases.GetCount(); jj++ )
518  {
519  if( component->IsLibSource( libName, aliases[jj] ) )
520  {
521  component->SetFootprintFilters( footprintFilters );
522  component->SetPinCount( pinCount );
523  }
524  }
525 
526  }
527 }
bool IsLibSource(const wxString &aLibrary, const wxString &aName) const
Definition: pcb_netlist.h:169
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:114
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 ...
unsigned GetCount() const
Function GetCount.
Definition: pcb_netlist.h:228
#define NULL
void SetPinCount(int aPinCount)
Definition: pcb_netlist.h:159
COMPONENT is used to store components and all of their related information found in a netlist.
Definition: pcb_netlist.h:80
COMPONENT * GetComponent(unsigned aIndex)
Function GetComponent returns the COMPONENT at aIndex.
Definition: pcb_netlist.h:237
void SetFootprintFilters(const wxArrayString &aFilters)
Definition: pcb_netlist.h:156

References FROM_UTF8(), NETLIST::GetComponent(), NETLIST::GetCount(), COMPONENT::IsLibSource(), m_netlist, NULL, COMPONENT::SetFootprintFilters(), COMPONENT::SetPinCount(), skipCurrent(), DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, and token.

Referenced by Parse().

◆ parseNet()

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 177 of file kicad_netlist_reader.cpp.

178 {
179  /* Parses a section like
180  * (net (code 20) (name /PC-A0)
181  * (node (ref "BUS1") (pin "62)")
182  * (node (ref "U3") ("pin 3") (pin_function "clock"))
183  * (node (ref "U9") (pin "M6") (pin_function "reset")))
184  */
185 
186  COMPONENT* component = NULL;
187  wxString code;
188  wxString name;
189  wxString reference;
190  wxString pin_number;
191  wxString pin_function;
192  int nodecount = 0;
193 
194  // The token net was read, so the next data is (code <number>)
195  while( (token = NextTok()) != T_EOF )
196  {
197  if( token == T_RIGHT )
198  break;
199  else 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  pin_function.Clear(); // By default: no pin function.
222 
223  while( (token = NextTok()) != T_EOF )
224  {
225  if( token == T_RIGHT )
226  break;
227  else if( token == T_LEFT )
228  token = NextTok();
229 
230  switch( token )
231  {
232  case T_ref:
233  NeedSYMBOLorNUMBER();
234  reference = FROM_UTF8( CurText() );
235  NeedRIGHT();
236  break;
237 
238  case T_pin:
239  NeedSYMBOLorNUMBER();
240  pin_number = FROM_UTF8( CurText() );
241  NeedRIGHT();
242  break;
243 
244  case T_pinfunction:
245  NeedSYMBOLorNUMBER();
246  pin_function = FROM_UTF8( CurText() );
247  NeedRIGHT();
248  break;
249 
250  default:
251  skipCurrent();
252  break;
253  }
254  }
255 
256 
257  component = m_netlist->GetComponentByReference( reference );
258 
259  // Cannot happen if the netlist is valid.
260  if( component == NULL )
261  {
262  wxString msg;
263  msg.Printf( _( "Cannot find component with reference designator \"%s\" in netlist." ),
264  reference );
267  }
268 
269  component->AddNet( pin_number, name, pin_function );
270  nodecount++;
271  break;
272 
273  default:
274  skipCurrent();
275  break;
276  }
277  }
278 }
char * Line() const
Function Line returns a pointer to the last line that was read in.
Definition: richio.h:139
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:114
virtual const wxString & GetSource() const
Function GetSource returns the name of the source of the lines in an abstract sense.
Definition: richio.h:130
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 NULL
LINE_READER * m_lineReader
The line reader used to parse the netlist. Not owned.
virtual unsigned LineNumber() const
Function Line Number returns the line number of the last line read from this LINE_READER.
Definition: richio.h:159
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
COMPONENT is used to store components and all of their related information found in a netlist.
Definition: pcb_netlist.h:80
unsigned Length() const
Function Length returns the number of bytes in the last line read from this LINE_READER.
Definition: richio.h:168
const char * name
Definition: DXF_plotter.cpp:60
#define _(s)
Definition: 3d_actions.cpp:33
COMPONENT * GetComponentByReference(const wxString &aReference)
Function GetComponentByReference returns a COMPONENT by aReference.
void AddNet(const wxString &aPinName, const wxString &aNetName, const wxString &aPinFunction)
Definition: pcb_netlist.h:125

References _, COMPONENT::AddNet(), FROM_UTF8(), NETLIST::GetComponentByReference(), LINE_READER::GetSource(), LINE_READER::Length(), LINE_READER::Line(), LINE_READER::LineNumber(), m_lineReader, m_netlist, name, NULL, skipCurrent(), DRCRULE_T::T_EOF, DRCRULE_T::T_LEFT, DRCRULE_T::T_name, DRCRULE_T::T_RIGHT, THROW_PARSE_ERROR, and token.

Referenced by Parse().

◆ SetLineReader()

void KICAD_NETLIST_PARSER::SetLineReader ( LINE_READER aLineReader)

◆ SetNetlist()

void KICAD_NETLIST_PARSER::SetNetlist ( NETLIST aNetlist)
inline

Definition at line 362 of file netlist_reader.h.

362 { m_netlist = aNetlist; }
NETLIST * m_netlist
The netlist to parse into. Not owned.

References m_netlist.

◆ skipCurrent()

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.

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 }

References DRCRULE_T::T_EOF, DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, and token.

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

Member Data Documentation

◆ m_lineReader

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().

◆ m_netlist

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(), parseNet(), and SetNetlist().

◆ token

NL_T::T KICAD_NETLIST_PARSER::token
private

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