KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcbnew/netlist_reader/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 The 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 <config.h> // to define strncasecmp for some platforms
27#include <richio.h>
28#include <string_utils.h>
29
30#include "pcb_netlist.h"
31#include <netlist_reader/netlist_reader.h>
32
33
35{
36 int state = 0;
37 bool is_comment = false;
38 COMPONENT* component = nullptr;
39
40 while( m_lineReader->ReadLine() )
41 {
42 char* line = StrPurge( m_lineReader->Line() );
43
44 if( is_comment ) // Comments in progress
45 {
46 // Test for end of the current comment
47 if( ( line = strchr( line, '}' ) ) == nullptr )
48 continue;
49
50 is_comment = false;
51 }
52
53 if( *line == '{' ) // Start Comment or Pcbnew info section
54 {
55 is_comment = true;
56
57 if( m_loadFootprintFilters && state == 0
58 && (strncasecmp( line, "{ Allowed footprints", 20 ) == 0) )
59 {
61 continue;
62 }
63
64 if( ( line = strchr( line, '}' ) ) == nullptr )
65 continue;
66 }
67
68 if( *line == '(' )
69 state++;
70
71 if( *line == ')' )
72 state--;
73
74 if( state == 2 )
75 {
76 component = loadComponent( line );
77 continue;
78 }
79
80 if( state >= 3 ) // Pad descriptions are read here.
81 {
82 wxASSERT( component != nullptr );
83
84 loadNet( line, component );
85 state--;
86 }
87 }
88
90 {
92 }
93}
94
95
97{
98 char* text;
99 wxString msg;
100 wxString footprintName; // the footprint name read from netlist
101 wxString value; // the component value read from netlist
102 wxString reference; // the component schematic reference designator read from netlist
103 wxString name; // the name of component that was placed in the schematic
104 char line[1024];
105
106 strncpy( line, aText, sizeof(line)-1 );
107 line[sizeof(line)-1] = '\0';
108
109 value = wxT( "~" );
110
111 // Sample component line: /68183921-93a5-49ac-91b0-49d05a0e1647 $noname R20 4.7K {Lib=R}
112
113 // Read time stamp (first word)
114 if( ( text = strtok( line, " ()\t\n" ) ) == nullptr )
115 {
116 msg = _( "Cannot parse time stamp in symbol section of netlist." );
117 THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), line, m_lineReader->LineNumber(),
118 m_lineReader->Length() );
119 }
120
121 KIID_PATH path( From_UTF8( text ) );
122
123 // Read footprint name (second word)
124 if( ( text = strtok( nullptr, " ()\t\n" ) ) == nullptr )
125 {
126 msg = _( "Cannot parse footprint name in symbol section of netlist." );
127 THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), aText, m_lineReader->LineNumber(),
128 m_lineReader->Length() );
129 }
130
131 footprintName = From_UTF8( text );
132
133 // The footprint name will have to be looked up in the *.cmp file.
134 if( footprintName == wxT( "$noname" ) )
135 footprintName = wxEmptyString;
136
137 // Read schematic reference designator (third word)
138 if( ( text = strtok( nullptr, " ()\t\n" ) ) == nullptr )
139 {
140 msg = _( "Cannot parse reference designator in symbol section of netlist." );
141 THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), aText, m_lineReader->LineNumber(),
142 m_lineReader->Length() );
143 }
144
145 reference = From_UTF8( text );
146
147 // Read schematic value (forth word)
148 if( ( text = strtok( nullptr, " ()\t\n" ) ) == nullptr )
149 {
150 msg = _( "Cannot parse value in symbol section of netlist." );
151 THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), aText, m_lineReader->LineNumber(),
152 m_lineReader->Length() );
153 }
154
155 value = From_UTF8( text );
156
157 // Read component name (fifth word) {Lib=C}
158 // This is an optional field (a comment), which does not always exists
159 if( ( text = strtok( nullptr, " ()\t\n" ) ) != nullptr )
160 {
161 name = From_UTF8( text ).AfterFirst( wxChar( '=' ) ).BeforeLast( wxChar( '}' ) );
162 }
163
164 LIB_ID fpid;
165
166 if( !footprintName.IsEmpty() )
167 fpid.SetLibItemName( footprintName );
168
169 COMPONENT* component = new COMPONENT( fpid, reference, value, path, {} );
170 component->SetName( name );
171 m_netlist->AddComponent( component );
172 return component;
173}
174
175
176void LEGACY_NETLIST_READER::loadNet( char* aText, COMPONENT* aComponent )
177{
178 wxString msg;
179 char* p;
180 char line[256];
181
182 strncpy( line, aText, sizeof( line ) );
183 line[ sizeof(line) - 1 ] = '\0';
184
185 if( ( p = strtok( line, " ()\t\n" ) ) == nullptr )
186 {
187 msg = _( "Cannot parse pin name in symbol net section of netlist." );
188 THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), line, m_lineReader->LineNumber(),
189 m_lineReader->Length() );
190 }
191
192 wxString pinName = From_UTF8( p );
193
194 if( ( p = strtok( nullptr, " ()\t\n" ) ) == nullptr )
195 {
196 msg = _( "Cannot parse net name in symbol net section of netlist." );
197 THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), line, m_lineReader->LineNumber(),
198 m_lineReader->Length() );
199 }
200
201 wxString netName = From_UTF8( p );
202
203 if( (char) netName[0] == '?' ) // ? indicates no net connected to pin.
204 netName = wxEmptyString;
205
206 aComponent->AddNet( pinName, netName, wxEmptyString, wxEmptyString );
207}
208
209
211{
212 wxArrayString filters;
213 wxString cmpRef;
214 char* line;
215 COMPONENT* component = nullptr; // Suppress compile warning
216
217 while( ( line = m_lineReader->ReadLine() ) != nullptr )
218 {
219 if( strncasecmp( line, "$endlist", 8 ) == 0 ) // end of list for the current component
220 {
221 wxASSERT( component != nullptr );
222 component->SetFootprintFilters( filters );
223 component = nullptr;
224 filters.Clear();
225 continue;
226 }
227
228 if( strncasecmp( line, "$endfootprintlist", 4 ) == 0 )
229 // End of this section
230 return;
231
232 if( strncasecmp( line, "$component", 10 ) == 0 ) // New component reference found
233 {
234 cmpRef = From_UTF8( line + 11 );
235 cmpRef.Trim( true );
236 cmpRef.Trim( false );
237
238 component = m_netlist->GetComponentByReference( cmpRef );
239
240 // Cannot happen if the netlist is valid.
241 if( component == nullptr )
242 {
243 wxString msg;
244 msg.Printf( _( "Cannot find symbol %s in footprint filter section of netlist." ),
245 cmpRef );
246 THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), line, m_lineReader->LineNumber(),
247 m_lineReader->Length() );
248 }
249 }
250 else
251 {
252 // Add new filter to list
253 wxString fp = From_UTF8( line + 1 );
254 fp.Trim( false );
255 fp.Trim( true );
256 filters.Add( fp );
257 }
258 }
259}
260
261// LocalWords: EDA Charras pcb netlist noname cmp endlist
262// LocalWords: endfootprintlist
const char * name
Store all of the related component information found in a netlist.
void SetFootprintFilters(const wxArrayString &aFilters)
void AddNet(const wxString &aPinName, const wxString &aNetName, const wxString &aPinFunction, const wxString &aPinType)
void SetName(const wxString &aName)
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.
int SetLibItemName(const UTF8 &aLibItemName)
Override the library item name portion of the LIB_ID to aLibItemName.
Definition lib_id.cpp:111
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.
LINE_READER * m_lineReader
The line reader of the netlist.
NETLIST * m_netlist
The net list to read the file(s) into.
#define _(s)
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
wxString From_UTF8(const char *cstring)
char * StrPurge(char *text)
Remove leading and training spaces, tabs and end of line chars in text.
std::string path