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