KiCad PCB EDA Suite
Loading...
Searching...
No Matches
netlist_reader.cpp
Go to the documentation of this file.
1
4/*
5 * This program source code file is part of KiCad, a free EDA CAD application.
6 *
7 * Copyright (C) 1992-2011 Jean-Pierre Charras.
8 * Copyright (C) 2013-2016 Wayne Stambaugh <[email protected]>.
9 * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, you may find one here:
23 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
24 * or you may search the http://www.gnu.org website for the version 2 license,
25 * or you may write to the Free Software Foundation, Inc.,
26 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
27 */
28
29
30
31#include <string_utils.h>
32#include <reporter.h>
33#include <richio.h>
34
35#include "pcb_netlist.h"
36#include "netlist_reader.h"
37#include <footprint.h>
38
39#include <wx/regex.h>
40
41
43{
44 delete m_lineReader;
45 delete m_footprintReader;
46}
47
48
50{
51 // Orcad Pcb2 netlist format starts by "( {", followed by an unknown comment,
52 // depending on the tool which created the file
53 wxRegEx reOrcad( wxT( "(?i)[ ]*\\([ \t]+{+" ), wxRE_ADVANCED );
54 wxASSERT( reOrcad.IsValid() );
55
56 // Our legacy netlist format starts by "# EESchema Netlist "
57 wxRegEx reLegacy( wxT( "(?i)#[ \t]+EESchema[ \t]+Netlist[ \t]+" ), wxRE_ADVANCED );
58 wxASSERT( reLegacy.IsValid() );
59
60 // Our new netlist format starts by "(export (version "
61 wxRegEx reKicad( wxT( "[ ]*\\(export[ ]+" ), wxRE_ADVANCED );
62 wxASSERT( reKicad.IsValid() );
63
64 wxString line;
65
66 while( aLineReader->ReadLine() )
67 {
68 line = From_UTF8( aLineReader->Line() );
69
70 if( reLegacy.Matches( line ) )
71 return LEGACY;
72 else if( reKicad.Matches( line ) )
73 return KICAD;
74 else if( reOrcad.Matches( line ) )
75 return ORCAD;
76 }
77
78 return UNKNOWN;
79}
80
81
83 const wxString& aNetlistFileName,
84 const wxString& aCompFootprintFileName )
85{
86 wxASSERT( aNetlist != nullptr );
87
88 std::unique_ptr<FILE_LINE_READER> file_rdr =
89 std::make_unique<FILE_LINE_READER>( aNetlistFileName );
90
91 NETLIST_FILE_T type = GuessNetlistFileType( file_rdr.get() );
92 file_rdr->Rewind();
93
94 // The component footprint link reader is NULL if no file name was specified.
95 std::unique_ptr<CMP_READER> cmp_rdr( aCompFootprintFileName.IsEmpty() ?
96 nullptr :
97 new CMP_READER( new FILE_LINE_READER( aCompFootprintFileName ) ) );
98
99 switch( type )
100 {
101 case LEGACY:
102 case ORCAD:
103 return new LEGACY_NETLIST_READER( file_rdr.release(), aNetlist, cmp_rdr.release() );
104
105 case KICAD:
106 return new KICAD_NETLIST_READER( file_rdr.release(), aNetlist, cmp_rdr.release() );
107
108 default: // Unrecognized format:
109 break;
110 }
111
112 return nullptr;
113}
114
115
117{
118 if( m_lineReader )
119 {
120 delete m_lineReader;
121 m_lineReader = nullptr;
122 }
123}
124
125
126bool CMP_READER::Load( NETLIST* aNetlist )
127{
128 wxCHECK_MSG( aNetlist != nullptr, true, wxT( "No netlist passed to CMP_READER::Load()" ) );
129
130 wxString reference; // Stores value read from line like Reference = BUS1;
131 wxString timestamp; // Stores value read from line like TimeStamp = /32307DE2/AA450F67;
132 wxString footprint; // Stores value read from line like IdModule = CP6;
133 wxString buffer;
134 wxString value;
135
136 bool ok = true;
137
138 while( m_lineReader->ReadLine() )
139 {
140 buffer = From_UTF8( m_lineReader->Line() );
141
142 if( !buffer.StartsWith( wxT( "BeginCmp" ) ) )
143 continue;
144
145 // Begin component description.
146 reference.Empty();
147 footprint.Empty();
148 timestamp.Empty();
149
150 while( m_lineReader->ReadLine() )
151 {
152 buffer = From_UTF8( m_lineReader->Line() );
153
154 if( buffer.StartsWith( wxT( "EndCmp" ) ) )
155 break;
156
157 // store string value, stored between '=' and ';' delimiters.
158 value = buffer.AfterFirst( '=' );
159 value = value.BeforeLast( ';' );
160 value.Trim( true );
161 value.Trim( false );
162
163 if( buffer.StartsWith( wxT( "Reference" ) ) )
164 {
165 reference = value;
166 continue;
167 }
168
169 if( buffer.StartsWith( wxT( "IdModule =" ) ) )
170 {
171 footprint = value;
172 continue;
173 }
174
175 if( buffer.StartsWith( wxT( "TimeStamp =" ) ) )
176 {
177 timestamp = value;
178 continue;
179 }
180 }
181
182 // Find the corresponding item in component list:
183 COMPONENT* component = aNetlist->GetComponentByReference( reference );
184
185 // The corresponding component could no longer existing in the netlist. This
186 // can happen when it is removed from schematic and still exists in footprint
187 // assignment list. This is an usual case during the life of a design.
188 if( component )
189 {
190 LIB_ID fpid;
191
192 if( !footprint.IsEmpty() && fpid.Parse( footprint, true ) >= 0 )
193 {
194 wxString error;
195 error.Printf( _( "Invalid footprint ID in\nfile: '%s'\nline: %d" ),
197
198 THROW_IO_ERROR( error );
199 }
200
201 // For checking purpose, store the existing LIB_ID (if any) in the alternate fpid copy
202 // if this existing LIB_ID differs from the LIB_ID read from the .cmp file.
203 // CvPcb can ask for user to chose the right LIB_ID.
204 // It happens if the LIB_ID was modified outside CvPcb.
205 if( fpid != component->GetFPID() && !component->GetFPID().empty() )
206 component->SetAltFPID( component->GetFPID() );
207
208 component->SetFPID( fpid );
209 }
210 else
211 {
212 ok = false; // can be used to display a warning in Pcbnew.
213 }
214 }
215
216 return ok;
217}
Read a component footprint link file (*.cmp) format.
bool Load(NETLIST *aNetlist)
Read the *.cmp file format contains the component footprint assignments created by CvPcb into aNetlis...
LINE_READER * m_lineReader
The line reader to read.
Store all of the related footprint information found in a netlist.
Definition: pcb_netlist.h:88
void SetAltFPID(const LIB_ID &aFPID)
Definition: pcb_netlist.h:149
void SetFPID(const LIB_ID &aFPID)
Definition: pcb_netlist.h:146
const LIB_ID & GetFPID() const
Definition: pcb_netlist.h:147
A LINE_READER that reads from an open file.
Definition: richio.h:185
Read the new s-expression based KiCad netlist format.
Read the KiCad legacy and the old Orcad netlist formats.
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:49
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
Definition: lib_id.cpp:51
bool empty() const
Definition: lib_id.h:193
An abstract class from which implementation specific LINE_READERs may be derived to read single lines...
Definition: richio.h:93
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
char * Line() const
Return a pointer to the last line that was read in.
Definition: richio.h:129
A pure virtual class to derive a specific type of netlist reader from.
static NETLIST_READER * GetNetlistReader(NETLIST *aNetlist, const wxString &aNetlistFileName, const wxString &aCompFootprintFileName=wxEmptyString)
Attempt to determine the net list file type of aNetlistFileName and return the appropriate NETLIST_RE...
static NETLIST_FILE_T GuessNetlistFileType(LINE_READER *aLineReader)
Look at aFileHeaderLine to see if it matches any of the netlist file types it knows about.
LINE_READER * m_lineReader
The line reader of the netlist.
CMP_READER * m_footprintReader
The reader used to load the footprint links. If NULL, footprint links are not read.
virtual ~NETLIST_READER()
Store information read from a netlist along with the flags used to update the NETLIST in the BOARD.
Definition: pcb_netlist.h:241
COMPONENT * GetComponentByReference(const wxString &aReference)
Return a COMPONENT by aReference.
#define _(s)
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:39
wxString From_UTF8(const char *cstring)