KiCad PCB EDA Suite
legacy_netlist_reader.cpp
Go to the documentation of this file.
1 
5 /*
6  * This program source code file is part of KiCad, a free EDA CAD application.
7  *
8  * Copyright (C) 1992-2011 Jean-Pierre Charras.
9  * Copyright (C) 2013 Wayne Stambaugh <stambaughw@gmail.com>.
10  * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, you may find one here:
24  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
25  * or you may search the http://www.gnu.org website for the version 2 license,
26  * or you may write to the Free Software Foundation, Inc.,
27  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
28  */
29 
30 #include <richio.h>
31 #include <string_utils.h>
32 
33 #include "pcb_netlist.h"
34 #include "netlist_reader.h"
35 
37 {
38  int state = 0;
39  bool is_comment = false;
40  COMPONENT* component = nullptr;
41 
42  while( m_lineReader->ReadLine() )
43  {
44  char* line = StrPurge( m_lineReader->Line() );
45 
46  if( is_comment ) // Comments in progress
47  {
48  // Test for end of the current comment
49  if( ( line = strchr( line, '}' ) ) == nullptr )
50  continue;
51 
52  is_comment = false;
53  }
54 
55  if( *line == '{' ) // Start Comment or Pcbnew info section
56  {
57  is_comment = true;
58 
59  if( m_loadFootprintFilters && state == 0
60  && (strncasecmp( line, "{ Allowed footprints", 20 ) == 0) )
61  {
63  continue;
64  }
65 
66  if( ( line = strchr( line, '}' ) ) == nullptr )
67  continue;
68  }
69 
70  if( *line == '(' )
71  state++;
72 
73  if( *line == ')' )
74  state--;
75 
76  if( state == 2 )
77  {
78  component = loadComponent( line );
79  continue;
80  }
81 
82  if( state >= 3 ) // Pad descriptions are read here.
83  {
84  wxASSERT( component != nullptr );
85 
86  loadNet( line, component );
87  state--;
88  }
89  }
90 
91  if( m_footprintReader )
92  {
94  }
95 }
96 
97 
99 {
100  char* text;
101  wxString msg;
102  wxString footprintName; // the footprint name read from netlist
103  wxString value; // the component value read from netlist
104  wxString reference; // the component schematic reference designator read from netlist
105  wxString name; // the name of component that was placed in the schematic
106  char line[1024];
107 
108  strncpy( line, aText, sizeof(line)-1 );
109  line[sizeof(line)-1] = '\0';
110 
111  value = wxT( "~" );
112 
113  // Sample component line: /68183921-93a5-49ac-91b0-49d05a0e1647 $noname R20 4.7K {Lib=R}
114 
115  // Read time stamp (first word)
116  if( ( text = strtok( line, " ()\t\n" ) ) == nullptr )
117  {
118  msg = _( "Cannot parse time stamp in symbol section of netlist." );
120  m_lineReader->Length() );
121  }
122 
124 
125  // Read footprint name (second word)
126  if( ( text = strtok( nullptr, " ()\t\n" ) ) == nullptr )
127  {
128  msg = _( "Cannot parse footprint name in symbol section of netlist." );
130  m_lineReader->Length() );
131  }
132 
133  footprintName = FROM_UTF8( text );
134 
135  // The footprint name will have to be looked up in the *.cmp file.
136  if( footprintName == wxT( "$noname" ) )
137  footprintName = wxEmptyString;
138 
139  // Read schematic reference designator (third word)
140  if( ( text = strtok( nullptr, " ()\t\n" ) ) == nullptr )
141  {
142  msg = _( "Cannot parse reference designator in symbol section of netlist." );
144  m_lineReader->Length() );
145  }
146 
147  reference = FROM_UTF8( text );
148 
149  // Read schematic value (forth word)
150  if( ( text = strtok( nullptr, " ()\t\n" ) ) == nullptr )
151  {
152  msg = _( "Cannot parse value in symbol section of netlist." );
154  m_lineReader->Length() );
155  }
156 
157  value = FROM_UTF8( text );
158 
159  // Read component name (fifth word) {Lib=C}
160  // This is an optional field (a comment), which does not always exists
161  if( ( text = strtok( nullptr, " ()\t\n" ) ) != nullptr )
162  {
163  name = FROM_UTF8( text ).AfterFirst( wxChar( '=' ) ).BeforeLast( wxChar( '}' ) );
164  }
165 
166  LIB_ID fpid;
167 
168  if( !footprintName.IsEmpty() )
169  fpid.SetLibItemName( footprintName );
170 
171  COMPONENT* component = new COMPONENT( fpid, reference, value, path, {} );
172  component->SetName( name );
173  m_netlist->AddComponent( component );
174  return component;
175 }
176 
177 
178 void LEGACY_NETLIST_READER::loadNet( char* aText, COMPONENT* aComponent )
179 {
180  wxString msg;
181  char* p;
182  char line[256];
183 
184  strncpy( line, aText, sizeof( line ) );
185  line[ sizeof(line) - 1 ] = '\0';
186 
187  if( ( p = strtok( line, " ()\t\n" ) ) == nullptr )
188  {
189  msg = _( "Cannot parse pin name in symbol net section of netlist." );
191  m_lineReader->Length() );
192  }
193 
194  wxString pinName = FROM_UTF8( p );
195 
196  if( ( p = strtok( nullptr, " ()\t\n" ) ) == nullptr )
197  {
198  msg = _( "Cannot parse net name in symbol net section of netlist." );
200  m_lineReader->Length() );
201  }
202 
203  wxString netName = FROM_UTF8( p );
204 
205  if( (char) netName[0] == '?' ) // ? indicates no net connected to pin.
206  netName = wxEmptyString;
207 
208  aComponent->AddNet( pinName, netName, wxEmptyString, wxEmptyString );
209 }
210 
211 
213 {
214  wxArrayString filters;
215  wxString cmpRef;
216  char* line;
217  COMPONENT* component = nullptr; // Suppress compile warning
218 
219  while( ( line = m_lineReader->ReadLine() ) != nullptr )
220  {
221  if( strncasecmp( line, "$endlist", 8 ) == 0 ) // end of list for the current component
222  {
223  wxASSERT( component != nullptr );
224  component->SetFootprintFilters( filters );
225  component = nullptr;
226  filters.Clear();
227  continue;
228  }
229 
230  if( strncasecmp( line, "$endfootprintlist", 4 ) == 0 )
231  // End of this section
232  return;
233 
234  if( strncasecmp( line, "$component", 10 ) == 0 ) // New component reference found
235  {
236  cmpRef = FROM_UTF8( line + 11 );
237  cmpRef.Trim( true );
238  cmpRef.Trim( false );
239 
240  component = m_netlist->GetComponentByReference( cmpRef );
241 
242  // Cannot happen if the netlist is valid.
243  if( component == nullptr )
244  {
245  wxString msg;
246  msg.Printf( _( "Cannot find symbol %s in footprint filter section of netlist." ),
247  cmpRef );
249  m_lineReader->Length() );
250  }
251  }
252  else
253  {
254  // Add new filter to list
255  wxString fp = FROM_UTF8( line + 1 );
256  fp.Trim( false );
257  fp.Trim( true );
258  filters.Add( fp );
259  }
260  }
261 }
262 
263 // LocalWords: EDA Charras pcb netlist noname cmp endlist
264 // LocalWords: endfootprintlist
char * Line() const
Return a pointer to the last line that was read in.
Definition: richio.h:117
static wxString FROM_UTF8(const char *cstring)
Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:110
virtual const wxString & GetSource() const
Returns the name of the source of the lines in an abstract sense.
Definition: richio.h:109
NETLIST * m_netlist
The net list to read the file(s) into.
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
void AddComponent(COMPONENT *aComponent)
Add aComponent to the NETLIST.
bool Load(NETLIST *aNetlist)
Read the *.cmp file format contains the component footprint assignments created by CvPcb into aNetlis...
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
Definition: ki_exception.h:164
virtual unsigned LineNumber() const
Return the line number of the last line read from this LINE_READER.
Definition: richio.h:135
char * StrPurge(char *text)
Remove leading and training spaces, tabs and end of line chars in text.
#define _(s)
void loadNet(char *aText, COMPONENT *aComponent)
Function loadNet read a component net description from aText.
int SetLibItemName(const UTF8 &aLibItemName)
Override the library item name portion of the LIB_ID to aLibItemName.
Definition: lib_id.cpp:108
Store all of the related footprint information found in a netlist.
Definition: pcb_netlist.h:84
unsigned Length() const
Return the number of bytes in the last line read from this LINE_READER.
Definition: richio.h:143
void SetFootprintFilters(const wxArrayString &aFilters)
Definition: pcb_netlist.h:142
bool m_loadFootprintFilters
Load the component footprint filters section if true.
virtual void LoadNetlist() override
Read the netlist file in the legacy format into aNetlist.
virtual char * ReadLine()=0
Read a line of text into the buffer and increments the line number counter.
const char * name
Definition: DXF_plotter.cpp:56
void SetName(const wxString &aName)
Definition: pcb_netlist.h:117
void AddNet(const wxString &aPinName, const wxString &aNetName, const wxString &aPinFunction, const wxString &aPinType)
Definition: pcb_netlist.h:103
void loadFootprintFilters()
Load the footprint filter section of netlist file.
COMPONENT * GetComponentByReference(const wxString &aReference)
Return a COMPONENT by aReference.
LINE_READER * m_lineReader
The line reader of the netlist.
COMPONENT * loadComponent(char *aText)
Read the aLine containing the description of a component from a legacy format netlist and add it to t...
CMP_READER * m_footprintReader
The reader used to load the footprint links. If NULL, footprint links are not read.