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 <[email protected]>.
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
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
178void 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
const char * name
Definition: DXF_plotter.cpp:56
bool Load(NETLIST *aNetlist)
Read the *.cmp file format contains the component footprint assignments created by CvPcb into aNetlis...
Store all of the related footprint information found in a netlist.
Definition: pcb_netlist.h:85
void SetFootprintFilters(const wxArrayString &aFilters)
Definition: pcb_netlist.h:147
void AddNet(const wxString &aPinName, const wxString &aNetName, const wxString &aPinFunction, const wxString &aPinType)
Definition: pcb_netlist.h:103
void SetName(const wxString &aName)
Definition: pcb_netlist.h:119
COMPONENT * loadComponent(char *aText)
Read the aLine containing the description of a component from a legacy format netlist and add it to t...
void loadFootprintFilters()
Load the footprint filter section of netlist file.
void loadNet(char *aText, COMPONENT *aComponent)
Function loadNet read a component net description from aText.
virtual void LoadNetlist() override
Read the netlist file in the legacy format into aNetlist.
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:49
int SetLibItemName(const UTF8 &aLibItemName)
Override the library item name portion of the LIB_ID to aLibItemName.
Definition: lib_id.cpp:109
virtual char * ReadLine()=0
Read a line of text into the buffer and increments the line number counter.
virtual const wxString & GetSource() const
Returns the name of the source of the lines in an abstract sense.
Definition: richio.h:109
virtual unsigned LineNumber() const
Return the line number of the last line read from this LINE_READER.
Definition: richio.h:135
unsigned Length() const
Return the number of bytes in the last line read from this LINE_READER.
Definition: richio.h:143
char * Line() const
Return a pointer to the last line that was read in.
Definition: richio.h:117
NETLIST * m_netlist
The net list to read the file(s) into.
LINE_READER * m_lineReader
The line reader of the netlist.
bool m_loadFootprintFilters
Load the component footprint filters section if true.
CMP_READER * m_footprintReader
The reader used to load the footprint links. If NULL, footprint links are not read.
void AddComponent(COMPONENT *aComponent)
Add aComponent to the NETLIST.
COMPONENT * GetComponentByReference(const wxString &aReference)
Return a COMPONENT by aReference.
#define _(s)
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
Definition: ki_exception.h:164
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
char * StrPurge(char *text)
Remove leading and training spaces, tabs and end of line chars in text.