KiCad PCB EDA Suite
sch_legacy_plugin.cpp File Reference
#include <algorithm>
#include <boost/algorithm/string/join.hpp>
#include <cctype>
#include <mutex>
#include <set>
#include <wx/mstream.h>
#include <wx/filename.h>
#include <wx/log.h>
#include <wx/textfile.h>
#include <wx/tokenzr.h>
#include <wx_filename.h>
#include <kiway.h>
#include <string_utils.h>
#include <locale_io.h>
#include <richio.h>
#include <trace_helpers.h>
#include <trigo.h>
#include <progress_reporter.h>
#include <general.h>
#include <sch_bitmap.h>
#include <sch_bus_entry.h>
#include <sch_symbol.h>
#include <sch_junction.h>
#include <sch_line.h>
#include <sch_marker.h>
#include <sch_no_connect.h>
#include <sch_text.h>
#include <sch_sheet.h>
#include <sch_sheet_pin.h>
#include <bus_alias.h>
#include <sch_plugins/legacy/sch_legacy_plugin.h>
#include <sch_screen.h>
#include <schematic.h>
#include <symbol_library.h>
#include <lib_shape.h>
#include <lib_field.h>
#include <lib_pin.h>
#include <lib_text.h>
#include <eeschema_id.h>
#include <tool/selection.h>

Go to the source code of this file.

Classes

class  SCH_LEGACY_PLUGIN_CACHE
 A cache assistant for the symbol library portion of the SCH_PLUGIN API, and only for the SCH_LEGACY_PLUGIN, so therefore is private to this implementation file, i.e. More...
 

Macros

#define Mils2Iu(x)   Mils2iu( x )
 
#define DOCFILE_IDENT   "EESchema-DOCLIB Version 2.0"
 
#define SCH_PARSE_ERROR(text, reader, pos)
 
#define T_STYLE   "style"
 
#define T_COLOR   "rgb"
 
#define T_COLORA   "rgba"
 
#define T_WIDTH   "width"
 

Functions

static bool is_eol (char c)
 
static bool strCompare (const char *aString, const char *aLine, const char **aOutput=nullptr)
 Compare aString to the string starting at aLine and advances the character point to the end of String and returns the new pointer position in aOutput if it is not NULL. More...
 
static int parseInt (LINE_READER &aReader, const char *aLine, const char **aOutput=nullptr)
 Parse an ASCII integer string with possible leading whitespace into an integer and updates the pointer at aOutput if it is not NULL, just like "man strtol()". More...
 
static uint32_t parseHex (LINE_READER &aReader, const char *aLine, const char **aOutput=nullptr)
 Parse an ASCII hex integer string with possible leading whitespace into a long integer and updates the pointer at aOutput if it is not NULL, just like "man strtoll". More...
 
static double parseDouble (LINE_READER &aReader, const char *aLine, const char **aOutput=nullptr)
 Parses an ASCII point string with possible leading whitespace into a double precision floating point number and updates the pointer at aOutput if it is not NULL, just like "man strtod". More...
 
static char parseChar (LINE_READER &aReader, const char *aCurrentToken, const char **aNextToken=nullptr)
 Parse a single ASCII character and updates the pointer at aOutput if it is not NULL. More...
 
static void parseUnquotedString (wxString &aString, LINE_READER &aReader, const char *aCurrentToken, const char **aNextToken=nullptr, bool aCanBeEmpty=false)
 Parse an unquoted utf8 string and updates the pointer at aOutput if it is not NULL. More...
 
static void parseQuotedString (wxString &aString, LINE_READER &aReader, const char *aCurrentToken, const char **aNextToken=nullptr, bool aCanBeEmpty=false)
 Parse an quoted ASCII utf8 and updates the pointer at aOutput if it is not NULL. More...
 

Variables

const char * delims = " \t\r\n"
 
const std::map< PINSHEETLABEL_SHAPE, const char * > sheetLabelNames
 

Macro Definition Documentation

◆ DOCFILE_IDENT

#define DOCFILE_IDENT   "EESchema-DOCLIB Version 2.0"

Definition at line 71 of file sch_legacy_plugin.cpp.

◆ Mils2Iu

#define Mils2Iu (   x)    Mils2iu( x )

Definition at line 67 of file sch_legacy_plugin.cpp.

◆ SCH_PARSE_ERROR

#define SCH_PARSE_ERROR (   text,
  reader,
  pos 
)
Value:
THROW_PARSE_ERROR( text, reader.GetSource(), reader.Line(), \
reader.LineNumber(), pos - reader.Line() )
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
Definition: ki_exception.h:164

Definition at line 73 of file sch_legacy_plugin.cpp.

◆ T_COLOR

#define T_COLOR   "rgb"

Definition at line 83 of file sch_legacy_plugin.cpp.

◆ T_COLORA

#define T_COLORA   "rgba"

Definition at line 84 of file sch_legacy_plugin.cpp.

◆ T_STYLE

#define T_STYLE   "style"

Definition at line 82 of file sch_legacy_plugin.cpp.

◆ T_WIDTH

#define T_WIDTH   "width"

Definition at line 85 of file sch_legacy_plugin.cpp.

Function Documentation

◆ is_eol()

static bool is_eol ( char  c)
static

Definition at line 88 of file sch_legacy_plugin.cpp.

89 {
90  // The default file eol character used internally by KiCad.
91  // |
92  // | Possible eol if someone edited the file by hand on certain platforms.
93  // | |
94  // | | May have gone past eol with strtok().
95  // | | |
96  if( c == '\n' || c == '\r' || c == 0 )
97  return true;
98 
99  return false;
100 }

Referenced by SCH_LEGACY_PLUGIN_CACHE::loadText(), and SCH_LEGACY_PLUGIN::loadWire().

◆ parseChar()

static char parseChar ( LINE_READER aReader,
const char *  aCurrentToken,
const char **  aNextToken = nullptr 
)
static

Parse a single ASCII character and updates the pointer at aOutput if it is not NULL.

Parameters
aReader- The line reader used to generate exception throw information.
aCurrentToken- A pointer the current position in a string.
aNextToken- The pointer to a string pointer to copy the string pointer position when the parsing is complete.
Returns
A valid ASCII character.
Exceptions
IO_ERRORon an unexpected end of line.
PARSE_ERRORif the parsed token is not a single character token.

Definition at line 277 of file sch_legacy_plugin.cpp.

279 {
280  while( *aCurrentToken && isspace( *aCurrentToken ) )
281  aCurrentToken++;
282 
283  if( !*aCurrentToken )
284  SCH_PARSE_ERROR( _( "unexpected end of line" ), aReader, aCurrentToken );
285 
286  if( !isspace( *( aCurrentToken + 1 ) ) )
287  SCH_PARSE_ERROR( "expected single character token", aReader, aCurrentToken );
288 
289  if( aNextToken )
290  {
291  const char* next = aCurrentToken + 2;
292 
293  while( *next && isspace( *next ) )
294  next++;
295 
296  *aNextToken = next;
297  }
298 
299  return *aCurrentToken;
300 }
CITER next(CITER it)
Definition: ptree.cpp:126
#define _(s)
#define SCH_PARSE_ERROR(text, reader, pos)

References _, next(), and SCH_PARSE_ERROR.

Referenced by SCH_LEGACY_PLUGIN_CACHE::loadField(), SCH_LEGACY_PLUGIN::loadSheet(), SCH_LEGACY_PLUGIN::loadSymbol(), SCH_LEGACY_PLUGIN_CACHE::loadText(), and SCH_LEGACY_PLUGIN_CACHE::parseFillMode().

◆ parseDouble()

static double parseDouble ( LINE_READER aReader,
const char *  aLine,
const char **  aOutput = nullptr 
)
static

Parses an ASCII point string with possible leading whitespace into a double precision floating point number and updates the pointer at aOutput if it is not NULL, just like "man strtod".

Parameters
aReader- The line reader used to generate exception throw information.
aLine- A pointer the current position in a string.
aOutput- The pointer to a string pointer to copy the string pointer position when the parsing is complete.
Returns
A valid double value.
Exceptions
IO_ERRORon an unexpected end of line.
PARSE_ERRORif the parsed token is not a valid integer.

Definition at line 236 of file sch_legacy_plugin.cpp.

238 {
239  if( !*aLine )
240  SCH_PARSE_ERROR( _( "unexpected end of line" ), aReader, aLine );
241 
242  // Clear errno before calling strtod() in case some other crt call set it.
243  errno = 0;
244 
245  double retv = strtod( aLine, (char**) aOutput );
246 
247  // Make sure no error occurred when calling strtod().
248  if( errno == ERANGE )
249  SCH_PARSE_ERROR( "invalid floating point number", aReader, aLine );
250 
251  // strtod does not strip off whitespace before the next token.
252  if( aOutput )
253  {
254  const char* next = *aOutput;
255 
256  while( *next && isspace( *next ) )
257  next++;
258 
259  *aOutput = next;
260  }
261 
262  return retv;
263 }
CITER next(CITER it)
Definition: ptree.cpp:126
#define _(s)
#define SCH_PARSE_ERROR(text, reader, pos)

References _, next(), and SCH_PARSE_ERROR.

Referenced by SCH_LEGACY_PLUGIN::loadBitmap(), PCB_PARSER::parse3DModel(), PCB_PARSER::parseBoardStackup(), PCB_PARSER::parseBoardUnits(), PCB_PARSER::parseFOOTPRINT_unchecked(), PCB_PARSER::parsePAD(), PCB_PARSER::parsePAGE_INFO(), PCB_PARSER::parseSetup(), and PCB_PARSER::parseZONE().

◆ parseHex()

static uint32_t parseHex ( LINE_READER aReader,
const char *  aLine,
const char **  aOutput = nullptr 
)
static

Parse an ASCII hex integer string with possible leading whitespace into a long integer and updates the pointer at aOutput if it is not NULL, just like "man strtoll".

Parameters
aReader- The line reader used to generate exception throw information.
aLine- A pointer the current position in a string.
aOutput- The pointer to a string pointer to copy the string pointer position when the parsing is complete.
Returns
A valid uint32_t value.
Exceptions
IO_ERRORon an unexpected end of line.
PARSE_ERRORif the parsed token is not a valid integer.

Definition at line 191 of file sch_legacy_plugin.cpp.

192 {
193  if( !*aLine )
194  SCH_PARSE_ERROR( _( "unexpected end of line" ), aReader, aLine );
195 
196  // Due to some issues between some files created by a 64 bits version and those
197  // created by a 32 bits version, we use here a temporary at least 64 bits storage:
198  unsigned long long retv;
199 
200  // Clear errno before calling strtoull() in case some other crt call set it.
201  errno = 0;
202  retv = strtoull( aLine, (char**) aOutput, 16 );
203 
204  // Make sure no error occurred when calling strtoull().
205  if( errno == ERANGE )
206  SCH_PARSE_ERROR( "invalid hexadecimal number", aReader, aLine );
207 
208  // Strip off whitespace before the next token.
209  if( aOutput )
210  {
211  const char* next = *aOutput;
212 
213  while( *next && isspace( *next ) )
214  next++;
215 
216  *aOutput = next;
217  }
218 
219  return (uint32_t)retv;
220 }
CITER next(CITER it)
Definition: ptree.cpp:126
#define _(s)
#define SCH_PARSE_ERROR(text, reader, pos)

References _, next(), and SCH_PARSE_ERROR.

Referenced by SCH_LEGACY_PLUGIN::loadSymbol(), PCB_PARSER::parseARC(), PCB_PARSER::parseFOOTPRINT_unchecked(), PCB_PARSER::parseFP_SHAPE(), PCB_PARSER::parsePCB_SHAPE(), PCB_PARSER::parsePCB_TRACK(), PCB_PARSER::parsePCB_VIA(), and PCB_PARSER::parseSetup().

◆ parseInt()

static int parseInt ( LINE_READER aReader,
const char *  aLine,
const char **  aOutput = nullptr 
)
static

Parse an ASCII integer string with possible leading whitespace into an integer and updates the pointer at aOutput if it is not NULL, just like "man strtol()".

Parameters
aReader- The line reader used to generate exception throw information.
aLine- A pointer the current position in a string.
aOutput- The pointer to a string pointer to copy the string pointer position when the parsing is complete.
Returns
A valid integer value.
Exceptions
AnIO_ERROR on an unexpected end of line.
APARSE_ERROR if the parsed token is not a valid integer.

Definition at line 149 of file sch_legacy_plugin.cpp.

150 {
151  if( !*aLine )
152  SCH_PARSE_ERROR( _( "unexpected end of line" ), aReader, aLine );
153 
154  // Clear errno before calling strtol() in case some other crt call set it.
155  errno = 0;
156 
157  long retv = strtol( aLine, (char**) aOutput, 10 );
158 
159  // Make sure no error occurred when calling strtol().
160  if( errno == ERANGE )
161  SCH_PARSE_ERROR( "invalid integer value", aReader, aLine );
162 
163  // strtol does not strip off whitespace before the next token.
164  if( aOutput )
165  {
166  const char* next = *aOutput;
167 
168  while( *next && isspace( *next ) )
169  next++;
170 
171  *aOutput = next;
172  }
173 
174  return (int) retv;
175 }
CITER next(CITER it)
Definition: ptree.cpp:126
#define _(s)
#define SCH_PARSE_ERROR(text, reader, pos)

References _, next(), and SCH_PARSE_ERROR.

Referenced by SCH_LEGACY_PLUGIN_CACHE::Load(), SCH_LEGACY_PLUGIN_CACHE::loadArc(), SCH_LEGACY_PLUGIN_CACHE::loadBezier(), SCH_LEGACY_PLUGIN::loadBitmap(), SCH_LEGACY_PLUGIN::loadBusEntry(), SCH_LEGACY_PLUGIN_CACHE::loadCircle(), SCH_LEGACY_PLUGIN_CACHE::loadField(), SCH_LEGACY_PLUGIN::loadHeader(), SCH_LEGACY_PLUGIN::loadJunction(), SCH_LEGACY_PLUGIN::loadNoConnect(), SCH_LEGACY_PLUGIN::loadPageSettings(), SCH_LEGACY_PLUGIN_CACHE::loadPolyLine(), SCH_LEGACY_PLUGIN_CACHE::loadRect(), SCH_LEGACY_PLUGIN::loadSheet(), SCH_LEGACY_PLUGIN::loadSymbol(), SCH_LEGACY_PLUGIN::loadText(), SCH_LEGACY_PLUGIN_CACHE::loadText(), SCH_LEGACY_PLUGIN::loadWire(), PCB_PARSER::parseARC(), PCB_PARSER::parseDefaults(), PCB_PARSER::parseDIMENSION(), PCB_PARSER::parseFOOTPRINT_unchecked(), PCB_PARSER::parseHeader(), PCB_PARSER::parseLayer(), PCB_PARSER::parseNETINFO_ITEM(), PCB_PARSER::parsePAD(), PCB_PARSER::parsePCB_TRACK(), PCB_PARSER::parsePCB_VIA(), PCB_PARSER::parseTITLE_BLOCK(), and PCB_PARSER::parseZONE().

◆ parseQuotedString()

static void parseQuotedString ( wxString &  aString,
LINE_READER aReader,
const char *  aCurrentToken,
const char **  aNextToken = nullptr,
bool  aCanBeEmpty = false 
)
static

Parse an quoted ASCII utf8 and updates the pointer at aOutput if it is not NULL.

The parsed string must be contained within a single line. There are no multi-line quoted strings in the legacy schematic file format.

Parameters
aString- A reference to the parsed string.
aReader- The line reader used to generate exception throw information.
aCurrentToken- A pointer the current position in a string.
aNextToken- The pointer to a string pointer to copy the string pointer position when the parsing is complete.
aCanBeEmpty- True if the parsed string is optional. False if it is mandatory.
Exceptions
IO_ERRORon an unexpected end of line.
PARSE_ERRORif the aCanBeEmpty is false and no string was parsed.

Definition at line 379 of file sch_legacy_plugin.cpp.

382 {
383  if( !*aCurrentToken )
384  {
385  if( aCanBeEmpty )
386  return;
387  else
388  SCH_PARSE_ERROR( _( "unexpected end of line" ), aReader, aCurrentToken );
389  }
390 
391  const char* tmp = aCurrentToken;
392 
393  while( *tmp && isspace( *tmp ) )
394  tmp++;
395 
396  if( !*tmp )
397  {
398  if( aCanBeEmpty )
399  return;
400  else
401  SCH_PARSE_ERROR( _( "unexpected end of line" ), aReader, aCurrentToken );
402  }
403 
404  // Verify opening quote.
405  if( *tmp != '"' )
406  SCH_PARSE_ERROR( "expecting opening quote", aReader, aCurrentToken );
407 
408  tmp++;
409 
410  std::string utf8; // utf8 without escapes and quotes.
411 
412  // Fetch everything up to closing quote.
413  while( *tmp )
414  {
415  if( *tmp == '\\' )
416  {
417  tmp++;
418 
419  if( !*tmp )
420  SCH_PARSE_ERROR( _( "unexpected end of line" ), aReader, aCurrentToken );
421 
422  // Do not copy the escape byte if it is followed by \ or "
423  if( *tmp != '"' && *tmp != '\\' )
424  utf8 += '\\';
425 
426  utf8 += *tmp;
427  }
428  else if( *tmp == '"' ) // Closing double quote.
429  {
430  break;
431  }
432  else
433  {
434  utf8 += *tmp;
435  }
436 
437  tmp++;
438  }
439 
440  aString = FROM_UTF8( utf8.c_str() );
441 
442  if( aString.IsEmpty() && !aCanBeEmpty )
443  SCH_PARSE_ERROR( "expected quoted string", aReader, aCurrentToken );
444 
445  if( *tmp && *tmp != '"' )
446  SCH_PARSE_ERROR( "no closing quote for string found", aReader, tmp );
447 
448  // Move past the closing quote.
449  tmp++;
450 
451  if( aNextToken )
452  {
453  const char* next = tmp;
454 
455  while( *next == ' ' )
456  next++;
457 
458  *aNextToken = next;
459  }
460 }
CITER next(CITER it)
Definition: ptree.cpp:126
static wxString FROM_UTF8(const char *cstring)
Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:110
#define _(s)
#define SCH_PARSE_ERROR(text, reader, pos)

References _, FROM_UTF8(), next(), and SCH_PARSE_ERROR.

Referenced by SCH_LEGACY_PLUGIN_CACHE::loadField(), SCH_LEGACY_PLUGIN::loadPageSettings(), SCH_LEGACY_PLUGIN::loadSheet(), SCH_LEGACY_PLUGIN::loadSymbol(), and SCH_LEGACY_PLUGIN_CACHE::loadText().

◆ parseUnquotedString()

static void parseUnquotedString ( wxString &  aString,
LINE_READER aReader,
const char *  aCurrentToken,
const char **  aNextToken = nullptr,
bool  aCanBeEmpty = false 
)
static

Parse an unquoted utf8 string and updates the pointer at aOutput if it is not NULL.

The parsed string must be a continuous string with no white space.

Parameters
aString- A reference to the parsed string.
aReader- The line reader used to generate exception throw information.
aCurrentToken- A pointer the current position in a string.
aNextToken- The pointer to a string pointer to copy the string pointer position when the parsing is complete.
aCanBeEmpty- True if the parsed string is optional. False if it is mandatory.
Exceptions
IO_ERRORon an unexpected end of line.
PARSE_ERRORif the aCanBeEmpty is false and no string was parsed.

Definition at line 317 of file sch_legacy_plugin.cpp.

320 {
321  if( !*aCurrentToken )
322  {
323  if( aCanBeEmpty )
324  return;
325  else
326  SCH_PARSE_ERROR( _( "unexpected end of line" ), aReader, aCurrentToken );
327  }
328 
329  const char* tmp = aCurrentToken;
330 
331  while( *tmp && isspace( *tmp ) )
332  tmp++;
333 
334  if( !*tmp )
335  {
336  if( aCanBeEmpty )
337  return;
338  else
339  SCH_PARSE_ERROR( _( "unexpected end of line" ), aReader, aCurrentToken );
340  }
341 
342  std::string utf8;
343 
344  while( *tmp && !isspace( *tmp ) )
345  utf8 += *tmp++;
346 
347  aString = FROM_UTF8( utf8.c_str() );
348 
349  if( aString.IsEmpty() && !aCanBeEmpty )
350  SCH_PARSE_ERROR( _( "expected unquoted string" ), aReader, aCurrentToken );
351 
352  if( aNextToken )
353  {
354  const char* next = tmp;
355 
356  while( *next && isspace( *next ) )
357  next++;
358 
359  *aNextToken = next;
360  }
361 }
CITER next(CITER it)
Definition: ptree.cpp:126
static wxString FROM_UTF8(const char *cstring)
Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:110
#define _(s)
#define SCH_PARSE_ERROR(text, reader, pos)

References _, FROM_UTF8(), next(), and SCH_PARSE_ERROR.

Referenced by SCH_LEGACY_PLUGIN::loadBusAlias(), SCH_LEGACY_PLUGIN_CACHE::loadField(), SCH_LEGACY_PLUGIN_CACHE::loadFootprintFilters(), SCH_LEGACY_PLUGIN::loadJunction(), SCH_LEGACY_PLUGIN::loadNoConnect(), SCH_LEGACY_PLUGIN::loadPageSettings(), SCH_LEGACY_PLUGIN::loadSheet(), SCH_LEGACY_PLUGIN::loadSymbol(), SCH_LEGACY_PLUGIN_CACHE::loadText(), and SCH_LEGACY_PLUGIN::loadWire().

◆ strCompare()

static bool strCompare ( const char *  aString,
const char *  aLine,
const char **  aOutput = nullptr 
)
static

Compare aString to the string starting at aLine and advances the character point to the end of String and returns the new pointer position in aOutput if it is not NULL.

Parameters
aString- A pointer to the string to compare.
aLine- A pointer to string to begin the comparison.
aOutput- A pointer to a string pointer to the end of the comparison if not NULL.
Returns
true if aString was found starting at aLine. Otherwise false.

Definition at line 112 of file sch_legacy_plugin.cpp.

113 {
114  size_t len = strlen( aString );
115  bool retv = ( strncasecmp( aLine, aString, len ) == 0 ) &&
116  ( isspace( aLine[ len ] ) || aLine[ len ] == 0 );
117 
118  if( retv && aOutput )
119  {
120  const char* tmp = aLine;
121 
122  // Move past the end of the token.
123  tmp += len;
124 
125  // Move to the beginning of the next token.
126  while( *tmp && isspace( *tmp ) )
127  tmp++;
128 
129  *aOutput = tmp;
130  }
131 
132  return retv;
133 }

Referenced by SCH_LEGACY_PLUGIN_CACHE::Load(), SCH_LEGACY_PLUGIN_CACHE::loadAliases(), SCH_LEGACY_PLUGIN_CACHE::loadArc(), SCH_LEGACY_PLUGIN_CACHE::loadBezier(), SCH_LEGACY_PLUGIN::loadBitmap(), SCH_LEGACY_PLUGIN::loadBusAlias(), SCH_LEGACY_PLUGIN::loadBusEntry(), SCH_LEGACY_PLUGIN_CACHE::loadCircle(), SCH_LEGACY_PLUGIN::LoadContent(), SCH_LEGACY_PLUGIN_CACHE::loadDocs(), SCH_LEGACY_PLUGIN_CACHE::loadDrawEntries(), SCH_LEGACY_PLUGIN::loadFile(), SCH_LEGACY_PLUGIN_CACHE::loadFootprintFilters(), SCH_LEGACY_PLUGIN::loadHeader(), SCH_LEGACY_PLUGIN_CACHE::loadHeader(), SCH_LEGACY_PLUGIN::loadJunction(), SCH_LEGACY_PLUGIN::loadNoConnect(), SCH_LEGACY_PLUGIN::loadPageSettings(), SCH_LEGACY_PLUGIN_CACHE::LoadPart(), SCH_LEGACY_PLUGIN_CACHE::loadPin(), SCH_LEGACY_PLUGIN_CACHE::loadPolyLine(), SCH_LEGACY_PLUGIN_CACHE::loadRect(), SCH_LEGACY_PLUGIN::loadSheet(), SCH_LEGACY_PLUGIN::loadSymbol(), SCH_LEGACY_PLUGIN::loadText(), SCH_LEGACY_PLUGIN_CACHE::loadText(), and SCH_LEGACY_PLUGIN::loadWire().

Variable Documentation

◆ delims

const char* delims = " \t\r\n"

Definition at line 79 of file sch_legacy_plugin.cpp.

◆ sheetLabelNames