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-2017 KiCad Developers, see AUTHORS.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  throw( PARSE_ERROR, boost::bad_pointer )
101 {
102  char* text;
103  wxString msg;
104  wxString timeStamp; // the full time stamp read from netlist
105  wxString footprintName; // the footprint name read from netlist
106  wxString value; // the component value read from netlist
107  wxString reference; // the component schematic reference designator read from netlist
108  wxString name; // the name of component that was placed in the schematic
109  char line[1024];
110 
111  strncpy( line, aText, sizeof(line)-1 );
112  line[sizeof(line)-1] = '\0';
113 
114  value = wxT( "~" );
115 
116  // Sample component line: /40C08647 $noname R20 4.7K {Lib=R}
117 
118  // Read time stamp (first word)
119  if( ( text = strtok( line, " ()\t\n" ) ) == NULL )
120  {
121  msg = _( "Cannot parse time stamp in component section of netlist." );
122  THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), line, m_lineReader->LineNumber(),
123  m_lineReader->Length() );
124  }
125 
126  timeStamp = FROM_UTF8( text );
127 
128  // Read footprint name (second word)
129  if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL )
130  {
131  msg = _( "Cannot parse footprint name in component section of netlist." );
132  THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), aText, m_lineReader->LineNumber(),
133  m_lineReader->Length() );
134  }
135 
136  footprintName = FROM_UTF8( text );
137 
138  // The footprint name will have to be looked up in the *.cmp file.
139  if( footprintName == wxT( "$noname" ) )
140  footprintName = wxEmptyString;
141 
142  // Read schematic reference designator (third word)
143  if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL )
144  {
145  msg = _( "Cannot parse reference designator in component section of netlist." );
146  THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), aText, m_lineReader->LineNumber(),
147  m_lineReader->Length() );
148  }
149 
150  reference = FROM_UTF8( text );
151 
152  // Read schematic value (forth word)
153  if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL )
154  {
155  msg = _( "Cannot parse value in component section of netlist." );
156  THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), aText, m_lineReader->LineNumber(),
157  m_lineReader->Length() );
158  }
159 
160  value = FROM_UTF8( text );
161 
162  // Read component name (fifth word) {Lib=C}
163  // This is an optional field (a comment), which does not always exists
164  if( ( text = strtok( NULL, " ()\t\n" ) ) != NULL )
165  {
166  name = FROM_UTF8( text ).AfterFirst( wxChar( '=' ) ).BeforeLast( wxChar( '}' ) );
167  }
168 
169  LIB_ID fpid;
170 
171  if( !footprintName.IsEmpty() )
172  fpid.SetLibItemName( TO_UTF8( footprintName ) );
173 
174  COMPONENT* component = new COMPONENT( fpid, reference, value, timeStamp );
175  component->SetName( name );
176  m_netlist->AddComponent( component );
177  return component;
178 }
179 
180 
181 void LEGACY_NETLIST_READER::loadNet( char* aText, COMPONENT* aComponent ) throw( PARSE_ERROR )
182 {
183  wxString msg;
184  char* p;
185  char line[256];
186 
187  strncpy( line, aText, sizeof( line ) );
188  line[ sizeof(line) - 1 ] = '\0';
189 
190  if( ( p = strtok( line, " ()\t\n" ) ) == NULL )
191  {
192  msg = _( "Cannot parse pin name in component net section of netlist." );
193  THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), line, m_lineReader->LineNumber(),
194  m_lineReader->Length() );
195  }
196 
197  wxString pinName = FROM_UTF8( p );
198 
199  if( ( p = strtok( NULL, " ()\t\n" ) ) == NULL )
200  {
201  msg = _( "Cannot parse net name in component net section of netlist." );
202  THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), line, m_lineReader->LineNumber(),
203  m_lineReader->Length() );
204  }
205 
206  wxString netName = FROM_UTF8( p );
207 
208  if( (char) netName[0] == '?' ) // ? indicates no net connected to pin.
209  netName = wxEmptyString;
210 
211  aComponent->AddNet( pinName, netName );
212 }
213 
214 
216 {
217  wxArrayString filters;
218  wxString cmpRef;
219  char* line;
220  COMPONENT* component = NULL; // Suppress compil warning
221 
222  while( ( line = m_lineReader->ReadLine() ) != NULL )
223  {
224  if( strncasecmp( line, "$endlist", 8 ) == 0 ) // end of list for the current component
225  {
226  wxASSERT( component != NULL );
227  component->SetFootprintFilters( filters );
228  component = NULL;
229  filters.Clear();
230  continue;
231  }
232 
233  if( strncasecmp( line, "$endfootprintlist", 4 ) == 0 )
234  // End of this section
235  return;
236 
237  if( strncasecmp( line, "$component", 10 ) == 0 ) // New component reference found
238  {
239  cmpRef = FROM_UTF8( line + 11 );
240  cmpRef.Trim( true );
241  cmpRef.Trim( false );
242 
243  component = m_netlist->GetComponentByReference( cmpRef );
244 
245  // Cannot happen if the netlist is valid.
246  if( component == NULL )
247  {
248  wxString msg;
249  msg.Printf( _( "Cannot find component \'%s\' in footprint filter section "
250  "of netlist." ), GetChars( cmpRef ) );
252  m_lineReader->Length() );
253  }
254  }
255  else
256  {
257  // Add new filter to list
258  wxString fp = FROM_UTF8( line + 1 );
259  fp.Trim( false );
260  fp.Trim( true );
261  filters.Add( fp );
262  }
263  }
264 }
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
NETLIST * m_netlist
The net list to read the file(s) into.
Class LIB_ID.
Definition: lib_id.h:56
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
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.
Struct PARSE_ERROR contains a filename or source description, a problem input line, a line number, a byte offset, and an error message which contains the the caller's report and his call site information: CPP source file, function, and line number.
Definition: ki_exception.h:94
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 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.
Struct IO_ERROR is a class used to hold an error message and may be used when throwing exceptions con...
Definition: ki_exception.h:47
static unsigned long timeStamp(CPTREE &aTree)
Make a unique time stamp.
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.