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-2016 Wayne Stambaugh <stambaughw@verizon.net>.
10  * Copyright (C) 1992-2016 KiCad Developers, see change_log.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 <fctsys.h>
31 #include <richio.h>
32 #include <kicad_string.h>
33 
34 #include <pcb_netlist.h>
35 #include <netlist_reader.h>
36 
38 {
39  int state = 0;
40  bool is_comment = false;
41  COMPONENT* component = NULL;
42 
43  while( m_lineReader->ReadLine() )
44  {
45  char* line = StrPurge( m_lineReader->Line() );
46 
47  if( is_comment ) // Comments in progress
48  {
49  // Test for end of the current comment
50  if( ( line = strchr( line, '}' ) ) == NULL )
51  continue;
52 
53  is_comment = false;
54  }
55 
56  if( *line == '{' ) // Start Comment or Pcbnew info section
57  {
58  is_comment = true;
59 
60  if( m_loadFootprintFilters && state == 0
61  && (strncasecmp( line, "{ Allowed footprints", 20 ) == 0) )
62  {
64  continue;
65  }
66 
67  if( ( line = strchr( line, '}' ) ) == NULL )
68  continue;
69  }
70 
71  if( *line == '(' )
72  state++;
73 
74  if( *line == ')' )
75  state--;
76 
77  if( state == 2 )
78  {
79  component = loadComponent( line );
80  continue;
81  }
82 
83  if( state >= 3 ) // Pad descriptions are read here.
84  {
85  wxASSERT( component != NULL );
86 
87  loadNet( line, component );
88  state--;
89  }
90  }
91 
92  if( m_footprintReader )
93  {
95  }
96 }
97 
98 
100 {
101  char* text;
102  wxString msg;
103  wxString timeStamp; // the full time stamp read from netlist
104  wxString footprintName; // the footprint name read from netlist
105  wxString value; // the component value read from netlist
106  wxString reference; // the component schematic reference designator read from netlist
107  wxString name; // the name of component that was placed in the schematic
108  char line[1024];
109 
110  strncpy( line, aText, sizeof(line)-1 );
111  line[sizeof(line)-1] = '\0';
112 
113  value = wxT( "~" );
114 
115  // Sample component line: /40C08647 $noname R20 4.7K {Lib=R}
116 
117  // Read time stamp (first word)
118  if( ( text = strtok( line, " ()\t\n" ) ) == NULL )
119  {
120  msg = _( "Cannot parse time stamp in component section of netlist." );
122  m_lineReader->Length() );
123  }
124 
125  timeStamp = FROM_UTF8( text );
126 
127  // Read footprint name (second word)
128  if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL )
129  {
130  msg = _( "Cannot parse footprint name in component section of netlist." );
132  m_lineReader->Length() );
133  }
134 
135  footprintName = FROM_UTF8( text );
136 
137  // The footprint name will have to be looked up in the *.cmp file.
138  if( footprintName == wxT( "$noname" ) )
139  footprintName = wxEmptyString;
140 
141  // Read schematic reference designator (third word)
142  if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL )
143  {
144  msg = _( "Cannot parse reference designator in component section of netlist." );
146  m_lineReader->Length() );
147  }
148 
149  reference = FROM_UTF8( text );
150 
151  // Read schematic value (forth word)
152  if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL )
153  {
154  msg = _( "Cannot parse value in component section of netlist." );
156  m_lineReader->Length() );
157  }
158 
159  value = FROM_UTF8( text );
160 
161  // Read component name (fifth word) {Lib=C}
162  // This is an optional field (a comment), which does not always exists
163  if( ( text = strtok( NULL, " ()\t\n" ) ) != NULL )
164  {
165  name = FROM_UTF8( text ).AfterFirst( wxChar( '=' ) ).BeforeLast( wxChar( '}' ) );
166  }
167 
168  LIB_ID fpid;
169 
170  if( !footprintName.IsEmpty() )
171  fpid.SetLibItemName( footprintName );
172 
173  COMPONENT* component = new COMPONENT( fpid, reference, value, timeStamp );
174  component->SetName( name );
175  m_netlist->AddComponent( component );
176  return component;
177 }
178 
179 
180 void LEGACY_NETLIST_READER::loadNet( char* aText, COMPONENT* aComponent )
181 {
182  wxString msg;
183  char* p;
184  char line[256];
185 
186  strncpy( line, aText, sizeof( line ) );
187  line[ sizeof(line) - 1 ] = '\0';
188 
189  if( ( p = strtok( line, " ()\t\n" ) ) == NULL )
190  {
191  msg = _( "Cannot parse pin name in component net section of netlist." );
193  m_lineReader->Length() );
194  }
195 
196  wxString pinName = FROM_UTF8( p );
197 
198  if( ( p = strtok( NULL, " ()\t\n" ) ) == NULL )
199  {
200  msg = _( "Cannot parse net name in component net section of netlist." );
202  m_lineReader->Length() );
203  }
204 
205  wxString netName = FROM_UTF8( p );
206 
207  if( (char) netName[0] == '?' ) // ? indicates no net connected to pin.
208  netName = wxEmptyString;
209 
210  aComponent->AddNet( pinName, netName );
211 }
212 
213 
215 {
216  wxArrayString filters;
217  wxString cmpRef;
218  char* line;
219  COMPONENT* component = NULL; // Suppress compil warning
220 
221  while( ( line = m_lineReader->ReadLine() ) != NULL )
222  {
223  if( strncasecmp( line, "$endlist", 8 ) == 0 ) // end of list for the current component
224  {
225  wxASSERT( component != NULL );
226  component->SetFootprintFilters( filters );
227  component = NULL;
228  filters.Clear();
229  continue;
230  }
231 
232  if( strncasecmp( line, "$endfootprintlist", 4 ) == 0 )
233  // End of this section
234  return;
235 
236  if( strncasecmp( line, "$component", 10 ) == 0 ) // New component reference found
237  {
238  cmpRef = FROM_UTF8( line + 11 );
239  cmpRef.Trim( true );
240  cmpRef.Trim( false );
241 
242  component = m_netlist->GetComponentByReference( cmpRef );
243 
244  // Cannot happen if the netlist is valid.
245  if( component == NULL )
246  {
247  wxString msg;
248  msg.Printf( _( "Cannot find component \'%s\' in footprint filter section "
249  "of netlist." ), GetChars( cmpRef ) );
251  m_lineReader->Length() );
252  }
253  }
254  else
255  {
256  // Add new filter to list
257  wxString fp = FROM_UTF8( line + 1 );
258  fp.Trim( false );
259  fp.Trim( true );
260  filters.Add( fp );
261  }
262  }
263 }
virtual unsigned LineNumber() const
Function Line Number returns the line number of the last line read from this LINE_READER.
Definition: richio.h:159
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes...
Definition: macros.h:53
char * StrPurge(char *text)
Function StrPurge removes leading and training spaces, tabs and end of line chars in text return a po...
Definition: string.cpp:194
unsigned long timeStamp(wxXmlNode *aTree)
Make a unique time stamp.
NETLIST * m_netlist
The net list to read the file(s) into.
Class LIB_ID.
Definition: lib_id.h:56
void AddComponent(COMPONENT *aComponent)
Function AddComponent adds aComponent to the NETLIST.
bool Load(NETLIST *aNetlist)
Function Load read the *.cmp file format contains the component footprint assignments created by CvPc...
void SetFootprintFilters(const wxArrayString &aFilterList)
Definition: pcb_netlist.h:170
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
Definition: ki_exception.h:133
char * Line() const
Function Line returns a pointer to the last line that was read in.
Definition: richio.h:139
void loadNet(char *aText, COMPONENT *aComponent)
Function loadNet read a component net description from aText.
unsigned Length() const
Function Length returns the number of bytes in the last line read from this LINE_READER.
Definition: richio.h:168
int SetLibItemName(const UTF8 &aLibItemName, bool aTestForRev=true)
Function SetLibItemName.
Definition: lib_id.cpp:232
Class COMPONENT is used to store components and all of their related information found in a netlist...
Definition: pcb_netlist.h:83
bool m_loadFootprintFilters
Load the component footprint filters section if true.
virtual void LoadNetlist() override
Function LoadNetlist read the netlist file in the legacy format into aNetlist.
virtual char * ReadLine()=0
Function ReadLine reads a line of text into the buffer and increments the line number counter...
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
void SetName(const wxString &aName)
Definition: pcb_netlist.h:143
virtual const wxString & GetSource() const
Function GetSource returns the name of the source of the lines in an abstract sense.
Definition: richio.h:130
void AddNet(const wxString &aPinName, const wxString &aNetName)
Definition: pcb_netlist.h:130
const char * name
void loadFootprintFilters()
Function loadFootprintFilters loads the footprint filter section of netlist file. ...
COMPONENT * GetComponentByReference(const wxString &aReference)
Function GetComponentByReference returns a COMPONENT by aReference.
LINE_READER * m_lineReader
The line reader of the netlist.
COMPONENT * loadComponent(char *aText)
Function loadComponent read the aLine containing the description of a component from a legacy format ...
CMP_READER * m_footprintReader
The reader used to load the footprint links. If NULL, footprint links are not read.