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