KiCad PCB EDA Suite
PCB_PARSER Class Reference

Class PCB_PARSER reads a Pcbnew s-expression formatted LINE_READER object and returns the appropriate BOARD_ITEM object. More...

#include <pcb_parser.h>

Inheritance diagram for PCB_PARSER:
CLIPBOARD_PARSER

Public Member Functions

 PCB_PARSER (LINE_READER *aReader=NULL)
 
LINE_READERSetLineReader (LINE_READER *aReader)
 Function SetLineReader sets aLineReader into the parser, and returns the previous one, if any. More...
 
void SetBoard (BOARD *aBoard)
 
BOARD_ITEMParse ()
 
MODULEparseMODULE (wxArrayString *aInitialComments=0)
 Function parseMODULE. More...
 
bool IsTooRecent ()
 Return whether a version number, if any was parsed, was too recent. More...
 
wxString GetRequiredVersion ()
 Return a string representing the version of kicad required to open this file. More...
 

Private Types

typedef std::unordered_map< std::string, PCB_LAYER_IDLAYER_ID_MAP
 
typedef std::unordered_map< std::string, LSETLSET_MAP
 

Private Member Functions

int getNetCode (int aNetCode)
 

Converts net code using the mapping table if available, otherwise returns unchanged net code if < 0 or if is is out of range

More...
 
void pushValueIntoMap (int aIndex, int aValue)
 function pushValueIntoMap Add aValue value in netcode mapping (m_netCodes) at index aIndex ensure there is room in m_netCodes for that, and add room if needed. More...
 
void init ()
 Function init clears and re-establishes m_layerMap with the default layer names. More...
 
void parseHeader ()
 
void parseGeneralSection ()
 
void parsePAGE_INFO ()
 
void parseTITLE_BLOCK ()
 
void parseLayers ()
 
void parseLayer (LAYER *aLayer)
 
void parseSetup ()
 
void parseNETINFO_ITEM ()
 
void parseNETCLASS ()
 
DRAWSEGMENTparseDRAWSEGMENT ()
 
TEXTE_PCBparseTEXTE_PCB ()
 
DIMENSIONparseDIMENSION ()
 
MODULEparseMODULE_unchecked (wxArrayString *aInitialComments=0)
 Function parseMODULE_unchecked Parse a module, but do not replace PARSE_ERROR with FUTURE_FORMAT_ERROR automatically. More...
 
TEXTE_MODULEparseTEXTE_MODULE ()
 
EDGE_MODULEparseEDGE_MODULE ()
 
D_PADparseD_PAD (MODULE *aParent=NULL)
 
bool parseD_PAD_option (D_PAD *aPad)
 
TRACKparseTRACK ()
 
VIAparseVIA ()
 
ZONE_CONTAINERparseZONE_CONTAINER ()
 
PCB_TARGETparsePCB_TARGET ()
 
BOARDparseBOARD ()
 
BOARDparseBOARD_unchecked ()
 Function parseBOARD_unchecked Parse a module, but do not replace PARSE_ERROR with FUTURE_FORMAT_ERROR automatically. More...
 
template<class T , class M >
lookUpLayer (const M &aMap)
 Function lookUpLayer parses the current token for the layer definition of a BOARD_ITEM object. More...
 
PCB_LAYER_ID parseBoardItemLayer ()
 Function parseBoardItemLayer parses the layer definition of a BOARD_ITEM object. More...
 
LSET parseBoardItemLayersAsMask ()
 Function parseBoardItemLayersAsMask parses the layers definition of a BOARD_ITEM object. More...
 
wxPoint parseXY ()
 Function parseXY parses a coordinate pair (xy X Y) in board units (mm). More...
 
void parseXY (int *aX, int *aY)
 
void parseEDA_TEXT (EDA_TEXT *aText)
 Function parseEDA_TEXT parses the common settings for any object derived from EDA_TEXT. More...
 
MODULE_3D_SETTINGSparse3DModel ()
 
double parseDouble ()
 Function parseDouble parses the current token as an ASCII numeric string with possible leading whitespace into a double precision floating point number. More...
 
double parseDouble (const char *aExpected)
 
double parseDouble (PCB_KEYS_T::T aToken)
 
int parseBoardUnits ()
 
int parseBoardUnits (const char *aExpected)
 
int parseBoardUnits (PCB_KEYS_T::T aToken)
 
int parseInt ()
 
int parseInt (const char *aExpected)
 
long parseHex ()
 
bool parseBool ()
 
int parseVersion ()
 Parse a format version tag like (version 20160417) return the version. More...
 

Private Attributes

BOARDm_board
 
LAYER_ID_MAP m_layerIndices
 map layer name to it's index More...
 
LSET_MAP m_layerMasks
 map layer names to their masks More...
 
std::vector< int > m_netCodes
 net codes mapping for boards being loaded More...
 
bool m_tooRecent
 true if version parses as later than supported More...
 
int m_requiredVersion
 set to the KiCad format version this board requires More...
 

Detailed Description

Class PCB_PARSER reads a Pcbnew s-expression formatted LINE_READER object and returns the appropriate BOARD_ITEM object.

Definition at line 65 of file pcb_parser.h.

Member Typedef Documentation

typedef std::unordered_map< std::string, PCB_LAYER_ID > PCB_PARSER::LAYER_ID_MAP
private

Definition at line 67 of file pcb_parser.h.

typedef std::unordered_map< std::string, LSET > PCB_PARSER::LSET_MAP
private

Definition at line 68 of file pcb_parser.h.

Constructor & Destructor Documentation

PCB_PARSER::PCB_PARSER ( LINE_READER aReader = NULL)
inline

Definition at line 274 of file pcb_parser.h.

References init().

274  :
275  PCB_LEXER( aReader ),
276  m_board( 0 )
277  {
278  init();
279  }
BOARD * m_board
Definition: pcb_parser.h:70
void init()
Function init clears and re-establishes m_layerMap with the default layer names.
Definition: pcb_parser.cpp:56

Member Function Documentation

int PCB_PARSER::getNetCode ( int  aNetCode)
inlineprivate

Converts net code using the mapping table if available, otherwise returns unchanged net code if < 0 or if is is out of range

Definition at line 79 of file pcb_parser.h.

References init(), lookUpLayer(), parse3DModel(), parseBOARD(), parseBOARD_unchecked(), parseBoardItemLayer(), parseBoardItemLayersAsMask(), parseD_PAD(), parseD_PAD_option(), parseDIMENSION(), parseDouble(), parseDRAWSEGMENT(), parseEDA_TEXT(), parseEDGE_MODULE(), parseGeneralSection(), parseHeader(), parseLayer(), parseLayers(), parseMODULE_unchecked(), parseNETCLASS(), parseNETINFO_ITEM(), parsePAGE_INFO(), parsePCB_TARGET(), parseSetup(), parseTEXTE_MODULE(), parseTEXTE_PCB(), parseTITLE_BLOCK(), parseTRACK(), parseVIA(), parseXY(), parseZONE_CONTAINER(), and pushValueIntoMap().

80  {
81  if( ( aNetCode >= 0 ) && ( aNetCode < (int) m_netCodes.size() ) )
82  return m_netCodes[aNetCode];
83 
84  return aNetCode;
85  }
std::vector< int > m_netCodes
net codes mapping for boards being loaded
Definition: pcb_parser.h:73
wxString PCB_PARSER::GetRequiredVersion ( )

Return a string representing the version of kicad required to open this file.

Not particularly meaningful if IsTooRecent() returns false.

Definition at line 182 of file pcb_parser.cpp.

References err, and THROW_PARSE_ERROR.

Referenced by IsTooRecent(), CLIPBOARD_IO::Load(), and PCB_IO::Load().

183 {
184  int year, month, day;
185 
186  year = m_requiredVersion / 10000;
187  month = ( m_requiredVersion / 100 ) - ( year * 100 );
188  day = m_requiredVersion - ( year * 10000 ) - ( month * 100 );
189 
190  // wx throws an assertion, not a catchable exception, when the date is invalid.
191  // User input shouldn't give wx asserts, so check manually and throw a proper
192  // error instead
193  if( day <= 0 || month <= 0 || month > 12 ||
194  day > wxDateTime::GetNumberOfDays( (wxDateTime::Month)( month - 1 ), year ) )
195  {
196  wxString err;
197  err.Printf( _( "Cannot interpret date code %d" ), m_requiredVersion );
198  THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
199  }
200 
201  wxDateTime date( day, (wxDateTime::Month)( month - 1 ), year, 0, 0, 0, 0 );
202  return date.FormatDate();
203 }
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
Definition: ki_exception.h:133
string & err
Definition: json11.cpp:598
int m_requiredVersion
set to the KiCad format version this board requires
Definition: pcb_parser.h:75
void PCB_PARSER::init ( )
private

Function init clears and re-establishes m_layerMap with the default layer names.

m_layerMap will have some of its entries overwritten whenever a (new) board is encountered.

Definition at line 56 of file pcb_parser.cpp.

References LSET::AllCuMask(), B_Adhes, B_CrtYd, B_Cu, B_Fab, B_Mask, B_Paste, B_SilkS, F_Adhes, F_CrtYd, F_Cu, F_Fab, F_Mask, F_Paste, F_SilkS, i, In15_Cu, LSET::Name(), PCB_LAYER_ID_COUNT, StrPrintf(), and TO_UTF8.

Referenced by getNetCode(), PCB_PARSER(), and SetBoard().

57 {
58  m_tooRecent = false;
60  m_layerIndices.clear();
61  m_layerMasks.clear();
62 
63  // Add untranslated default (i.e. english) layernames.
64  // Some may be overridden later if parsing a board rather than a footprint.
65  // The english name will survive if parsing only a footprint.
66  for( LAYER_NUM layer = 0; layer < PCB_LAYER_ID_COUNT; ++layer )
67  {
68  std::string untranslated = TO_UTF8( wxString( LSET::Name( PCB_LAYER_ID( layer ) ) ) );
69 
70  m_layerIndices[ untranslated ] = PCB_LAYER_ID( layer );
71  m_layerMasks[ untranslated ] = LSET( PCB_LAYER_ID( layer ) );
72  }
73 
74  m_layerMasks[ "*.Cu" ] = LSET::AllCuMask();
75  m_layerMasks[ "F&B.Cu" ] = LSET( 2, F_Cu, B_Cu );
76  m_layerMasks[ "*.Adhes" ] = LSET( 2, B_Adhes, F_Adhes );
77  m_layerMasks[ "*.Paste" ] = LSET( 2, B_Paste, F_Paste );
78  m_layerMasks[ "*.Mask" ] = LSET( 2, B_Mask, F_Mask );
79  m_layerMasks[ "*.SilkS" ] = LSET( 2, B_SilkS, F_SilkS );
80  m_layerMasks[ "*.Fab" ] = LSET( 2, B_Fab, F_Fab );
81  m_layerMasks[ "*.CrtYd" ] = LSET( 2, B_CrtYd, F_CrtYd );
82 
83  // This is for the first pretty & *.kicad_pcb formats, which had
84  // Inner1_Cu - Inner14_Cu with the numbering sequence
85  // reversed from the subsequent format's In1_Cu - In30_Cu numbering scheme.
86  // The newer format brought in an additional 16 Cu layers and flipped the cu stack but
87  // kept the gap between one of the outside layers and the last cu internal.
88 
89  for( int i=1; i<=14; ++i )
90  {
91  std::string key = StrPrintf( "Inner%d.Cu", i );
92 
93  m_layerMasks[ key ] = LSET( PCB_LAYER_ID( In15_Cu - i ) );
94  }
95 
96 #if defined(DEBUG) && 0
97  printf( "m_layerMasks:\n" );
98  for( LSET_MAP::const_iterator it = m_layerMasks.begin(); it != m_layerMasks.end(); ++it )
99  {
100  printf( " [%s] == 0x%s\n", it->first.c_str(), it->second.FmtHex().c_str() );
101  }
102 
103  printf( "m_layerIndices:\n" );
104  for( LAYER_ID_MAP::const_iterator it = m_layerIndices.begin(); it != m_layerIndices.end(); ++it )
105  {
106  printf( " [%s] == %d\n", it->first.c_str(), it->second );
107  }
108 #endif
109 
110 }
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Function AllCuMask returns a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:673
bool m_tooRecent
true if version parses as later than supported
Definition: pcb_parser.h:74
int StrPrintf(std::string *result, const char *format,...)
Function StrPrintf is like sprintf() but the output is appended to a std::string instead of to a char...
Definition: richio.cpp:74
#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
PCB_LAYER_ID
A quick note on layer IDs:
Class LSET is a set of PCB_LAYER_IDs.
static const wxChar * Name(PCB_LAYER_ID aLayerId)
Function Name returns the fixed name association with aLayerId.
Definition: lset.cpp:73
int LAYER_NUM
Type LAYER_NUM can be replaced with int and removed.
int m_requiredVersion
set to the KiCad format version this board requires
Definition: pcb_parser.h:75
size_t i
Definition: json11.cpp:597
LAYER_ID_MAP m_layerIndices
map layer name to it&#39;s index
Definition: pcb_parser.h:71
LSET_MAP m_layerMasks
map layer names to their masks
Definition: pcb_parser.h:72
bool PCB_PARSER::IsTooRecent ( )
inline

Return whether a version number, if any was parsed, was too recent.

Definition at line 314 of file pcb_parser.h.

References GetRequiredVersion(), and m_tooRecent.

Referenced by CLIPBOARD_IO::Load(), and PCB_IO::Load().

315  {
316  return m_tooRecent;
317  }
bool m_tooRecent
true if version parses as later than supported
Definition: pcb_parser.h:74
template<class T , class M >
T PCB_PARSER::lookUpLayer ( const M &  aMap)
private

Function lookUpLayer parses the current token for the layer definition of a BOARD_ITEM object.

Parameters
aMapis the LAYER_{NUM|MSK}_MAP to use for the lookup.
Exceptions
IO_ERRORif the layer is not valid.
PARSE_ERRORif the layer syntax is incorrect.
Returns
int - The result of the parsed BOARD_ITEM layer or set designator.

Definition at line 963 of file pcb_parser.cpp.

References Format(), FROM_UTF8(), GetChars(), and THROW_IO_ERROR.

Referenced by getNetCode().

964 {
965  // avoid constructing another std::string, use lexer's directly
966  typename M::const_iterator it = aMap.find( curText );
967 
968  if( it == aMap.end() )
969  {
970 #if 0 && defined(DEBUG)
971  // dump the whole darn table, there's something wrong with it.
972  for( it = aMap.begin(); it != aMap.end(); ++it )
973  {
974  wxLogDebug( &aMap == (void*)&m_layerIndices ? wxT( "lm[%s] = %d" ) :
975  wxT( "lm[%s] = %08X" ), it->first.c_str(), it->second );
976  }
977 #endif
978 
979  wxString error = wxString::Format( _(
980  "Layer \"%s\" in file\n"
981  "\"%s\"\n"
982  "at line %d, position %d\n"
983  "was not defined in the layers section"
984  ),
985  GetChars( FROM_UTF8( CurText() ) ),
986  GetChars( CurSource() ),
987  CurLineNumber(), CurOffset() );
988 
989  THROW_IO_ERROR( error );
990  }
991 
992  return it->second;
993 }
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
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 Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
LAYER_ID_MAP m_layerIndices
map layer name to it&#39;s index
Definition: pcb_parser.h:71
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
BOARD_ITEM * PCB_PARSER::Parse ( )

Definition at line 442 of file pcb_parser.cpp.

References err, GetChars(), and THROW_PARSE_ERROR.

Referenced by GITHUB_PLUGIN::FootprintLoad(), CLIPBOARD_IO::Load(), PCB_IO::Load(), and SetBoard().

443 {
444  T token;
445  BOARD_ITEM* item;
446  LOCALE_IO toggle;
447 
448  // MODULEs can be prefixed with an initial block of single line comments and these
449  // are kept for Format() so they round trip in s-expression form. BOARDs might
450  // eventually do the same, but currently do not.
451  std::unique_ptr<wxArrayString> initial_comments( ReadCommentLines() );
452 
453  token = CurTok();
454 
455  if( token != T_LEFT )
456  Expecting( T_LEFT );
457 
458  switch( NextTok() )
459  {
460  case T_kicad_pcb:
461  if( m_board == NULL )
462  m_board = new BOARD();
463 
464  item = (BOARD_ITEM*) parseBOARD();
465  break;
466 
467  case T_module:
468  item = (BOARD_ITEM*) parseMODULE( initial_comments.release() );
469  break;
470 
471  default:
472  wxString err;
473  err.Printf( _( "Unknown token \"%s\"" ), GetChars( FromUTF8() ) );
474  THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
475  }
476 
477  return item;
478 }
Class LOCALE_IO is a class that can be instantiated within a scope in which you are expecting excepti...
Definition: common.h:166
Class BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class...
BOARD * parseBOARD()
Definition: pcb_parser.cpp:481
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
Definition: ki_exception.h:133
string & err
Definition: json11.cpp:598
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
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:169
BOARD * m_board
Definition: pcb_parser.h:70
MODULE * parseMODULE(wxArrayString *aInitialComments=0)
Function parseMODULE.
MODULE_3D_SETTINGS * PCB_PARSER::parse3DModel ( )
private

Definition at line 350 of file pcb_parser.cpp.

References MODULE_3D_SETTINGS::m_Filename, MODULE_3D_SETTINGS::m_Offset, MODULE_3D_SETTINGS::m_Rotation, MODULE_3D_SETTINGS::m_Scale, parseDouble(), MODULE_3D_SETTINGS::VECTOR3D::x, MODULE_3D_SETTINGS::VECTOR3D::y, and MODULE_3D_SETTINGS::VECTOR3D::z.

Referenced by getNetCode().

351 {
352  wxCHECK_MSG( CurTok() == T_model, NULL,
353  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as MODULE_3D_SETTINGS." ) );
354 
355  T token;
356 
358  NeedSYMBOLorNUMBER();
359  n3D->m_Filename = FromUTF8();
360 
361  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
362  {
363  if( token != T_LEFT )
364  Expecting( T_LEFT );
365 
366  token = NextTok();
367 
368  switch( token )
369  {
370  case T_at:
371  NeedLEFT();
372  token = NextTok();
373 
374  if( token != T_xyz )
375  Expecting( T_xyz );
376 
377  /* Note:
378  * Prior to KiCad v5, model offset was designated by "at",
379  * and the units were in inches.
380  * Now we use mm, but support reading of legacy files
381  */
382 
383  n3D->m_Offset.x = parseDouble( "x value" ) * 25.4f;
384  n3D->m_Offset.y = parseDouble( "y value" ) * 25.4f;
385  n3D->m_Offset.z = parseDouble( "z value" ) * 25.4f;
386  NeedRIGHT();
387  break;
388 
389  case T_offset:
390  NeedLEFT();
391  token = NextTok();
392 
393  if( token != T_xyz )
394  Expecting( T_xyz );
395 
396  /*
397  * 3D model offset is in mm
398  */
399  n3D->m_Offset.x = parseDouble( "x value" );
400  n3D->m_Offset.y = parseDouble( "y value" );
401  n3D->m_Offset.z = parseDouble( "z value" );
402  NeedRIGHT();
403  break;
404 
405  case T_scale:
406  NeedLEFT();
407  token = NextTok();
408 
409  if( token != T_xyz )
410  Expecting( T_xyz );
411 
412  n3D->m_Scale.x = parseDouble( "x value" );
413  n3D->m_Scale.y = parseDouble( "y value" );
414  n3D->m_Scale.z = parseDouble( "z value" );
415  NeedRIGHT();
416  break;
417 
418  case T_rotate:
419  NeedLEFT();
420  token = NextTok();
421 
422  if( token != T_xyz )
423  Expecting( T_xyz );
424 
425  n3D->m_Rotation.x = parseDouble( "x value" );
426  n3D->m_Rotation.y = parseDouble( "y value" );
427  n3D->m_Rotation.z = parseDouble( "z value" );
428  NeedRIGHT();
429  break;
430 
431  default:
432  Expecting( "at, offset, scale, or rotate" );
433  }
434 
435  NeedRIGHT();
436  }
437 
438  return n3D;
439 }
VECTOR3D m_Offset
3D model offset (mm)
Definition: class_module.h:101
wxString m_Filename
The 3D shape filename in 3D library.
Definition: class_module.h:102
VECTOR3D m_Rotation
3D model rotation (degrees)
Definition: class_module.h:100
VECTOR3D m_Scale
3D model scaling factor (dimensionless)
Definition: class_module.h:99
double parseDouble()
Function parseDouble parses the current token as an ASCII numeric string with possible leading whites...
Definition: pcb_parser.cpp:124
BOARD * PCB_PARSER::parseBOARD ( )
private

Definition at line 481 of file pcb_parser.cpp.

Referenced by getNetCode().

482 {
483  try
484  {
485  return parseBOARD_unchecked();
486  }
487  catch( const PARSE_ERROR& parse_error )
488  {
489  if( m_tooRecent )
490  throw FUTURE_FORMAT_ERROR( parse_error, GetRequiredVersion() );
491  else
492  throw;
493  }
494 }
bool m_tooRecent
true if version parses as later than supported
Definition: pcb_parser.h:74
wxString GetRequiredVersion()
Return a string representing the version of kicad required to open this file.
Definition: pcb_parser.cpp:182
BOARD * parseBOARD_unchecked()
Function parseBOARD_unchecked Parse a module, but do not replace PARSE_ERROR with FUTURE_FORMAT_ERROR...
Definition: pcb_parser.cpp:497
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&#39;s report and his call site information: CPP source file, function, and line number.
Definition: ki_exception.h:94
Struct FUTURE_FORMAT_ERROR variant of PARSE_ERROR indicating that a syntax or related error was likel...
Definition: ki_exception.h:143
BOARD * PCB_PARSER::parseBOARD_unchecked ( )
private

Function parseBOARD_unchecked Parse a module, but do not replace PARSE_ERROR with FUTURE_FORMAT_ERROR automatically.

Definition at line 497 of file pcb_parser.cpp.

References ADD_APPEND, ADD_INSERT, err, GetChars(), and THROW_PARSE_ERROR.

Referenced by getNetCode().

498 {
499  T token;
500 
501  parseHeader();
502 
503  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
504  {
505  if( token != T_LEFT )
506  Expecting( T_LEFT );
507 
508  token = NextTok();
509 
510  switch( token )
511  {
512  case T_general:
514  break;
515 
516  case T_page:
517  parsePAGE_INFO();
518  break;
519 
520  case T_title_block:
522  break;
523 
524  case T_layers:
525  parseLayers();
526  break;
527 
528  case T_setup:
529  parseSetup();
530  break;
531 
532  case T_net:
534  break;
535 
536  case T_net_class:
537  parseNETCLASS();
538  break;
539 
540  case T_gr_arc:
541  case T_gr_circle:
542  case T_gr_curve:
543  case T_gr_line:
544  case T_gr_poly:
546  break;
547 
548  case T_gr_text:
550  break;
551 
552  case T_dimension:
554  break;
555 
556  case T_module:
558  break;
559 
560  case T_segment:
562  break;
563 
564  case T_via:
566  break;
567 
568  case T_zone:
570  break;
571 
572  case T_target:
574  break;
575 
576  default:
577  wxString err;
578  err.Printf( _( "Unknown token \"%s\"" ), GetChars( FromUTF8() ) );
579  THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
580  }
581  }
582 
583  return m_board;
584 }
void parseHeader()
Definition: pcb_parser.cpp:587
TRACK * parseTRACK()
VIA * parseVIA()
void parseNETINFO_ITEM()
DIMENSION * parseDIMENSION()
void parseTITLE_BLOCK()
Definition: pcb_parser.cpp:725
void parseLayers()
Definition: pcb_parser.cpp:850
void parsePAGE_INFO()
Definition: pcb_parser.cpp:669
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
Definition: ki_exception.h:133
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_INSERT) override
Adds an item to the container.
DRAWSEGMENT * parseDRAWSEGMENT()
PCB_TARGET * parsePCB_TARGET()
TEXTE_PCB * parseTEXTE_PCB()
void parseNETCLASS()
string & err
Definition: json11.cpp:598
ZONE_CONTAINER * parseZONE_CONTAINER()
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
BOARD * m_board
Definition: pcb_parser.h:70
void parseGeneralSection()
Definition: pcb_parser.cpp:623
MODULE * parseMODULE(wxArrayString *aInitialComments=0)
Function parseMODULE.
void parseSetup()
PCB_LAYER_ID PCB_PARSER::parseBoardItemLayer ( )
private

Function parseBoardItemLayer parses the layer definition of a BOARD_ITEM object.

Exceptions
IO_ERRORif the layer is not valid.
PARSE_ERRORif the layer syntax is incorrect.
Returns
The index the parsed BOARD_ITEM layer.

Definition at line 996 of file pcb_parser.cpp.

References UNDEFINED_LAYER.

Referenced by getNetCode().

997 {
998  wxCHECK_MSG( CurTok() == T_layer, UNDEFINED_LAYER,
999  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as layer." ) );
1000 
1001  NextTok();
1002 
1003  PCB_LAYER_ID layerIndex = lookUpLayer<PCB_LAYER_ID>( m_layerIndices );
1004 
1005  // Handle closing ) in object parser.
1006 
1007  return layerIndex;
1008 }
PCB_LAYER_ID
A quick note on layer IDs:
LAYER_ID_MAP m_layerIndices
map layer name to it&#39;s index
Definition: pcb_parser.h:71
LSET PCB_PARSER::parseBoardItemLayersAsMask ( )
private

Function parseBoardItemLayersAsMask parses the layers definition of a BOARD_ITEM object.

Exceptions
IO_ERRORif any of the layers is not valid.
PARSE_ERRORif the layers syntax is incorrect.
Returns
The mask of layers the parsed BOARD_ITEM is on.

Definition at line 1011 of file pcb_parser.cpp.

Referenced by getNetCode().

1012 {
1013  wxCHECK_MSG( CurTok() == T_layers, LSET(),
1014  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
1015  wxT( " as item layer mask." ) );
1016 
1017  LSET layerMask;
1018 
1019  for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
1020  {
1021  LSET mask = lookUpLayer<LSET>( m_layerMasks );
1022  layerMask |= mask;
1023  }
1024 
1025  return layerMask;
1026 }
Class LSET is a set of PCB_LAYER_IDs.
LSET_MAP m_layerMasks
map layer names to their masks
Definition: pcb_parser.h:72
int PCB_PARSER::parseBoardUnits ( )
inlineprivate

Definition at line 223 of file pcb_parser.h.

References KiROUND(), and parseDouble().

Referenced by parseBoardUnits().

224  {
225  // There should be no major rounding issues here, since the values in
226  // the file are in mm and get converted to nano-meters.
227  // See test program tools/test-nm-biu-to-ascii-mm-round-tripping.cpp
228  // to confirm or experiment. Use a similar strategy in both places, here
229  // and in the test program. Make that program with:
230  // $ make test-nm-biu-to-ascii-mm-round-tripping
231  return KiROUND( parseDouble() * IU_PER_MM );
232  }
static int KiROUND(double v)
KiROUND rounds a floating point number to an int using "round halfway cases away from zero"...
Definition: common.h:107
double parseDouble()
Function parseDouble parses the current token as an ASCII numeric string with possible leading whites...
Definition: pcb_parser.cpp:124
int PCB_PARSER::parseBoardUnits ( const char *  aExpected)
inlineprivate

Definition at line 234 of file pcb_parser.h.

References KiROUND(), and parseDouble().

235  {
236  // Use here KiROUND, not KIROUND (see comments about them)
237  // when having a function as argument, because it will be called twice
238  // with KIROUND
239  return KiROUND( parseDouble( aExpected ) * IU_PER_MM );
240  }
static int KiROUND(double v)
KiROUND rounds a floating point number to an int using "round halfway cases away from zero"...
Definition: common.h:107
double parseDouble()
Function parseDouble parses the current token as an ASCII numeric string with possible leading whites...
Definition: pcb_parser.cpp:124
int PCB_PARSER::parseBoardUnits ( PCB_KEYS_T::T  aToken)
inlineprivate

Definition at line 242 of file pcb_parser.h.

References DSN::GetTokenText(), and parseBoardUnits().

243  {
244  return parseBoardUnits( GetTokenText( aToken ) );
245  }
int parseBoardUnits()
Definition: pcb_parser.h:223
const char * GetTokenText(T aTok)
Function GetTokenText is in the DSN namespace and returns the C string representing a SPECCTRA_DB::ke...
Definition: specctra.cpp:69
bool PCB_PARSER::parseBool ( )
private

Definition at line 154 of file pcb_parser.cpp.

Referenced by parseHex().

155 {
156  T token = NextTok();
157 
158  if( token == T_yes )
159  return true;
160  else if( token == T_no )
161  return false;
162  else
163  Expecting( "yes or no" );
164 
165  return false;
166 }
D_PAD * PCB_PARSER::parseD_PAD ( MODULE aParent = NULL)
private

Definition at line 2289 of file pcb_parser.cpp.

References DRAWSEGMENT::BuildPolyPointsList(), delta, Format(), DRAWSEGMENT::GetAngle(), DRAWSEGMENT::GetArcStart(), DRAWSEGMENT::GetCenter(), GetChars(), DRAWSEGMENT::GetEnd(), DRAWSEGMENT::GetRadius(), DRAWSEGMENT::GetStart(), DRAWSEGMENT::GetWidth(), PAD_ATTRIB_CONN, PAD_ATTRIB_HOLE_NOT_PLATED, PAD_ATTRIB_SMD, PAD_ATTRIB_STANDARD, PAD_DRILL_SHAPE_OBLONG, PAD_SHAPE_CIRCLE, PAD_SHAPE_CUSTOM, PAD_SHAPE_OVAL, PAD_SHAPE_RECT, PAD_SHAPE_ROUNDRECT, PAD_SHAPE_TRAPEZOID, parseDouble(), parseInt(), THROW_IO_ERROR, wxPoint::x, and wxPoint::y.

Referenced by getNetCode().

2290 {
2291  wxCHECK_MSG( CurTok() == T_pad, NULL,
2292  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as D_PAD." ) );
2293 
2294  wxSize sz;
2295  wxPoint pt;
2296 
2297  std::unique_ptr< D_PAD > pad( new D_PAD( aParent ) );
2298 
2299  NeedSYMBOLorNUMBER();
2300  pad->SetName( FromUTF8() );
2301 
2302  T token = NextTok();
2303 
2304  switch( token )
2305  {
2306  case T_thru_hole:
2307  pad->SetAttribute( PAD_ATTRIB_STANDARD );
2308  break;
2309 
2310  case T_smd:
2311  pad->SetAttribute( PAD_ATTRIB_SMD );
2312 
2313  // Default D_PAD object is thru hole with drill.
2314  // SMD pads have no hole
2315  pad->SetDrillSize( wxSize( 0, 0 ) );
2316  break;
2317 
2318  case T_connect:
2319  pad->SetAttribute( PAD_ATTRIB_CONN );
2320 
2321  // Default D_PAD object is thru hole with drill.
2322  // CONN pads have no hole
2323  pad->SetDrillSize( wxSize( 0, 0 ) );
2324  break;
2325 
2326  case T_np_thru_hole:
2327  pad->SetAttribute( PAD_ATTRIB_HOLE_NOT_PLATED );
2328  break;
2329 
2330  default:
2331  Expecting( "thru_hole, smd, connect, or np_thru_hole" );
2332  }
2333 
2334  token = NextTok();
2335 
2336  switch( token )
2337  {
2338  case T_circle:
2339  pad->SetShape( PAD_SHAPE_CIRCLE );
2340  break;
2341 
2342  case T_rect:
2343  pad->SetShape( PAD_SHAPE_RECT );
2344  break;
2345 
2346  case T_oval:
2347  pad->SetShape( PAD_SHAPE_OVAL );
2348  break;
2349 
2350  case T_trapezoid:
2351  pad->SetShape( PAD_SHAPE_TRAPEZOID );
2352  break;
2353 
2354  case T_roundrect:
2355  pad->SetShape( PAD_SHAPE_ROUNDRECT );
2356  break;
2357 
2358  case T_custom:
2359  pad->SetShape( PAD_SHAPE_CUSTOM );
2360  break;
2361 
2362  default:
2363  Expecting( "circle, rectangle, roundrect, oval, trapezoid or custom" );
2364  }
2365 
2366  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2367  {
2368  if( token != T_LEFT )
2369  Expecting( T_LEFT );
2370 
2371  token = NextTok();
2372 
2373  switch( token )
2374  {
2375  case T_size:
2376  sz.SetWidth( parseBoardUnits( "width value" ) );
2377  sz.SetHeight( parseBoardUnits( "height value" ) );
2378  pad->SetSize( sz );
2379  NeedRIGHT();
2380  break;
2381 
2382  case T_at:
2383  pt.x = parseBoardUnits( "X coordinate" );
2384  pt.y = parseBoardUnits( "Y coordinate" );
2385  pad->SetPos0( pt );
2386  token = NextTok();
2387 
2388  if( token == T_NUMBER )
2389  {
2390  pad->SetOrientation( parseDouble() * 10.0 );
2391  NeedRIGHT();
2392  }
2393  else if( token != T_RIGHT )
2394  {
2395  Expecting( ") or angle value" );
2396  }
2397 
2398  break;
2399 
2400  case T_rect_delta:
2401  {
2402  wxSize delta;
2403  delta.SetWidth( parseBoardUnits( "rectangle delta width" ) );
2404  delta.SetHeight( parseBoardUnits( "rectangle delta height" ) );
2405  pad->SetDelta( delta );
2406  NeedRIGHT();
2407  }
2408  break;
2409 
2410  case T_drill:
2411  {
2412  bool haveWidth = false;
2413  wxSize drillSize = pad->GetDrillSize();
2414 
2415  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2416  {
2417  if( token == T_LEFT )
2418  token = NextTok();
2419 
2420  switch( token )
2421  {
2422  case T_oval:
2423  pad->SetDrillShape( PAD_DRILL_SHAPE_OBLONG );
2424  break;
2425 
2426  case T_NUMBER:
2427  {
2428  if( !haveWidth )
2429  {
2430  drillSize.SetWidth( parseBoardUnits() );
2431 
2432  // If height is not defined the width and height are the same.
2433  drillSize.SetHeight( drillSize.GetWidth() );
2434  haveWidth = true;
2435  }
2436  else
2437  {
2438  drillSize.SetHeight( parseBoardUnits() );
2439  }
2440 
2441  }
2442  break;
2443 
2444  case T_offset:
2445  pt.x = parseBoardUnits( "drill offset x" );
2446  pt.y = parseBoardUnits( "drill offset y" );
2447  pad->SetOffset( pt );
2448  NeedRIGHT();
2449  break;
2450 
2451  default:
2452  Expecting( "oval, size, or offset" );
2453  }
2454  }
2455 
2456  // This fixes a bug caused by setting the default D_PAD drill size to a value
2457  // other than 0 used to fix a bunch of debug assertions even though it is defined
2458  // as a through hole pad. Wouldn't a though hole pad with no drill be a surface
2459  // mount pad (or a conn pad which is a smd pad with no solder paste)?
2460  if( ( pad->GetAttribute() != PAD_ATTRIB_SMD ) && ( pad->GetAttribute() != PAD_ATTRIB_CONN ) )
2461  pad->SetDrillSize( drillSize );
2462  else
2463  pad->SetDrillSize( wxSize( 0, 0 ) );
2464 
2465  }
2466  break;
2467 
2468  case T_layers:
2469  {
2470  LSET layerMask = parseBoardItemLayersAsMask();
2471  pad->SetLayerSet( layerMask );
2472  }
2473  break;
2474 
2475  case T_net:
2476  if( ! pad->SetNetCode( getNetCode( parseInt( "net number" ) ), /* aNoAssert */ true ) )
2478  wxString::Format( _( "Invalid net ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),
2479  GetChars( CurSource() ), CurLineNumber(), CurOffset() )
2480  );
2481  NeedSYMBOLorNUMBER();
2482  if( m_board && FromUTF8() != m_board->FindNet( pad->GetNetCode() )->GetNetname() )
2484  wxString::Format( _( "Invalid net ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),
2485  GetChars( CurSource() ), CurLineNumber(), CurOffset() )
2486  );
2487  NeedRIGHT();
2488  break;
2489 
2490  case T_die_length:
2491  pad->SetPadToDieLength( parseBoardUnits( T_die_length ) );
2492  NeedRIGHT();
2493  break;
2494 
2495  case T_solder_mask_margin:
2496  pad->SetLocalSolderMaskMargin( parseBoardUnits( T_solder_mask_margin ) );
2497  NeedRIGHT();
2498  break;
2499 
2500  case T_solder_paste_margin:
2501  pad->SetLocalSolderPasteMargin( parseBoardUnits( T_solder_paste_margin ) );
2502  NeedRIGHT();
2503  break;
2504 
2505  case T_solder_paste_margin_ratio:
2506  pad->SetLocalSolderPasteMarginRatio(
2507  parseDouble( "pad local solder paste margin ratio value" ) );
2508  NeedRIGHT();
2509  break;
2510 
2511  case T_clearance:
2512  pad->SetLocalClearance( parseBoardUnits( "local clearance value" ) );
2513  NeedRIGHT();
2514  break;
2515 
2516  case T_zone_connect:
2517  pad->SetZoneConnection( (ZoneConnection) parseInt( "zone connection value" ) );
2518  NeedRIGHT();
2519  break;
2520 
2521  case T_thermal_width:
2522  pad->SetThermalWidth( parseBoardUnits( T_thermal_width ) );
2523  NeedRIGHT();
2524  break;
2525 
2526  case T_thermal_gap:
2527  pad->SetThermalGap( parseBoardUnits( T_thermal_gap ) );
2528  NeedRIGHT();
2529  break;
2530 
2531  case T_roundrect_rratio:
2532  pad->SetRoundRectRadiusRatio( parseDouble( "roundrect radius ratio" ) );
2533  NeedRIGHT();
2534  break;
2535 
2536  case T_options:
2537  parseD_PAD_option( pad.get() );
2538  break;
2539 
2540  case T_primitives:
2541  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2542  {
2543  if( token == T_LEFT )
2544  token = NextTok();
2545 
2546  // Currently, I am using parseDRAWSEGMENT() to read basic shapes parameters,
2547  // because they are the same as a DRAWSEGMENT.
2548  // However it could be better to write a specific parser, to avoid possible issues
2549  // if the DRAWSEGMENT parser is modified.
2550  DRAWSEGMENT* dummysegm = NULL;
2551 
2552  switch( token )
2553  {
2554  case T_gr_arc:
2555  dummysegm = parseDRAWSEGMENT();
2556  pad->AddPrimitive( dummysegm->GetCenter(), dummysegm->GetArcStart(),
2557  dummysegm->GetAngle(), dummysegm->GetWidth() );
2558  break;
2559 
2560  case T_gr_line:
2561  dummysegm = parseDRAWSEGMENT();
2562  pad->AddPrimitive( dummysegm->GetStart(), dummysegm->GetEnd(),
2563  dummysegm->GetWidth() );
2564  break;
2565 
2566  case T_gr_circle:
2567  dummysegm = parseDRAWSEGMENT();
2568  pad->AddPrimitive( dummysegm->GetCenter(), dummysegm->GetRadius(),
2569  dummysegm->GetWidth() );
2570  break;
2571 
2572  case T_gr_poly:
2573  dummysegm = parseDRAWSEGMENT();
2574  pad->AddPrimitive( dummysegm->BuildPolyPointsList(), dummysegm->GetWidth() );
2575  break;
2576 
2577  default:
2578  Expecting( "gr_line, gr_arc, gr_circle or gr_poly" );
2579  break;
2580  }
2581 
2582  delete dummysegm;
2583  }
2584  break;
2585 
2586  default:
2587  Expecting( "at, drill, layers, net, die_length, solder_mask_margin, roundrect_rratio,\n"
2588  "solder_paste_margin, solder_paste_margin_ratio, clearance,\n"
2589  "zone_connect, fp_poly, primitives, thermal_width, or thermal_gap" );
2590  }
2591  }
2592 
2593  // Be sure the custom shape polygon is built:
2594  if( pad->GetShape() == PAD_SHAPE_CUSTOM )
2595  pad->MergePrimitivesAsPolygon();
2596 
2597  return pad.release();
2598 }
LSET parseBoardItemLayersAsMask()
Function parseBoardItemLayersAsMask parses the layers definition of a BOARD_ITEM object.
const std::vector< wxPoint > BuildPolyPointsList() const
Build and return the list of corners in a std::vector<wxPoint> It must be used only to convert the SH...
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:65
const wxPoint GetCenter() const override
Function GetCenter()
ZoneConnection
How pads are covered by copper in zone.
Definition: zones.h:55
Smd pad, appears on the solder paste layer (default)
Definition: pad_shapes.h:61
bool parseD_PAD_option(D_PAD *aPad)
static const int delta[8][2]
Definition: solve.cpp:112
int parseBoardUnits()
Definition: pcb_parser.h:223
const wxPoint & GetArcStart() const
Class LSET is a set of PCB_LAYER_IDs.
const wxPoint & GetEnd() const
Function GetEnd returns the ending point of the graphic.
DRAWSEGMENT * parseDRAWSEGMENT()
Like smd, does not appear on the solder paste layer (default) note also has a special attribute in Ge...
Definition: pad_shapes.h:62
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
double GetAngle() const
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
int getNetCode(int aNetCode)
Converts net code using the mapping table if available, otherwise returns unchanged net code if < 0 o...
Definition: pcb_parser.h:79
BOARD * m_board
Definition: pcb_parser.h:70
Usual pad.
Definition: pad_shapes.h:60
NETINFO_ITEM * FindNet(int aNetcode) const
Function FindNet searches for a net with the given netcode.
int GetWidth() const
double parseDouble()
Function parseDouble parses the current token as an ASCII numeric string with possible leading whites...
Definition: pcb_parser.cpp:124
int parseInt()
Definition: pcb_parser.h:247
const wxPoint & GetStart() const
Function GetStart returns the starting point of the graphic.
int GetRadius() const
Function GetRadius returns the radius of this item Has meaning only for arc and circle.
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
bool PCB_PARSER::parseD_PAD_option ( D_PAD aPad)
private

Definition at line 2601 of file pcb_parser.cpp.

References CUST_PAD_SHAPE_IN_ZONE_CONVEXHULL, CUST_PAD_SHAPE_IN_ZONE_OUTLINE, PAD_SHAPE_RECT, D_PAD::SetAnchorPadShape(), and D_PAD::SetCustomShapeInZoneOpt().

Referenced by getNetCode().

2602 {
2603  // Parse only the (option ...) inside a pad description
2604  for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
2605  {
2606  if( token != T_LEFT )
2607  Expecting( T_LEFT );
2608 
2609  token = NextTok();
2610 
2611  switch( token )
2612  {
2613  case T_anchor:
2614  token = NextTok();
2615  // Custom shaped pads have a "anchor pad", which is the reference
2616  // for connection calculations.
2617  // Because this is an anchor, only the 2 very basic shapes are managed:
2618  // circle and rect. The default is circle
2619  switch( token )
2620  {
2621  case T_circle: // default
2622  break;
2623 
2624  case T_rect:
2626  break;
2627 
2628  default:
2629  // Currently, because pad options is a moving target
2630  // just skip unknown keywords
2631  break;
2632  }
2633  NeedRIGHT();
2634  break;
2635 
2636  case T_clearance:
2637  token = NextTok();
2638  // Custom shaped pads have a clearance area that is the pad shape
2639  // (like usual pads) or the convew hull of the pad shape.
2640  switch( token )
2641  {
2642  case T_outline:
2644  break;
2645 
2646  case T_convexhull:
2648  break;
2649 
2650  default:
2651  // Currently, because pad options is a moving target
2652  // just skip unknown keywords
2653  break;
2654  }
2655  NeedRIGHT();
2656  break;
2657 
2658  default:
2659  // Currently, because pad options is a moving target
2660  // just skip unknown keywords
2661  while( (token = NextTok() ) != T_RIGHT )
2662  {}
2663  break;
2664  }
2665  }
2666 
2667  return true;
2668 }
void SetAnchorPadShape(PAD_SHAPE_T aShape)
Function SetAnchorPadShape Set the shape of the anchor pad for custm shped pads.
Definition: class_pad.h:253
void SetCustomShapeInZoneOpt(CUST_PAD_SHAPE_IN_ZONE aOption)
Set the option for the custom pad shape to use as clearance area in copper zones. ...
Definition: class_pad.h:242
DIMENSION * PCB_PARSER::parseDIMENSION ( )
private

Definition at line 1606 of file pcb_parser.cpp.

References EDA_TEXT::GetTextPos(), parseHex(), and EDA_ITEM::SetTimeStamp().

Referenced by getNetCode().

1607 {
1608  wxCHECK_MSG( CurTok() == T_dimension, NULL,
1609  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as DIMENSION." ) );
1610 
1611  T token;
1612 
1613  std::unique_ptr<DIMENSION> dimension( new DIMENSION( NULL ) );
1614 
1615  dimension->SetValue( parseBoardUnits( "dimension value" ) );
1616  NeedLEFT();
1617  token = NextTok();
1618 
1619  if( token != T_width )
1620  Expecting( T_width );
1621 
1622  dimension->SetWidth( parseBoardUnits( "dimension width value" ) );
1623  NeedRIGHT();
1624 
1625  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1626  {
1627  if( token != T_LEFT )
1628  Expecting( T_LEFT );
1629 
1630  token = NextTok();
1631 
1632  switch( token )
1633  {
1634  case T_layer:
1635  dimension->SetLayer( parseBoardItemLayer() );
1636  NeedRIGHT();
1637  break;
1638 
1639  case T_tstamp:
1640  dimension->SetTimeStamp( parseHex() );
1641  NeedRIGHT();
1642  break;
1643 
1644  case T_gr_text:
1645  {
1646  TEXTE_PCB* text = parseTEXTE_PCB();
1647  // This copy (using the copy constructor) rebuild the text timestamp,
1648  // that is not what we want.
1649  dimension->Text() = *text;
1650  // reinitialises the text time stamp to the right value (the dimension time stamp)
1651  dimension->Text().SetTimeStamp( dimension->GetTimeStamp() );
1652  dimension->SetPosition( text->GetTextPos() );
1653  delete text;
1654  break;
1655  }
1656 
1657  case T_feature1:
1658  NeedLEFT();
1659  token = NextTok();
1660 
1661  if( token != T_pts )
1662  Expecting( T_pts );
1663 
1664  parseXY( &dimension->m_featureLineDO.x, &dimension->m_featureLineDO.y );
1665  parseXY( &dimension->m_featureLineDF.x, &dimension->m_featureLineDF.y );
1666  dimension->UpdateHeight();
1667  NeedRIGHT();
1668  NeedRIGHT();
1669  break;
1670 
1671  case T_feature2:
1672  NeedLEFT();
1673  token = NextTok();
1674 
1675  if( token != T_pts )
1676  Expecting( T_pts );
1677 
1678  parseXY( &dimension->m_featureLineGO.x, &dimension->m_featureLineGO.y );
1679  parseXY( &dimension->m_featureLineGF.x, &dimension->m_featureLineGF.y );
1680  dimension->UpdateHeight();
1681  NeedRIGHT();
1682  NeedRIGHT();
1683  break;
1684 
1685 
1686  case T_crossbar:
1687  NeedLEFT();
1688  token = NextTok();
1689 
1690  if( token != T_pts )
1691  Expecting( T_pts );
1692 
1693  parseXY( &dimension->m_crossBarO.x, &dimension->m_crossBarO.y );
1694  parseXY( &dimension->m_crossBarF.x, &dimension->m_crossBarF.y );
1695  dimension->UpdateHeight();
1696  NeedRIGHT();
1697  NeedRIGHT();
1698  break;
1699 
1700  case T_arrow1a:
1701  NeedLEFT();
1702  token = NextTok();
1703 
1704  if( token != T_pts )
1705  Expecting( T_pts );
1706 
1707  parseXY( &dimension->m_crossBarF.x, &dimension->m_crossBarF.y );
1708  parseXY( &dimension->m_arrowD1F.x, &dimension->m_arrowD1F.y );
1709  NeedRIGHT();
1710  NeedRIGHT();
1711  break;
1712 
1713  case T_arrow1b:
1714  NeedLEFT();
1715  token = NextTok();
1716 
1717  if( token != T_pts )
1718  Expecting( T_pts );
1719 
1720  parseXY( &dimension->m_crossBarF.x, &dimension->m_crossBarF.y );
1721  parseXY( &dimension->m_arrowD2F.x, &dimension->m_arrowD2F.y );
1722  NeedRIGHT();
1723  NeedRIGHT();
1724  break;
1725 
1726  case T_arrow2a:
1727  NeedLEFT();
1728  token = NextTok();
1729 
1730  if( token != T_pts )
1731  Expecting( T_pts );
1732 
1733  parseXY( &dimension->m_crossBarO.x, &dimension->m_crossBarO.y );
1734  parseXY( &dimension->m_arrowG1F.x, &dimension->m_arrowG1F.y );
1735  NeedRIGHT();
1736  NeedRIGHT();
1737  break;
1738 
1739  case T_arrow2b:
1740  NeedLEFT();
1741  token = NextTok();
1742 
1743  if( token != T_pts )
1744  Expecting( T_pts );
1745 
1746  parseXY( &dimension->m_crossBarO.x, &dimension->m_crossBarO.y );
1747  parseXY( &dimension->m_arrowG2F.x, &dimension->m_arrowG2F.y );
1748  NeedRIGHT();
1749  NeedRIGHT();
1750  break;
1751 
1752  default:
1753  Expecting( "layer, tstamp, gr_text, feature1, feature2 crossbar, arrow1a, "
1754  "arrow1b, arrow2a, or arrow2b" );
1755  }
1756  }
1757 
1758  return dimension.release();
1759 }
const wxPoint & GetTextPos() const
Definition: eda_text.h:222
wxPoint parseXY()
Function parseXY parses a coordinate pair (xy X Y) in board units (mm).
Definition: pcb_parser.cpp:206
int parseBoardUnits()
Definition: pcb_parser.h:223
PCB_LAYER_ID parseBoardItemLayer()
Function parseBoardItemLayer parses the layer definition of a BOARD_ITEM object.
Definition: pcb_parser.cpp:996
TEXTE_PCB * parseTEXTE_PCB()
long parseHex()
Definition: pcb_parser.h:258
Class DIMENSION.
void SetTimeStamp(timestamp_t aNewTimeStamp)
Definition: base_struct.h:214
double PCB_PARSER::parseDouble ( )
private

Function parseDouble parses the current token as an ASCII numeric string with possible leading whitespace into a double precision floating point number.

Exceptions
IO_ERRORif an error occurs attempting to convert the current token.
Returns
The result of the parsed token.

Definition at line 124 of file pcb_parser.cpp.

References GetChars(), and THROW_IO_ERROR.

Referenced by getNetCode(), parseBoardUnits(), and parseDouble().

125 {
126  char* tmp;
127 
128  errno = 0;
129 
130  double fval = strtod( CurText(), &tmp );
131 
132  if( errno )
133  {
134  wxString error;
135  error.Printf( _( "Invalid floating point number in\nfile: \"%s\"\nline: %d\noffset: %d" ),
136  GetChars( CurSource() ), CurLineNumber(), CurOffset() );
137 
138  THROW_IO_ERROR( error );
139  }
140 
141  if( CurText() == tmp )
142  {
143  wxString error;
144  error.Printf( _( "Missing floating point number in\nfile: \"%s\"\nline: %d\noffset: %d" ),
145  GetChars( CurSource() ), CurLineNumber(), CurOffset() );
146 
147  THROW_IO_ERROR( error );
148  }
149 
150  return fval;
151 }
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
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
double PCB_PARSER::parseDouble ( const char *  aExpected)
inlineprivate

Definition at line 212 of file pcb_parser.h.

References parseDouble().

213  {
214  NeedNUMBER( aExpected );
215  return parseDouble();
216  }
double parseDouble()
Function parseDouble parses the current token as an ASCII numeric string with possible leading whites...
Definition: pcb_parser.cpp:124
double PCB_PARSER::parseDouble ( PCB_KEYS_T::T  aToken)
inlineprivate

Definition at line 218 of file pcb_parser.h.

References DSN::GetTokenText(), and parseDouble().

219  {
220  return parseDouble( GetTokenText( aToken ) );
221  }
double parseDouble()
Function parseDouble parses the current token as an ASCII numeric string with possible leading whites...
Definition: pcb_parser.cpp:124
const char * GetTokenText(T aTok)
Function GetTokenText is in the DSN namespace and returns the C string representing a SPECCTRA_DB::ke...
Definition: specctra.cpp:69
DRAWSEGMENT * PCB_PARSER::parseDRAWSEGMENT ( )
private

Definition at line 1373 of file pcb_parser.cpp.

References parseDouble(), parseHex(), S_ARC, S_CIRCLE, S_CURVE, S_POLYGON, wxPoint::x, and wxPoint::y.

Referenced by getNetCode().

1374 {
1375  wxCHECK_MSG( CurTok() == T_gr_arc || CurTok() == T_gr_circle || CurTok() == T_gr_curve ||
1376  CurTok() == T_gr_line || CurTok() == T_gr_poly, NULL,
1377  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as DRAWSEGMENT." ) );
1378 
1379  T token;
1380  wxPoint pt;
1381  std::unique_ptr< DRAWSEGMENT > segment( new DRAWSEGMENT( NULL ) );
1382 
1383  switch( CurTok() )
1384  {
1385  case T_gr_arc:
1386  segment->SetShape( S_ARC );
1387  NeedLEFT();
1388  token = NextTok();
1389 
1390  // the start keyword actually gives the arc center
1391  // Allows also T_center for future change
1392  if( token != T_start && token != T_center )
1393  Expecting( T_start );
1394 
1395  pt.x = parseBoardUnits( "X coordinate" );
1396  pt.y = parseBoardUnits( "Y coordinate" );
1397  segment->SetCenter( pt );
1398  NeedRIGHT();
1399  NeedLEFT();
1400  token = NextTok();
1401 
1402  if( token != T_end ) // the end keyword actually gives the starting point of the arc
1403  Expecting( T_end );
1404 
1405  pt.x = parseBoardUnits( "X coordinate" );
1406  pt.y = parseBoardUnits( "Y coordinate" );
1407  segment->SetArcStart( pt );
1408  NeedRIGHT();
1409  break;
1410 
1411  case T_gr_circle:
1412  segment->SetShape( S_CIRCLE );
1413  NeedLEFT();
1414  token = NextTok();
1415 
1416  if( token != T_center )
1417  Expecting( T_center );
1418 
1419  pt.x = parseBoardUnits( "X coordinate" );
1420  pt.y = parseBoardUnits( "Y coordinate" );
1421  segment->SetCenter( pt );
1422  NeedRIGHT();
1423  NeedLEFT();
1424 
1425  token = NextTok();
1426 
1427  if( token != T_end )
1428  Expecting( T_end );
1429 
1430  pt.x = parseBoardUnits( "X coordinate" );
1431  pt.y = parseBoardUnits( "Y coordinate" );
1432  segment->SetEnd( pt );
1433  NeedRIGHT();
1434  break;
1435 
1436  case T_gr_curve:
1437  segment->SetShape( S_CURVE );
1438  NeedLEFT();
1439  token = NextTok();
1440 
1441  if( token != T_pts )
1442  Expecting( T_pts );
1443 
1444  segment->SetStart( parseXY() );
1445  segment->SetBezControl1( parseXY() );
1446  segment->SetBezControl2( parseXY() );
1447  segment->SetEnd( parseXY() );
1448  NeedRIGHT();
1449  break;
1450 
1451  case T_gr_line:
1452  // Default DRAWSEGMENT type is S_SEGMENT.
1453  NeedLEFT();
1454  token = NextTok();
1455 
1456  if( token != T_start )
1457  Expecting( T_start );
1458 
1459  pt.x = parseBoardUnits( "X coordinate" );
1460  pt.y = parseBoardUnits( "Y coordinate" );
1461  segment->SetStart( pt );
1462  NeedRIGHT();
1463  NeedLEFT();
1464  token = NextTok();
1465 
1466  if( token != T_end )
1467  Expecting( T_end );
1468 
1469  pt.x = parseBoardUnits( "X coordinate" );
1470  pt.y = parseBoardUnits( "Y coordinate" );
1471  segment->SetEnd( pt );
1472  NeedRIGHT();
1473  break;
1474 
1475  case T_gr_poly:
1476  {
1477  segment->SetShape( S_POLYGON );
1478  segment->SetWidth( 0 ); // this is the default value. will be (perhaps) modified later
1479  NeedLEFT();
1480  token = NextTok();
1481 
1482  if( token != T_pts )
1483  Expecting( T_pts );
1484 
1485  std::vector< wxPoint > pts;
1486 
1487  while( (token = NextTok()) != T_RIGHT )
1488  pts.push_back( parseXY() );
1489 
1490  segment->SetPolyPoints( pts );
1491  }
1492  break;
1493 
1494  default:
1495  Expecting( "gr_arc, gr_circle, gr_curve, gr_line, or gr_poly" );
1496  }
1497 
1498  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1499  {
1500  if( token != T_LEFT )
1501  Expecting( T_LEFT );
1502 
1503  token = NextTok();
1504 
1505  switch( token )
1506  {
1507  case T_angle:
1508  segment->SetAngle( parseDouble( "segment angle" ) * 10.0 );
1509  break;
1510 
1511  case T_layer:
1512  segment->SetLayer( parseBoardItemLayer() );
1513  break;
1514 
1515  case T_width:
1516  segment->SetWidth( parseBoardUnits( T_width ) );
1517  break;
1518 
1519  case T_tstamp:
1520  segment->SetTimeStamp( parseHex() );
1521  break;
1522 
1523  case T_status:
1524  segment->SetStatus( static_cast<STATUS_FLAGS>( parseHex() ) );
1525  break;
1526 
1527  default:
1528  Expecting( "layer, width, tstamp, or status" );
1529  }
1530 
1531  NeedRIGHT();
1532  }
1533 
1534  return segment.release();
1535 }
polygon (not yet used for tracks, but could be in microwave apps)
wxPoint parseXY()
Function parseXY parses a coordinate pair (xy X Y) in board units (mm).
Definition: pcb_parser.cpp:206
int parseBoardUnits()
Definition: pcb_parser.h:223
Arcs (with rounded ends)
PCB_LAYER_ID parseBoardItemLayer()
Function parseBoardItemLayer parses the layer definition of a BOARD_ITEM object.
Definition: pcb_parser.cpp:996
Bezier Curve.
double parseDouble()
Function parseDouble parses the current token as an ASCII numeric string with possible leading whites...
Definition: pcb_parser.cpp:124
long parseHex()
Definition: pcb_parser.h:258
void PCB_PARSER::parseEDA_TEXT ( EDA_TEXT aText)
private

Function parseEDA_TEXT parses the common settings for any object derived from EDA_TEXT.

Exceptions
PARSE_ERRORif the text syntax is not valid.
Parameters
aTextA point to the EDA_TEXT object to save the parsed settings into.

Definition at line 238 of file pcb_parser.cpp.

References GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_HJUSTIFY_RIGHT, GR_TEXT_VJUSTIFY_BOTTOM, GR_TEXT_VJUSTIFY_TOP, EDA_TEXT::SetBold(), EDA_TEXT::SetHorizJustify(), EDA_TEXT::SetItalic(), EDA_TEXT::SetMirrored(), EDA_TEXT::SetTextSize(), EDA_TEXT::SetThickness(), EDA_TEXT::SetVertJustify(), and EDA_TEXT::SetVisible().

Referenced by getNetCode().

239 {
240  wxCHECK_RET( CurTok() == T_effects,
241  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as EDA_TEXT." ) );
242 
243  T token;
244 
245  // Prior to v5.0 text size was omitted from file format if equal to 60mils
246  // Now, it is always explicitly written to file
247  bool foundTextSize = false;
248 
249  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
250  {
251  if( token == T_LEFT )
252  token = NextTok();
253 
254  switch( token )
255  {
256  case T_font:
257  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
258  {
259  if( token == T_LEFT )
260  continue;
261 
262  switch( token )
263  {
264  case T_size:
265  {
266  wxSize sz;
267  sz.SetHeight( parseBoardUnits( "text height" ) );
268  sz.SetWidth( parseBoardUnits( "text width" ) );
269  aText->SetTextSize( sz );
270  NeedRIGHT();
271 
272  foundTextSize = true;
273  }
274  break;
275 
276  case T_thickness:
277  aText->SetThickness( parseBoardUnits( "text thickness" ) );
278  NeedRIGHT();
279  break;
280 
281  case T_bold:
282  aText->SetBold( true );
283  break;
284 
285  case T_italic:
286  aText->SetItalic( true );
287  break;
288 
289  default:
290  Expecting( "size, bold, or italic" );
291  }
292  }
293  break;
294 
295  case T_justify:
296  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
297  {
298  if( token == T_LEFT )
299  continue;
300 
301  switch( token )
302  {
303  case T_left:
305  break;
306 
307  case T_right:
309  break;
310 
311  case T_top:
313  break;
314 
315  case T_bottom:
317  break;
318 
319  case T_mirror:
320  aText->SetMirrored( true );
321  break;
322 
323  default:
324  Expecting( "left, right, top, bottom, or mirror" );
325  }
326 
327  }
328  break;
329 
330  case T_hide:
331  aText->SetVisible( false );
332  break;
333 
334  default:
335  Expecting( "font, justify, or hide" );
336  }
337  }
338 
339  // Text size was not specified in file, force legacy default units
340  // 60mils is 1.524mm
341  if( !foundTextSize )
342  {
343  const float defaultTextSize = 1.524f * IU_PER_MM;
344 
345  aText->SetTextSize( wxSize( defaultTextSize, defaultTextSize ) );
346  }
347 }
void SetMirrored(bool isMirrored)
Definition: eda_text.h:176
void SetItalic(bool isItalic)
Definition: eda_text.h:167
void SetVisible(bool aVisible)
Definition: eda_text.h:173
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:212
int parseBoardUnits()
Definition: pcb_parser.h:223
void SetVertJustify(EDA_TEXT_VJUSTIFY_T aType)
Definition: eda_text.h:192
void SetHorizJustify(EDA_TEXT_HJUSTIFY_T aType)
Definition: eda_text.h:191
void SetBold(bool aBold)
Definition: eda_text.h:170
void SetThickness(int aNewThickness)
Function SetThickness sets pen width.
Definition: eda_text.h:146
EDGE_MODULE * PCB_PARSER::parseEDGE_MODULE ( )
private

Definition at line 2120 of file pcb_parser.cpp.

References parseDouble(), parseHex(), S_ARC, S_CIRCLE, S_CURVE, S_POLYGON, wxPoint::x, and wxPoint::y.

Referenced by getNetCode().

2121 {
2122  wxCHECK_MSG( CurTok() == T_fp_arc || CurTok() == T_fp_circle || CurTok() == T_fp_curve ||
2123  CurTok() == T_fp_line || CurTok() == T_fp_poly, NULL,
2124  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as EDGE_MODULE." ) );
2125 
2126  wxPoint pt;
2127  T token;
2128 
2129  std::unique_ptr< EDGE_MODULE > segment( new EDGE_MODULE( NULL ) );
2130 
2131  switch( CurTok() )
2132  {
2133  case T_fp_arc:
2134  segment->SetShape( S_ARC );
2135  NeedLEFT();
2136  token = NextTok();
2137 
2138  // the start keyword actually gives the arc center
2139  // Allows also T_center for future change
2140  if( token != T_start && token != T_center )
2141  Expecting( T_start );
2142 
2143  pt.x = parseBoardUnits( "X coordinate" );
2144  pt.y = parseBoardUnits( "Y coordinate" );
2145  segment->SetStart0( pt );
2146  NeedRIGHT();
2147  NeedLEFT();
2148  token = NextTok();
2149 
2150  if( token != T_end ) // end keyword actually gives the starting point of the arc
2151  Expecting( T_end );
2152 
2153  pt.x = parseBoardUnits( "X coordinate" );
2154  pt.y = parseBoardUnits( "Y coordinate" );
2155  segment->SetEnd0( pt );
2156  NeedRIGHT();
2157  NeedLEFT();
2158  token = NextTok();
2159 
2160  if( token != T_angle )
2161  Expecting( T_angle );
2162 
2163  segment->SetAngle( parseDouble( "segment angle" ) * 10.0 );
2164  NeedRIGHT();
2165  break;
2166 
2167  case T_fp_circle:
2168  segment->SetShape( S_CIRCLE );
2169  NeedLEFT();
2170  token = NextTok();
2171 
2172  if( token != T_center )
2173  Expecting( T_center );
2174 
2175  pt.x = parseBoardUnits( "X coordinate" );
2176  pt.y = parseBoardUnits( "Y coordinate" );
2177  segment->SetStart0( pt );
2178  NeedRIGHT();
2179  NeedLEFT();
2180  token = NextTok();
2181 
2182  if( token != T_end )
2183  Expecting( T_end );
2184 
2185  pt.x = parseBoardUnits( "X coordinate" );
2186  pt.y = parseBoardUnits( "Y coordinate" );
2187  segment->SetEnd0( pt );
2188  NeedRIGHT();
2189  break;
2190 
2191  case T_fp_curve:
2192  segment->SetShape( S_CURVE );
2193  NeedLEFT();
2194  token = NextTok();
2195 
2196  if( token != T_pts )
2197  Expecting( T_pts );
2198 
2199  segment->SetStart0( parseXY() );
2200  segment->SetBezControl1( parseXY() );
2201  segment->SetBezControl2( parseXY() );
2202  segment->SetEnd0( parseXY() );
2203  NeedRIGHT();
2204  break;
2205 
2206  case T_fp_line:
2207  // Default DRAWSEGMENT type is S_SEGMENT.
2208  NeedLEFT();
2209  token = NextTok();
2210 
2211  if( token != T_start )
2212  Expecting( T_start );
2213 
2214  pt.x = parseBoardUnits( "X coordinate" );
2215  pt.y = parseBoardUnits( "Y coordinate" );
2216  segment->SetStart0( pt );
2217 
2218  NeedRIGHT();
2219  NeedLEFT();
2220  token = NextTok();
2221 
2222  if( token != T_end )
2223  Expecting( T_end );
2224 
2225  pt.x = parseBoardUnits( "X coordinate" );
2226  pt.y = parseBoardUnits( "Y coordinate" );
2227  segment->SetEnd0( pt );
2228  NeedRIGHT();
2229  break;
2230 
2231  case T_fp_poly:
2232  {
2233  segment->SetShape( S_POLYGON );
2234  NeedLEFT();
2235  token = NextTok();
2236 
2237  if( token != T_pts )
2238  Expecting( T_pts );
2239 
2240  std::vector< wxPoint > pts;
2241 
2242  while( (token = NextTok()) != T_RIGHT )
2243  pts.push_back( parseXY() );
2244 
2245  segment->SetPolyPoints( pts );
2246  }
2247  break;
2248 
2249  default:
2250  Expecting( "fp_arc, fp_circle, fp_curve, fp_line, or fp_poly" );
2251  }
2252 
2253  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2254  {
2255  if( token != T_LEFT )
2256  Expecting( T_LEFT );
2257 
2258  token = NextTok();
2259 
2260  switch( token )
2261  {
2262  case T_layer:
2263  segment->SetLayer( parseBoardItemLayer() );
2264  break;
2265 
2266  case T_width:
2267  segment->SetWidth( parseBoardUnits( T_width ) );
2268  break;
2269 
2270  case T_tstamp:
2271  segment->SetTimeStamp( parseHex() );
2272  break;
2273 
2274  case T_status:
2275  segment->SetStatus( static_cast<STATUS_FLAGS>( parseHex() ) );
2276  break;
2277 
2278  default:
2279  Expecting( "layer or width" );
2280  }
2281 
2282  NeedRIGHT();
2283  }
2284 
2285  return segment.release();
2286 }
polygon (not yet used for tracks, but could be in microwave apps)
wxPoint parseXY()
Function parseXY parses a coordinate pair (xy X Y) in board units (mm).
Definition: pcb_parser.cpp:206
int parseBoardUnits()
Definition: pcb_parser.h:223
Arcs (with rounded ends)
PCB_LAYER_ID parseBoardItemLayer()
Function parseBoardItemLayer parses the layer definition of a BOARD_ITEM object.
Definition: pcb_parser.cpp:996
Bezier Curve.
double parseDouble()
Function parseDouble parses the current token as an ASCII numeric string with possible leading whites...
Definition: pcb_parser.cpp:124
long parseHex()
Definition: pcb_parser.h:258
void PCB_PARSER::parseGeneralSection ( )
private

Definition at line 623 of file pcb_parser.cpp.

References parseInt().

Referenced by getNetCode().

624 {
625  wxCHECK_RET( CurTok() == T_general,
626  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
627  wxT( " as a general section." ) );
628 
629  T token;
630 
631  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
632  {
633  if( token != T_LEFT )
634  Expecting( T_LEFT );
635 
636  token = NextTok();
637 
638  switch( token )
639  {
640  case T_thickness:
642  NeedRIGHT();
643  break;
644 
645  case T_nets:
646  m_netCodes.resize( parseInt( "nets number" ) );
647  NeedRIGHT();
648  break;
649 
650  case T_no_connects:
651  // ignore
652  parseInt( "no connect count" );
653  NeedRIGHT();
654  break;
655 
656  default: // Skip everything but the board thickness.
657  //wxLogDebug( wxT( "Skipping general section token %s " ), GetChars( GetTokenString( token ) ) );
658 
659  while( ( token = NextTok() ) != T_RIGHT )
660  {
661  if( !IsSymbol( token ) && token != T_NUMBER )
662  Expecting( "symbol or number" );
663  }
664  }
665  }
666 }
void SetBoardThickness(int aThickness)
int parseBoardUnits()
Definition: pcb_parser.h:223
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:532
std::vector< int > m_netCodes
net codes mapping for boards being loaded
Definition: pcb_parser.h:73
BOARD * m_board
Definition: pcb_parser.h:70
int parseInt()
Definition: pcb_parser.h:247
void PCB_PARSER::parseHeader ( )
private

Definition at line 587 of file pcb_parser.cpp.

References parseInt(), and SEXPR_BOARD_FILE_VERSION.

Referenced by getNetCode().

588 {
589  wxCHECK_RET( CurTok() == T_kicad_pcb,
590  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a header." ) );
591 
592  NeedLEFT();
593 
594  T tok = NextTok();
595  if( tok == T_version )
596  {
597  m_requiredVersion = parseInt( FromUTF8().mb_str( wxConvUTF8 ) );
599  NeedRIGHT();
600 
601  // Skip the host name and host build version information.
602  NeedLEFT();
603  NeedSYMBOL();
604  NeedSYMBOL();
605  NeedSYMBOL();
606  NeedRIGHT();
607  }
608  else
609  {
612 
613  // Skip the host name and host build version information.
614  NeedSYMBOL();
615  NeedSYMBOL();
616  NeedRIGHT();
617  }
618 
620 }
void SetFileFormatVersionAtLoad(int aVersion)
Definition: class_board.h:276
#define SEXPR_BOARD_FILE_VERSION
Current s-expression file format version. 2 was the last legacy format version.
bool m_tooRecent
true if version parses as later than supported
Definition: pcb_parser.h:74
int m_requiredVersion
set to the KiCad format version this board requires
Definition: pcb_parser.h:75
BOARD * m_board
Definition: pcb_parser.h:70
int parseInt()
Definition: pcb_parser.h:247
long PCB_PARSER::parseHex ( )
inlineprivate

Definition at line 258 of file pcb_parser.h.

References parseBool(), and parseVersion().

259  {
260  NextTok();
261  return strtol( CurText(), NULL, 16 );
262  }
int PCB_PARSER::parseInt ( )
inlineprivate

Definition at line 247 of file pcb_parser.h.

Referenced by parseInt().

248  {
249  return (int)strtol( CurText(), NULL, 10 );
250  }
int PCB_PARSER::parseInt ( const char *  aExpected)
inlineprivate

Definition at line 252 of file pcb_parser.h.

References parseInt().

253  {
254  NeedNUMBER( aExpected );
255  return parseInt();
256  }
int parseInt()
Definition: pcb_parser.h:247
void PCB_PARSER::parseLayer ( LAYER aLayer)
private

Definition at line 808 of file pcb_parser.cpp.

References LAYER::clear(), FROM_UTF8(), LAYER::m_name, LAYER::m_number, LAYER::m_type, LAYER::m_visible, name, parseInt(), and LAYER::ParseType().

Referenced by getNetCode().

809 {
810  T token;
811 
812  std::string name;
813  std::string type;
814  bool isVisible = true;
815 
816  aLayer->clear();
817 
818  if( CurTok() != T_LEFT )
819  Expecting( T_LEFT );
820 
821  // this layer_num is not used, we DO depend on LAYER_T however.
822  LAYER_NUM layer_num = parseInt( "layer index" );
823 
824  NeedSYMBOLorNUMBER();
825  name = CurText();
826 
827  NeedSYMBOL();
828  type = CurText();
829 
830  token = NextTok();
831 
832  if( token == T_hide )
833  {
834  isVisible = false;
835  NeedRIGHT();
836  }
837  else if( token != T_RIGHT )
838  {
839  Expecting( "hide or )" );
840  }
841 
842  aLayer->m_name = FROM_UTF8( name.c_str() );
843  aLayer->m_type = LAYER::ParseType( type.c_str() );
844  aLayer->m_number = layer_num;
845  aLayer->m_visible = isVisible;
846 }
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
wxString m_name
The name of the layer, there should be no spaces in this name.
Definition: class_board.h:111
LAYER_T m_type
The type of the layer.
Definition: class_board.h:113
bool m_visible
Definition: class_board.h:115
static LAYER_T ParseType(const char *aType)
Function ParseType converts a string to a LAYER_T.
int LAYER_NUM
Type LAYER_NUM can be replaced with int and removed.
void clear()
Definition: class_board.h:92
const char * name
Definition: DXF_plotter.cpp:61
int m_number
Definition: class_board.h:117
int parseInt()
Definition: pcb_parser.h:247
void PCB_PARSER::parseLayers ( )
private

Definition at line 850 of file pcb_parser.cpp.

References B_Cu, cu, err, Format(), GetChars(), i, LT_UNDEFINED, LAYER::m_name, LAYER::m_number, LAYER::m_type, LAYER::m_visible, name, THROW_IO_ERROR, and THROW_PARSE_ERROR.

Referenced by getNetCode().

851 {
852  wxCHECK_RET( CurTok() == T_layers,
853  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as layers." ) );
854 
855  T token;
856  LSET visibleLayers;
857  LSET enabledLayers;
858  int copperLayerCount = 0;
859  LAYER layer;
860 
861  std::vector<LAYER> cu;
862 
863  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
864  {
865  parseLayer( &layer );
866 
867  if( layer.m_type == LT_UNDEFINED ) // it's a non-copper layer
868  break;
869 
870  cu.push_back( layer ); // it's copper
871  }
872 
873  // All Cu layers are parsed, but not the non-cu layers here.
874 
875  // The original *.kicad_pcb file format and the inverted
876  // Cu stack format both have all the Cu layers first, so use this
877  // trick to handle either. The layer number in the (layers ..)
878  // s-expression element are ignored.
879  if( cu.size() )
880  {
881  // Rework the layer numbers, which changed when the Cu stack
882  // was flipped. So we instead use position in the list.
883  cu[cu.size()-1].m_number = B_Cu;
884 
885  for( unsigned i=0; i < cu.size()-1; ++i )
886  {
887  cu[i].m_number = i;
888  }
889 
890  for( std::vector<LAYER>::const_iterator it = cu.begin(); it<cu.end(); ++it )
891  {
892  enabledLayers.set( it->m_number );
893 
894  if( it->m_visible )
895  visibleLayers.set( it->m_number );
896 
897  m_board->SetLayerDescr( PCB_LAYER_ID( it->m_number ), *it );
898 
899  UTF8 name = it->m_name;
900 
901  m_layerIndices[ name ] = PCB_LAYER_ID( it->m_number );
902  m_layerMasks[ name ] = LSET( PCB_LAYER_ID( it->m_number ) );
903  }
904 
905  copperLayerCount = cu.size();
906  }
907 
908  // process non-copper layers
909  while( token != T_RIGHT )
910  {
911  LAYER_ID_MAP::const_iterator it = m_layerIndices.find( UTF8( layer.m_name ) );
912 
913  if( it == m_layerIndices.end() )
914  {
915  wxString error = wxString::Format(
916  _( "Layer \"%s\" in file \"%s\" at line %d, is not in fixed layer hash" ),
917  GetChars( layer.m_name ),
918  GetChars( CurSource() ),
919  CurLineNumber(),
920  CurOffset()
921  );
922 
923  THROW_IO_ERROR( error );
924  }
925 
926  layer.m_number = it->second;
927 
928  enabledLayers.set( layer.m_number );
929 
930  if( layer.m_visible )
931  visibleLayers.set( layer.m_number );
932 
933  // DBG( printf( "aux m_visible:%s\n", layer.m_visible ? "true" : "false" );)
934 
935  m_board->SetLayerDescr( it->second, layer );
936 
937  token = NextTok();
938 
939  if( token != T_LEFT )
940  break;
941 
942  parseLayer( &layer );
943  }
944 
945  // We need at least 2 copper layers and there must be an even number of them.
946  if( copperLayerCount < 2 || (copperLayerCount % 2) != 0 )
947  {
948  wxString err = wxString::Format(
949  _( "%d is not a valid layer count" ), copperLayerCount );
950 
951  THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
952  }
953 
954  m_board->SetCopperLayerCount( copperLayerCount );
955  m_board->SetEnabledLayers( enabledLayers );
956 
957  // call SetEnabledLayers before SetVisibleLayers()
958  m_board->SetVisibleLayers( visibleLayers );
959 }
Class UTF8 is an 8 bit string that is assuredly encoded in UTF8, and supplies special conversion supp...
Definition: utf8.h:73
wxString m_name
The name of the layer, there should be no spaces in this name.
Definition: class_board.h:111
LAYER_T m_type
The type of the layer.
Definition: class_board.h:113
void SetCopperLayerCount(int aCount)
#define cu(a)
Definition: auxiliary.h:88
PCB_LAYER_ID
A quick note on layer IDs:
Class LSET is a set of PCB_LAYER_IDs.
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
Definition: ki_exception.h:133
void SetVisibleLayers(LSET aLayerMask)
Function SetVisibleLayers is a proxy function that calls the correspondent function in m_BoardSetting...
bool SetLayerDescr(PCB_LAYER_ID aIndex, const LAYER &aLayer)
Function SetLayerDescr returns the type of the copper layer given by aLayer.
bool m_visible
Definition: class_board.h:115
string & err
Definition: json11.cpp:598
void parseLayer(LAYER *aLayer)
Definition: pcb_parser.cpp:808
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
const char * name
Definition: DXF_plotter.cpp:61
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
Class LAYER holds information pertinent to a layer of a BOARD.
Definition: class_board.h:85
BOARD * m_board
Definition: pcb_parser.h:70
size_t i
Definition: json11.cpp:597
LAYER_ID_MAP m_layerIndices
map layer name to it&#39;s index
Definition: pcb_parser.h:71
int m_number
Definition: class_board.h:117
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
void SetEnabledLayers(LSET aLayerMask)
Function SetEnabledLayers is a proxy function that calls the correspondent function in m_BoardSetting...
LSET_MAP m_layerMasks
map layer names to their masks
Definition: pcb_parser.h:72
MODULE * PCB_PARSER::parseMODULE ( wxArrayString *  aInitialComments = 0)

Function parseMODULE.

Parameters
aInitialCommentsmay be a pointer to a heap allocated initial comment block or NULL. If not NULL, then caller has given ownership of a wxArrayString to this function and care must be taken to delete it even on exception.

Definition at line 1762 of file pcb_parser.cpp.

Referenced by CLIPBOARD_PARSER::parseMODULE(), and SetBoard().

1763 {
1764  try
1765  {
1766  return parseMODULE_unchecked( aInitialComments );
1767  }
1768  catch( const PARSE_ERROR& parse_error )
1769  {
1770  if( m_tooRecent )
1771  throw FUTURE_FORMAT_ERROR( parse_error, GetRequiredVersion() );
1772  else
1773  throw;
1774  }
1775 }
bool m_tooRecent
true if version parses as later than supported
Definition: pcb_parser.h:74
wxString GetRequiredVersion()
Return a string representing the version of kicad required to open this file.
Definition: pcb_parser.cpp:182
MODULE * parseMODULE_unchecked(wxArrayString *aInitialComments=0)
Function parseMODULE_unchecked Parse a module, but do not replace PARSE_ERROR with FUTURE_FORMAT_ERRO...
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&#39;s report and his call site information: CPP source file, function, and line number.
Definition: ki_exception.h:94
Struct FUTURE_FORMAT_ERROR variant of PARSE_ERROR indicating that a syntax or related error was likel...
Definition: ki_exception.h:143
MODULE * PCB_PARSER::parseMODULE_unchecked ( wxArrayString *  aInitialComments = 0)
private

Function parseMODULE_unchecked Parse a module, but do not replace PARSE_ERROR with FUTURE_FORMAT_ERROR automatically.

Definition at line 1778 of file pcb_parser.cpp.

References ADD_APPEND, B_Cu, F_Cu, GetChars(), D_PAD::GetPos0(), EDA_TEXT::GetTextAngle(), TEXTE_MODULE::GetType(), max, MOD_CMS, MOD_VIRTUAL, name, LIB_ID::Parse(), parseDouble(), parseHex(), parseInt(), RotatePoint(), EDGE_MODULE::SetDrawCoord(), TEXTE_MODULE::SetDrawCoord(), EDA_ITEM::SetParent(), D_PAD::SetPosition(), TEXTE_MODULE::SetTextAngle(), SEXPR_BOARD_FILE_VERSION, TEXTE_MODULE::TEXT_is_REFERENCE, TEXTE_MODULE::TEXT_is_VALUE, THROW_IO_ERROR, wxPoint::x, and wxPoint::y.

Referenced by getNetCode().

1779 {
1780  wxCHECK_MSG( CurTok() == T_module, NULL,
1781  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as MODULE." ) );
1782 
1783  wxString name;
1784  wxPoint pt;
1785  T token;
1786  LIB_ID fpid;
1787 
1788  std::unique_ptr<MODULE> module( new MODULE( m_board ) );
1789 
1790  module->SetInitialComments( aInitialComments );
1791 
1792  token = NextTok();
1793 
1794  if( !IsSymbol( token ) && token != T_NUMBER )
1795  Expecting( "symbol|number" );
1796 
1797  name = FromUTF8();
1798 
1799  if( !name.IsEmpty() && fpid.Parse( FromUTF8() ) >= 0 )
1800  {
1801  wxString error;
1802  error.Printf( _( "Invalid footprint ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),
1803  GetChars( CurSource() ), CurLineNumber(), CurOffset() );
1804  THROW_IO_ERROR( error );
1805  }
1806 
1807  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1808  {
1809  if( token == T_LEFT )
1810  token = NextTok();
1811 
1812  switch( token )
1813  {
1814  case T_version:
1815  {
1816  // Theoretically a module nested in a PCB could declare its own version, though
1817  // as of writing this comment we don't do that. Just in case, take the greater
1818  // version.
1819  int this_version = parseInt( FromUTF8().mb_str( wxConvUTF8 ) );
1820  NeedRIGHT();
1821  m_requiredVersion = std::max( m_requiredVersion, this_version );
1823  break;
1824  }
1825 
1826  case T_locked:
1827  module->SetLocked( true );
1828  break;
1829 
1830  case T_placed:
1831  module->SetIsPlaced( true );
1832  break;
1833 
1834  case T_layer:
1835  {
1836  // Footprints can be only on the front side or the back side.
1837  // but because we can find some stupid layer in file, ensure a
1838  // acceptable layer is set for the footprint
1840  module->SetLayer( layer == B_Cu ? B_Cu : F_Cu );
1841  }
1842  NeedRIGHT();
1843  break;
1844 
1845  case T_tedit:
1846  module->SetLastEditTime( parseHex() );
1847  NeedRIGHT();
1848  break;
1849 
1850  case T_tstamp:
1851  module->SetTimeStamp( parseHex() );
1852  NeedRIGHT();
1853  break;
1854 
1855  case T_at:
1856  pt.x = parseBoardUnits( "X coordinate" );
1857  pt.y = parseBoardUnits( "Y coordinate" );
1858  module->SetPosition( pt );
1859  token = NextTok();
1860 
1861  if( token == T_NUMBER )
1862  {
1863  module->SetOrientation( parseDouble() * 10.0 );
1864  NeedRIGHT();
1865  }
1866  else if( token != T_RIGHT )
1867  {
1868  Expecting( T_RIGHT );
1869  }
1870 
1871  break;
1872 
1873  case T_descr:
1874  NeedSYMBOLorNUMBER(); // some symbols can be 0508, so a number is also a symbol here
1875  module->SetDescription( FromUTF8() );
1876  NeedRIGHT();
1877  break;
1878 
1879  case T_tags:
1880  NeedSYMBOLorNUMBER(); // some symbols can be 0508, so a number is also a symbol here
1881  module->SetKeywords( FromUTF8() );
1882  NeedRIGHT();
1883  break;
1884 
1885  case T_path:
1886  NeedSYMBOLorNUMBER(); // Paths can be numerical so a number is also a symbol here
1887  module->SetPath( FromUTF8() );
1888  NeedRIGHT();
1889  break;
1890 
1891  case T_autoplace_cost90:
1892  module->SetPlacementCost90( parseInt( "auto place cost at 90 degrees" ) );
1893  NeedRIGHT();
1894  break;
1895 
1896  case T_autoplace_cost180:
1897  module->SetPlacementCost180( parseInt( "auto place cost at 180 degrees" ) );
1898  NeedRIGHT();
1899  break;
1900 
1901  case T_solder_mask_margin:
1902  module->SetLocalSolderMaskMargin( parseBoardUnits( "local solder mask margin value" ) );
1903  NeedRIGHT();
1904  break;
1905 
1906  case T_solder_paste_margin:
1907  module->SetLocalSolderPasteMargin(
1908  parseBoardUnits( "local solder paste margin value" ) );
1909  NeedRIGHT();
1910  break;
1911 
1912  case T_solder_paste_ratio:
1913  module->SetLocalSolderPasteMarginRatio(
1914  parseDouble( "local solder paste margin ratio value" ) );
1915  NeedRIGHT();
1916  break;
1917 
1918  case T_clearance:
1919  module->SetLocalClearance( parseBoardUnits( "local clearance value" ) );
1920  NeedRIGHT();
1921  break;
1922 
1923  case T_zone_connect:
1924  module->SetZoneConnection( (ZoneConnection) parseInt( "zone connection value" ) );
1925  NeedRIGHT();
1926  break;
1927 
1928  case T_thermal_width:
1929  module->SetThermalWidth( parseBoardUnits( "thermal width value" ) );
1930  NeedRIGHT();
1931  break;
1932 
1933  case T_thermal_gap:
1934  module->SetThermalGap( parseBoardUnits( "thermal gap value" ) );
1935  NeedRIGHT();
1936  break;
1937 
1938  case T_attr:
1939  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1940  {
1941  switch( token )
1942  {
1943  case T_smd:
1944  module->SetAttributes( module->GetAttributes() | MOD_CMS );
1945  break;
1946 
1947  case T_virtual:
1948  module->SetAttributes( module->GetAttributes() | MOD_VIRTUAL );
1949  break;
1950 
1951  default:
1952  Expecting( "smd and/or virtual" );
1953  }
1954  }
1955  break;
1956 
1957  case T_fp_text:
1958  {
1959  TEXTE_MODULE* text = parseTEXTE_MODULE();
1960  text->SetParent( module.get() );
1961  double orientation = text->GetTextAngle();
1962  orientation -= module->GetOrientation();
1963  text->SetTextAngle( orientation );
1964  text->SetDrawCoord();
1965 
1966  switch( text->GetType() )
1967  {
1969  module->Reference() = *text;
1970  delete text;
1971  break;
1972 
1974  module->Value() = *text;
1975  delete text;
1976  break;
1977 
1978  default:
1979  module->GraphicalItemsList().PushBack( text );
1980  }
1981  }
1982  break;
1983 
1984  case T_fp_arc:
1985  case T_fp_circle:
1986  case T_fp_curve:
1987  case T_fp_line:
1988  case T_fp_poly:
1989  {
1990  EDGE_MODULE* em = parseEDGE_MODULE();
1991  em->SetParent( module.get() );
1992  em->SetDrawCoord();
1993  module->GraphicalItemsList().PushBack( em );
1994  }
1995  break;
1996 
1997  case T_pad:
1998  {
1999  D_PAD* pad = parseD_PAD( module.get() );
2000  pt = pad->GetPos0();
2001 
2002  RotatePoint( &pt, module->GetOrientation() );
2003  pad->SetPosition( pt + module->GetPosition() );
2004  module->Add( pad, ADD_APPEND );
2005  }
2006  break;
2007 
2008  case T_model:
2009  module->Add3DModel( parse3DModel() );
2010  break;
2011 
2012  default:
2013  Expecting( "locked, placed, tedit, tstamp, at, descr, tags, path, "
2014  "autoplace_cost90, autoplace_cost180, solder_mask_margin, "
2015  "solder_paste_margin, solder_paste_ratio, clearance, "
2016  "zone_connect, thermal_width, thermal_gap, attr, fp_text, "
2017  "fp_arc, fp_circle, fp_curve, fp_line, fp_poly, pad, or model" );
2018  }
2019  }
2020 
2021  module->SetFPID( fpid );
2022  module->CalculateBoundingBox();
2023 
2024  return module.release();
2025 }
TEXT_TYPE GetType() const
ZoneConnection
How pads are covered by copper in zone.
Definition: zones.h:55
Set for modules listed in the automatic insertion list (usually SMD footprints)
Definition: class_module.h:77
#define SEXPR_BOARD_FILE_VERSION
Current s-expression file format version. 2 was the last legacy format version.
void SetPosition(const wxPoint &aPos) override
Definition: class_pad.h:219
const wxPoint & GetPos0() const
Definition: class_pad.h:263
int Parse(const UTF8 &aId)
Parse LIB_ID with the information from aId.
Definition: lib_id.cpp:122
bool m_tooRecent
true if version parses as later than supported
Definition: pcb_parser.h:74
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:216
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
int parseBoardUnits()
Definition: pcb_parser.h:223
double GetTextAngle() const
Definition: eda_text.h:162
PCB_LAYER_ID
A quick note on layer IDs:
void SetParent(EDA_ITEM *aParent)
Definition: base_struct.h:224
PCB_LAYER_ID parseBoardItemLayer()
Function parseBoardItemLayer parses the layer definition of a BOARD_ITEM object.
Definition: pcb_parser.cpp:996
int m_requiredVersion
set to the KiCad format version this board requires
Definition: pcb_parser.h:75
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
EDGE_MODULE * parseEDGE_MODULE()
const char * name
Definition: DXF_plotter.cpp:61
#define max(a, b)
Definition: auxiliary.h:86
BOARD * m_board
Definition: pcb_parser.h:70
Virtual component: when created by copper shapes on board (Like edge card connectors, mounting hole...)
Definition: class_module.h:79
void SetDrawCoord()
Set absolute coordinates.
void SetDrawCoord()
Set draw coordinates (absolute values ) from relative coordinates.
double parseDouble()
Function parseDouble parses the current token as an ASCII numeric string with possible leading whites...
Definition: pcb_parser.cpp:124
void SetTextAngle(double aAngle)
TEXTE_MODULE * parseTEXTE_MODULE()
D_PAD * parseD_PAD(MODULE *aParent=NULL)
long parseHex()
Definition: pcb_parser.h:258
int parseInt()
Definition: pcb_parser.h:247
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
MODULE_3D_SETTINGS * parse3DModel()
Definition: pcb_parser.cpp:350
void PCB_PARSER::parseNETCLASS ( )
private

Definition at line 1290 of file pcb_parser.cpp.

References THROW_IO_ERROR.

Referenced by getNetCode().

1291 {
1292  wxCHECK_RET( CurTok() == T_net_class,
1293  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as net class." ) );
1294 
1295  T token;
1296 
1297  NETCLASSPTR nc = std::make_shared<NETCLASS>( wxEmptyString );
1298 
1299  // Read netclass name (can be a name or just a number like track width)
1300  NeedSYMBOLorNUMBER();
1301  nc->SetName( FromUTF8() );
1302  NeedSYMBOL();
1303  nc->SetDescription( FromUTF8() );
1304 
1305  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1306  {
1307  if( token != T_LEFT )
1308  Expecting( T_LEFT );
1309 
1310  token = NextTok();
1311 
1312  switch( token )
1313  {
1314  case T_clearance:
1315  nc->SetClearance( parseBoardUnits( T_clearance ) );
1316  break;
1317 
1318  case T_trace_width:
1319  nc->SetTrackWidth( parseBoardUnits( T_trace_width ) );
1320  break;
1321 
1322  case T_via_dia:
1323  nc->SetViaDiameter( parseBoardUnits( T_via_dia ) );
1324  break;
1325 
1326  case T_via_drill:
1327  nc->SetViaDrill( parseBoardUnits( T_via_drill ) );
1328  break;
1329 
1330  case T_uvia_dia:
1331  nc->SetuViaDiameter( parseBoardUnits( T_uvia_dia ) );
1332  break;
1333 
1334  case T_uvia_drill:
1335  nc->SetuViaDrill( parseBoardUnits( T_uvia_drill ) );
1336  break;
1337 
1338  case T_diff_pair_width:
1339  nc->SetDiffPairWidth( parseBoardUnits( T_diff_pair_width ) );
1340  break;
1341 
1342  case T_diff_pair_gap:
1343  nc->SetDiffPairGap( parseBoardUnits( T_diff_pair_gap ) );
1344  break;
1345 
1346  case T_add_net:
1347  NeedSYMBOLorNUMBER();
1348  nc->Add( FromUTF8() );
1349  break;
1350 
1351  default:
1352  Expecting( "clearance, trace_width, via_dia, via_drill, uvia_dia, uvia_drill, diff_pair_width, diff_pair_gap or add_net" );
1353  }
1354 
1355  NeedRIGHT();
1356  }
1357 
1358  if( !m_board->GetDesignSettings().m_NetClasses.Add( nc ) )
1359  {
1360  // Must have been a name conflict, this is a bad board file.
1361  // User may have done a hand edit to the file.
1362 
1363  // unique_ptr will delete nc on this code path
1364 
1365  wxString error;
1366  error.Printf( _( "Duplicate NETCLASS name \"%s\" in file \"%s\" at line %d, offset %d" ),
1367  nc->GetName().GetData(), CurSource().GetData(), CurLineNumber(), CurOffset() );
1368  THROW_IO_ERROR( error );
1369  }
1370 }
int parseBoardUnits()
Definition: pcb_parser.h:223
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:532
bool Add(const NETCLASSPTR &aNetclass)
Function Add takes aNetclass and puts it into this NETCLASSES container.
Definition: netclass.cpp:102
BOARD * m_board
Definition: pcb_parser.h:70
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
NETCLASSES m_NetClasses
List of current netclasses. There is always the default netclass.
void PCB_PARSER::parseNETINFO_ITEM ( )
private

Definition at line 1264 of file pcb_parser.cpp.

References NETINFO_ITEM::GetNet(), name, parseInt(), and NETINFO_LIST::UNCONNECTED.

Referenced by getNetCode().

1265 {
1266  wxCHECK_RET( CurTok() == T_net,
1267  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as net." ) );
1268 
1269  int netCode = parseInt( "net number" );
1270 
1271  NeedSYMBOLorNUMBER();
1272  wxString name = FromUTF8();
1273 
1274  NeedRIGHT();
1275 
1276  // net 0 should be already in list, so store this net
1277  // if it is not the net 0, or if the net 0 does not exists.
1278  // (TODO: a better test.)
1280  {
1281  NETINFO_ITEM* net = new NETINFO_ITEM( m_board, name, netCode );
1282  m_board->Add( net );
1283 
1284  // Store the new code mapping
1285  pushValueIntoMap( netCode, net->GetNet() );
1286  }
1287 }
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_INSERT) override
Adds an item to the container.
int GetNet() const
Function GetNet.
Definition: netinfo.h:227
Class NETINFO_ITEM handles the data for a net.
Definition: netinfo.h:69
const char * name
Definition: DXF_plotter.cpp:61
BOARD * m_board
Definition: pcb_parser.h:70
void pushValueIntoMap(int aIndex, int aValue)
function pushValueIntoMap Add aValue value in netcode mapping (m_netCodes) at index aIndex ensure the...
Definition: pcb_parser.cpp:113
NETINFO_ITEM * FindNet(int aNetcode) const
Function FindNet searches for a net with the given netcode.
int parseInt()
Definition: pcb_parser.h:247
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
Definition: netinfo.h:461
void PCB_PARSER::parsePAGE_INFO ( )
private

Definition at line 669 of file pcb_parser.cpp.

References PAGE_INFO::Custom, err, GetChars(), Mm2mils(), parseDouble(), PAGE_INFO::SetHeightMils(), PAGE_INFO::SetPortrait(), PAGE_INFO::SetType(), PAGE_INFO::SetWidthMils(), and THROW_PARSE_ERROR.

Referenced by getNetCode().

670 {
671  wxCHECK_RET( CurTok() == T_page,
672  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a PAGE_INFO." ) );
673 
674  T token;
675  PAGE_INFO pageInfo;
676 
677  NeedSYMBOL();
678 
679  wxString pageType = FromUTF8();
680 
681  if( !pageInfo.SetType( pageType ) )
682  {
683  wxString err;
684  err.Printf( _( "Page type \"%s\" is not valid " ), GetChars( FromUTF8() ) );
685  THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
686  }
687 
688  if( pageType == PAGE_INFO::Custom )
689  {
690  double width = parseDouble( "width" ); // width in mm
691 
692  // Perform some controls to avoid crashes if the size is edited by hands
693  if( width < 100.0 )
694  width = 100.0;
695  else if( width > 1200.0 )
696  width = 1200.0;
697 
698  double height = parseDouble( "height" ); // height in mm
699 
700  if( height < 100.0 )
701  height = 100.0;
702  else if( height > 1200.0 )
703  height = 1200.0;
704 
705  pageInfo.SetWidthMils( Mm2mils( width ) );
706  pageInfo.SetHeightMils( Mm2mils( height ) );
707  }
708 
709  token = NextTok();
710 
711  if( token == T_portrait )
712  {
713  pageInfo.SetPortrait( true );
714  NeedRIGHT();
715  }
716  else if( token != T_RIGHT )
717  {
718  Expecting( "portrait|)" );
719  }
720 
721  m_board->SetPageSettings( pageInfo );
722 }
int Mm2mils(double x)
Convert mm to mils.
Definition: base_units.h:41
void SetPageSettings(const PAGE_INFO &aPageSettings)
Definition: class_board.h:548
bool SetType(const wxString &aStandardPageDescriptionName, bool aIsPortrait=false)
Function SetType sets the name of the page type and also the sizes and margins commonly associated wi...
Definition: page_info.cpp:117
static const wxChar Custom[]
"User" defined page type
Definition: page_info.h:73
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
Definition: ki_exception.h:133
Class PAGE_INFO describes the page size and margins of a paper page on which to eventually print or p...
Definition: page_info.h:49
string & err
Definition: json11.cpp:598
void SetHeightMils(int aHeightInMils)
Definition: page_info.cpp:253
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
BOARD * m_board
Definition: pcb_parser.h:70
void SetWidthMils(int aWidthInMils)
Definition: page_info.cpp:239
double parseDouble()
Function parseDouble parses the current token as an ASCII numeric string with possible leading whites...
Definition: pcb_parser.cpp:124
void SetPortrait(bool aIsPortrait)
Function SetPortrait will rotate the paper page 90 degrees.
Definition: page_info.cpp:182
PCB_TARGET * PCB_PARSER::parsePCB_TARGET ( )
private

Definition at line 3197 of file pcb_parser.cpp.

References parseHex(), wxPoint::x, and wxPoint::y.

Referenced by getNetCode().

3198 {
3199  wxCHECK_MSG( CurTok() == T_target, NULL,
3200  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as PCB_TARGET." ) );
3201 
3202  wxPoint pt;
3203  T token;
3204 
3205  std::unique_ptr< PCB_TARGET > target( new PCB_TARGET( NULL ) );
3206 
3207  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3208  {
3209  if( token == T_LEFT )
3210  token = NextTok();
3211 
3212  switch( token )
3213  {
3214  case T_x:
3215  target->SetShape( 1 );
3216  break;
3217 
3218  case T_plus:
3219  target->SetShape( 0 );
3220  break;
3221 
3222  case T_at:
3223  pt.x = parseBoardUnits( "target x position" );
3224  pt.y = parseBoardUnits( "target y position" );
3225  target->SetPosition( pt );
3226  NeedRIGHT();
3227  break;
3228 
3229  case T_size:
3230  target->SetSize( parseBoardUnits( "target size" ) );
3231  NeedRIGHT();
3232  break;
3233 
3234  case T_width:
3235  target->SetWidth( parseBoardUnits( "target thickness" ) );
3236  NeedRIGHT();
3237  break;
3238 
3239  case T_layer:
3240  target->SetLayer( parseBoardItemLayer() );
3241  NeedRIGHT();
3242  break;
3243 
3244  case T_tstamp:
3245  target->SetTimeStamp( parseHex() );
3246  NeedRIGHT();
3247  break;
3248 
3249  default:
3250  Expecting( "x, plus, at, size, width, layer or tstamp" );
3251  }
3252  }
3253 
3254  return target.release();
3255 }
int parseBoardUnits()
Definition: pcb_parser.h:223
PCB_LAYER_ID parseBoardItemLayer()
Function parseBoardItemLayer parses the layer definition of a BOARD_ITEM object.
Definition: pcb_parser.cpp:996
long parseHex()
Definition: pcb_parser.h:258
void PCB_PARSER::parseSetup ( )
private

Definition at line 1029 of file pcb_parser.cpp.

References BOARD_DESIGN_SETTINGS::m_AuxOrigin, BOARD_DESIGN_SETTINGS::m_BlindBuriedViaAllowed, BOARD_DESIGN_SETTINGS::m_DrawSegmentWidth, BOARD_DESIGN_SETTINGS::m_EdgeSegmentWidth, BOARD_DESIGN_SETTINGS::m_GridOrigin, BOARD_DESIGN_SETTINGS::m_MicroViasAllowed, BOARD_DESIGN_SETTINGS::m_MicroViasMinDrill, BOARD_DESIGN_SETTINGS::m_MicroViasMinSize, BOARD_DESIGN_SETTINGS::m_ModuleSegmentWidth, BOARD_DESIGN_SETTINGS::m_ModuleTextSize, BOARD_DESIGN_SETTINGS::m_ModuleTextWidth, BOARD_DESIGN_SETTINGS::m_Pad_Master, BOARD_DESIGN_SETTINGS::m_PcbTextSize, BOARD_DESIGN_SETTINGS::m_PcbTextWidth, BOARD_DESIGN_SETTINGS::m_SolderMaskMargin, BOARD_DESIGN_SETTINGS::m_SolderMaskMinWidth, BOARD_DESIGN_SETTINGS::m_SolderPasteMargin, BOARD_DESIGN_SETTINGS::m_SolderPasteMarginRatio, BOARD_DESIGN_SETTINGS::m_TrackMinWidth, BOARD_DESIGN_SETTINGS::m_TrackWidthList, BOARD_DESIGN_SETTINGS::m_ViasDimensionsList, BOARD_DESIGN_SETTINGS::m_ViasMinDrill, BOARD_DESIGN_SETTINGS::m_ViasMinSize, ZONE_SETTINGS::m_Zone_45_Only, ZONE_SETTINGS::m_ZoneClearance, MIN_VISIBILITY_MASK, PCB_PLOT_PARAMS::Parse(), parseDouble(), parseHex(), D_PAD::SetDrillSize(), D_PAD::SetSize(), and BOARD_DESIGN_SETTINGS::SetVisibleElements().

Referenced by getNetCode().

1030 {
1031  wxCHECK_RET( CurTok() == T_setup,
1032  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as setup." ) );
1033 
1034  T token;
1035  NETCLASSPTR defaultNetClass = m_board->GetDesignSettings().GetDefault();
1036  // TODO Orson: is it really necessary to first operate on a copy and then apply it?
1037  // would not it be better to use reference here and apply all the changes instantly?
1038  BOARD_DESIGN_SETTINGS designSettings = m_board->GetDesignSettings();
1039  ZONE_SETTINGS zoneSettings = m_board->GetZoneSettings();
1040 
1041  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1042  {
1043  if( token != T_LEFT )
1044  Expecting( T_LEFT );
1045 
1046  token = NextTok();
1047 
1048  switch( token )
1049  {
1050  case T_last_trace_width: // not used now
1051  /* lastTraceWidth =*/ parseBoardUnits( T_last_trace_width );
1052  NeedRIGHT();
1053  break;
1054 
1055  case T_user_trace_width:
1056  designSettings.m_TrackWidthList.push_back( parseBoardUnits( T_user_trace_width ) );
1057  NeedRIGHT();
1058  break;
1059 
1060  case T_trace_clearance:
1061  defaultNetClass->SetClearance( parseBoardUnits( T_trace_clearance ) );
1062  NeedRIGHT();
1063  break;
1064 
1065  case T_zone_clearance:
1066  zoneSettings.m_ZoneClearance = parseBoardUnits( T_zone_clearance );
1067  NeedRIGHT();
1068  break;
1069 
1070  case T_zone_45_only:
1071  zoneSettings.m_Zone_45_Only = parseBool();
1072  NeedRIGHT();
1073  break;
1074 
1075  case T_trace_min:
1076  designSettings.m_TrackMinWidth = parseBoardUnits( T_trace_min );
1077  NeedRIGHT();
1078  break;
1079 
1080  case T_segment_width:
1081  designSettings.m_DrawSegmentWidth = parseBoardUnits( T_segment_width );
1082  NeedRIGHT();
1083  break;
1084 
1085  case T_edge_width:
1086  designSettings.m_EdgeSegmentWidth = parseBoardUnits( T_edge_width );
1087  NeedRIGHT();
1088  break;
1089 
1090  case T_via_size:
1091  defaultNetClass->SetViaDiameter( parseBoardUnits( T_via_size ) );
1092  NeedRIGHT();
1093  break;
1094 
1095  case T_via_drill:
1096  defaultNetClass->SetViaDrill( parseBoardUnits( T_via_drill ) );
1097  NeedRIGHT();
1098  break;
1099 
1100  case T_via_min_size:
1101  designSettings.m_ViasMinSize = parseBoardUnits( T_via_min_size );
1102  NeedRIGHT();
1103  break;
1104 
1105  case T_via_min_drill:
1106  designSettings.m_ViasMinDrill = parseBoardUnits( T_via_min_drill );
1107  NeedRIGHT();
1108  break;
1109 
1110  case T_user_via:
1111  {
1112  int viaSize = parseBoardUnits( "user via size" );
1113  int viaDrill = parseBoardUnits( "user via drill" );
1114  designSettings.m_ViasDimensionsList.push_back( VIA_DIMENSION( viaSize, viaDrill ) );
1115  NeedRIGHT();
1116  }
1117  break;
1118 
1119  case T_uvia_size:
1120  defaultNetClass->SetuViaDiameter( parseBoardUnits( T_uvia_size ) );
1121  NeedRIGHT();
1122  break;
1123 
1124  case T_uvia_drill:
1125  defaultNetClass->SetuViaDrill( parseBoardUnits( T_uvia_drill ) );
1126  NeedRIGHT();
1127  break;
1128 
1129  case T_uvias_allowed:
1130  designSettings.m_MicroViasAllowed = parseBool();
1131  NeedRIGHT();
1132  break;
1133 
1134  case T_blind_buried_vias_allowed:
1135  designSettings.m_BlindBuriedViaAllowed = parseBool();
1136  NeedRIGHT();
1137  break;
1138 
1139  case T_uvia_min_size:
1140  designSettings.m_MicroViasMinSize = parseBoardUnits( T_uvia_min_size );
1141  NeedRIGHT();
1142  break;
1143 
1144  case T_uvia_min_drill:
1145  designSettings.m_MicroViasMinDrill = parseBoardUnits( T_uvia_min_drill );
1146  NeedRIGHT();
1147  break;
1148 
1149  case T_pcb_text_width:
1150  designSettings.m_PcbTextWidth = parseBoardUnits( T_pcb_text_width );
1151  NeedRIGHT();
1152  break;
1153 
1154  case T_pcb_text_size:
1155  designSettings.m_PcbTextSize.x = parseBoardUnits( "pcb text width" );
1156  designSettings.m_PcbTextSize.y = parseBoardUnits( "pcb text height" );
1157  NeedRIGHT();
1158  break;
1159 
1160  case T_mod_edge_width:
1161  designSettings.m_ModuleSegmentWidth = parseBoardUnits( T_mod_edge_width );
1162  NeedRIGHT();
1163  break;
1164 
1165  case T_mod_text_size:
1166  designSettings.m_ModuleTextSize.x = parseBoardUnits( "module text width" );
1167  designSettings.m_ModuleTextSize.y = parseBoardUnits( "module text height" );
1168  NeedRIGHT();
1169  break;
1170 
1171  case T_mod_text_width:
1172  designSettings.m_ModuleTextWidth = parseBoardUnits( T_mod_text_width );
1173  NeedRIGHT();
1174  break;
1175 
1176  case T_pad_size:
1177  {
1178  wxSize sz;
1179  sz.SetWidth( parseBoardUnits( "master pad width" ) );
1180  sz.SetHeight( parseBoardUnits( "master pad height" ) );
1181  designSettings.m_Pad_Master.SetSize( sz );
1182  NeedRIGHT();
1183  }
1184  break;
1185 
1186  case T_pad_drill:
1187  {
1188  int drillSize = parseBoardUnits( T_pad_drill );
1189  designSettings.m_Pad_Master.SetDrillSize( wxSize( drillSize, drillSize ) );
1190  NeedRIGHT();
1191  }
1192  break;
1193 
1194  case T_pad_to_mask_clearance:
1195  designSettings.m_SolderMaskMargin = parseBoardUnits( T_pad_to_mask_clearance );
1196  NeedRIGHT();
1197  break;
1198 
1199  case T_solder_mask_min_width:
1200  designSettings.m_SolderMaskMinWidth = parseBoardUnits( T_solder_mask_min_width );
1201  NeedRIGHT();
1202  break;
1203 
1204  case T_pad_to_paste_clearance:
1205  designSettings.m_SolderPasteMargin = parseBoardUnits( T_pad_to_paste_clearance );
1206  NeedRIGHT();
1207  break;
1208 
1209  case T_pad_to_paste_clearance_ratio:
1210  designSettings.m_SolderPasteMarginRatio = parseDouble( T_pad_to_paste_clearance_ratio );
1211  NeedRIGHT();
1212  break;
1213 
1214  case T_aux_axis_origin:
1215  {
1216  int x = parseBoardUnits( "auxiliary origin X" );
1217  int y = parseBoardUnits( "auxiliary origin Y" );
1218  // m_board->SetAuxOrigin( wxPoint( x, y ) ); gets overwritten via SetDesignSettings below
1219  designSettings.m_AuxOrigin = wxPoint( x, y );
1220  NeedRIGHT();
1221  }
1222  break;
1223 
1224  case T_grid_origin:
1225  {
1226  int x = parseBoardUnits( "grid origin X" );
1227  int y = parseBoardUnits( "grid origin Y" );
1228  // m_board->SetGridOrigin( wxPoint( x, y ) ); gets overwritten SetDesignSettings below
1229  designSettings.m_GridOrigin = wxPoint( x, y );
1230  NeedRIGHT();
1231  }
1232  break;
1233 
1234  case T_visible_elements:
1235  designSettings.SetVisibleElements( parseHex() | MIN_VISIBILITY_MASK );
1236  NeedRIGHT();
1237  break;
1238 
1239  case T_pcbplotparams:
1240  {
1241  PCB_PLOT_PARAMS plotParams;
1242  PCB_PLOT_PARAMS_PARSER parser( reader );
1243  // parser must share the same current line as our current PCB parser
1244  // synchronize it.
1245  parser.SyncLineReaderWith( *this );
1246 
1247  plotParams.Parse( &parser );
1248  SyncLineReaderWith( parser );
1249 
1250  m_board->SetPlotOptions( plotParams );
1251  }
1252  break;
1253 
1254  default:
1255  Unexpected( CurText() );
1256  }
1257  }
1258 
1259  m_board->SetDesignSettings( designSettings );
1260  m_board->SetZoneSettings( zoneSettings );
1261 }
int m_SolderMaskMargin
Solder mask margin.
Struct VIA_DIMENSION is a small helper container to handle a stock of specific vias each with unique ...
void SetZoneSettings(const ZONE_SETTINGS &aSettings)
Definition: class_board.h:557
const ZONE_SETTINGS & GetZoneSettings() const
Definition: class_board.h:556
NETCLASSPTR GetDefault() const
Function GetDefault.
wxPoint m_GridOrigin
origin for grid offsets
int m_SolderPasteMargin
Solder paste margin absolute value.
Class PCB_PLOT_PARAMS_PARSER is the parser class for PCB_PLOT_PARAMS.
int m_ModuleTextWidth
Default footprint texts thickness.
std::vector< int > m_TrackWidthList
Track width list.
int m_ModuleSegmentWidth
Default width for all graphic lines.
int m_PcbTextWidth
current Pcb (not module) Text width
void SetDrillSize(const wxSize &aSize)
Definition: class_pad.h:274
wxSize m_ModuleTextSize
Default footprint texts size.
int parseBoardUnits()
Definition: pcb_parser.h:223
bool parseBool()
Definition: pcb_parser.cpp:154
#define MIN_VISIBILITY_MASK
wxSize m_PcbTextSize
current Pcb (not module) Text size
int m_TrackMinWidth
track min value for width ((min copper size value
int m_ViasMinSize
vias (not micro vias) min diameter
int m_DrawSegmentWidth
current graphic line width (not EDGE layer)
int m_ViasMinDrill
vias (not micro vias) min drill diameter
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:532
void SetSize(const wxSize &aSize)
Definition: class_pad.h:268
int m_ZoneClearance
Clearance value.
Definition: zone_settings.h:63
void SetDesignSettings(const BOARD_DESIGN_SETTINGS &aDesignSettings)
Function SetDesignSettings.
Definition: class_board.h:542
bool m_BlindBuriedViaAllowed
true to allow blind/buried vias
void SetPlotOptions(const PCB_PLOT_PARAMS &aOptions)
Definition: class_board.h:551
int m_MicroViasMinSize
micro vias (not vias) min diameter
Class PCB_PLOT_PARAMS handles plot parameters and options when plotting/printing a board...
Class ZONE_SETTINGS handles zones parameters.
Definition: zone_settings.h:49
BOARD * m_board
Definition: pcb_parser.h:70
D_PAD m_Pad_Master
A dummy pad to store all default parameters.
void SetVisibleElements(int aMask)
Function SetVisibleElements changes the bit-mask of visible element categories.
std::vector< VIA_DIMENSION > m_ViasDimensionsList
Vias size and drill list.
double parseDouble()
Function parseDouble parses the current token as an ASCII numeric string with possible leading whites...
Definition: pcb_parser.cpp:124
bool m_MicroViasAllowed
true to allow micro vias
int m_MicroViasMinDrill
micro vias (not vias) min drill diameter
long parseHex()
Definition: pcb_parser.h:258
int m_EdgeSegmentWidth
current graphic line width (EDGE layer only)
double m_SolderPasteMarginRatio
Solder pask margin ratio value of pad size The final margin is the sum of these 2 values...
void Parse(PCB_PLOT_PARAMS_PARSER *aParser)
wxPoint m_AuxOrigin
origin for plot exports
int m_SolderMaskMinWidth
Solder mask min width.
Class BOARD_DESIGN_SETTINGS contains design settings for a BOARD object.
TEXTE_MODULE * PCB_PARSER::parseTEXTE_MODULE ( )
private

Definition at line 2028 of file pcb_parser.cpp.

References Format(), GetChars(), parseDouble(), TEXTE_MODULE::TEXT_is_REFERENCE, TEXTE_MODULE::TEXT_is_VALUE, THROW_IO_ERROR, wxPoint::x, and wxPoint::y.

Referenced by getNetCode().

2029 {
2030  wxCHECK_MSG( CurTok() == T_fp_text, NULL,
2031  wxString::Format( wxT( "Cannot parse %s as TEXTE_MODULE at line %d, offset %d." ),
2032  GetChars( GetTokenString( CurTok() ) ),
2033  CurLineNumber(), CurOffset() ) );
2034 
2035  T token = NextTok();
2036 
2037  std::unique_ptr<TEXTE_MODULE> text( new TEXTE_MODULE( NULL ) );
2038 
2039  switch( token )
2040  {
2041  case T_reference:
2042  text->SetType( TEXTE_MODULE::TEXT_is_REFERENCE );
2043  break;
2044 
2045  case T_value:
2046  text->SetType( TEXTE_MODULE::TEXT_is_VALUE );
2047  break;
2048 
2049  case T_user:
2050  break; // Default type is user text.
2051 
2052  default:
2053  THROW_IO_ERROR( wxString::Format( _( "Cannot handle footprint text type %s" ),
2054  GetChars( FromUTF8() ) ) );
2055  }
2056 
2057  NeedSYMBOLorNUMBER();
2058 
2059  text->SetText( FromUTF8() );
2060  NeedLEFT();
2061  token = NextTok();
2062 
2063  if( token != T_at )
2064  Expecting( T_at );
2065 
2066  wxPoint pt;
2067 
2068  pt.x = parseBoardUnits( "X coordinate" );
2069  pt.y = parseBoardUnits( "Y coordinate" );
2070  text->SetPos0( pt );
2071 
2072  NextTok();
2073 
2074  if( CurTok() == T_NUMBER )
2075  {
2076  text->SetTextAngle( parseDouble() * 10.0 );
2077  NextTok();
2078  }
2079 
2080  if( CurTok() == T_unlocked )
2081  {
2082  text->SetUnlocked( true );
2083  NextTok();
2084  }
2085 
2086  if( CurTok() != T_RIGHT )
2087  {
2088  Unexpected( CurText() );
2089  }
2090 
2091  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2092  {
2093  if( token == T_LEFT )
2094  token = NextTok();
2095 
2096  switch( token )
2097  {
2098  case T_layer:
2099  text->SetLayer( parseBoardItemLayer() );
2100  NeedRIGHT();
2101  break;
2102 
2103  case T_hide:
2104  text->SetVisible( false );
2105  break;
2106 
2107  case T_effects:
2108  parseEDA_TEXT( (EDA_TEXT*) text.get() );
2109  break;
2110 
2111  default:
2112  Expecting( "hide or effects" );
2113  }
2114  }
2115 
2116  return text.release();
2117 }
void parseEDA_TEXT(EDA_TEXT *aText)
Function parseEDA_TEXT parses the common settings for any object derived from EDA_TEXT.
Definition: pcb_parser.cpp:238
int parseBoardUnits()
Definition: pcb_parser.h:223
Class EDA_TEXT is a mix-in class (via multiple inheritance) that handles texts such as labels...
Definition: eda_text.h:112
PCB_LAYER_ID parseBoardItemLayer()
Function parseBoardItemLayer parses the layer definition of a BOARD_ITEM object.
Definition: pcb_parser.cpp:996
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 Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
double parseDouble()
Function parseDouble parses the current token as an ASCII numeric string with possible leading whites...
Definition: pcb_parser.cpp:124
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
TEXTE_PCB * PCB_PARSER::parseTEXTE_PCB ( )
private

Definition at line 1538 of file pcb_parser.cpp.

References parseDouble(), parseHex(), wxPoint::x, and wxPoint::y.

Referenced by getNetCode().

1539 {
1540  wxCHECK_MSG( CurTok() == T_gr_text, NULL,
1541  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as TEXTE_PCB." ) );
1542 
1543  T token;
1544 
1545  std::unique_ptr<TEXTE_PCB> text( new TEXTE_PCB( m_board ) );
1546  NeedSYMBOLorNUMBER();
1547 
1548  text->SetText( FromUTF8() );
1549  NeedLEFT();
1550  token = NextTok();
1551 
1552  if( token != T_at )
1553  Expecting( T_at );
1554 
1555  wxPoint pt;
1556 
1557  pt.x = parseBoardUnits( "X coordinate" );
1558  pt.y = parseBoardUnits( "Y coordinate" );
1559  text->SetTextPos( pt );
1560 
1561  // If there is no orientation defined, then it is the default value of 0 degrees.
1562  token = NextTok();
1563 
1564  if( token == T_NUMBER )
1565  {
1566  text->SetTextAngle( parseDouble() * 10.0 );
1567  NeedRIGHT();
1568  }
1569  else if( token != T_RIGHT )
1570  {
1571  Unexpected( CurText() );
1572  }
1573 
1574  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1575  {
1576  if( token != T_LEFT )
1577  Expecting( T_LEFT );
1578 
1579  token = NextTok();
1580 
1581  switch( token )
1582  {
1583  case T_layer:
1584  text->SetLayer( parseBoardItemLayer() );
1585  NeedRIGHT();
1586  break;
1587 
1588  case T_tstamp:
1589  text->SetTimeStamp( parseHex() );
1590  NeedRIGHT();
1591  break;
1592 
1593  case T_effects:
1594  parseEDA_TEXT( (EDA_TEXT*) text.get() );
1595  break;
1596 
1597  default:
1598  Expecting( "layer, tstamp or effects" );
1599  }
1600  }
1601 
1602  return text.release();
1603 }
void parseEDA_TEXT(EDA_TEXT *aText)
Function parseEDA_TEXT parses the common settings for any object derived from EDA_TEXT.
Definition: pcb_parser.cpp:238
int parseBoardUnits()
Definition: pcb_parser.h:223
Class EDA_TEXT is a mix-in class (via multiple inheritance) that handles texts such as labels...
Definition: eda_text.h:112
PCB_LAYER_ID parseBoardItemLayer()
Function parseBoardItemLayer parses the layer definition of a BOARD_ITEM object.
Definition: pcb_parser.cpp:996
BOARD * m_board
Definition: pcb_parser.h:70
double parseDouble()
Function parseDouble parses the current token as an ASCII numeric string with possible leading whites...
Definition: pcb_parser.cpp:124
long parseHex()
Definition: pcb_parser.h:258
void PCB_PARSER::parseTITLE_BLOCK ( )
private

Definition at line 725 of file pcb_parser.cpp.

References err, parseInt(), TITLE_BLOCK::SetComment1(), TITLE_BLOCK::SetComment2(), TITLE_BLOCK::SetComment3(), TITLE_BLOCK::SetComment4(), TITLE_BLOCK::SetCompany(), TITLE_BLOCK::SetDate(), TITLE_BLOCK::SetRevision(), TITLE_BLOCK::SetTitle(), and THROW_PARSE_ERROR.

Referenced by getNetCode().

726 {
727  wxCHECK_RET( CurTok() == T_title_block,
728  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
729  wxT( " as TITLE_BLOCK." ) );
730 
731  T token;
732  TITLE_BLOCK titleBlock;
733 
734  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
735  {
736  if( token != T_LEFT )
737  Expecting( T_LEFT );
738 
739  token = NextTok();
740 
741  switch( token )
742  {
743  case T_title:
744  NextTok();
745  titleBlock.SetTitle( FromUTF8() );
746  break;
747 
748  case T_date:
749  NextTok();
750  titleBlock.SetDate( FromUTF8() );
751  break;
752 
753  case T_rev:
754  NextTok();
755  titleBlock.SetRevision( FromUTF8() );
756  break;
757 
758  case T_company:
759  NextTok();
760  titleBlock.SetCompany( FromUTF8() );
761  break;
762 
763  case T_comment:
764  {
765  int commentNumber = parseInt( "comment" );
766 
767  switch( commentNumber )
768  {
769  case 1:
770  NextTok();
771  titleBlock.SetComment1( FromUTF8() );
772  break;
773 
774  case 2:
775  NextTok();
776  titleBlock.SetComment2( FromUTF8() );
777  break;
778 
779  case 3:
780  NextTok();
781  titleBlock.SetComment3( FromUTF8() );
782  break;
783 
784  case 4:
785  NextTok();
786  titleBlock.SetComment4( FromUTF8() );
787  break;
788 
789  default:
790  wxString err;
791  err.Printf( wxT( "%d is not a valid title block comment number" ), commentNumber );
792  THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
793  }
794  }
795  break;
796 
797  default:
798  Expecting( "title, date, rev, company, or comment" );
799  }
800 
801  NeedRIGHT();
802  }
803 
804  m_board->SetTitleBlock( titleBlock );
805 }
void SetComment1(const wxString &aComment)
Definition: title_block.h:116
void SetRevision(const wxString &aRevision)
Definition: title_block.h:83
void SetTitleBlock(const TITLE_BLOCK &aTitleBlock)
Definition: class_board.h:554
void SetDate(const wxString &aDate)
Function SetDate sets the date field, and defaults to the current time and date.
Definition: title_block.h:73
Class TITLE_BLOCK holds the information shown in the lower right corner of a plot, printout, or editing view.
Definition: title_block.h:39
void SetComment4(const wxString &aComment)
Definition: title_block.h:119
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
Definition: ki_exception.h:133
void SetCompany(const wxString &aCompany)
Definition: title_block.h:93
void SetTitle(const wxString &aTitle)
Definition: title_block.h:59
string & err
Definition: json11.cpp:598
void SetComment2(const wxString &aComment)
Definition: title_block.h:117
BOARD * m_board
Definition: pcb_parser.h:70
void SetComment3(const wxString &aComment)
Definition: title_block.h:118
int parseInt()
Definition: pcb_parser.h:247
TRACK * PCB_PARSER::parseTRACK ( )
private

Definition at line 2671 of file pcb_parser.cpp.

References Format(), GetChars(), parseHex(), parseInt(), THROW_IO_ERROR, wxPoint::x, and wxPoint::y.

Referenced by getNetCode().

2672 {
2673  wxCHECK_MSG( CurTok() == T_segment, NULL,
2674  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as TRACK." ) );
2675 
2676  wxPoint pt;
2677  T token;
2678 
2679  std::unique_ptr< TRACK > track( new TRACK( m_board ) );
2680 
2681  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2682  {
2683  if( token != T_LEFT )
2684  Expecting( T_LEFT );
2685 
2686  token = NextTok();
2687 
2688  switch( token )
2689  {
2690  case T_start:
2691  pt.x = parseBoardUnits( "start x" );
2692  pt.y = parseBoardUnits( "start y" );
2693  track->SetStart( pt );
2694  break;
2695 
2696  case T_end:
2697  pt.x = parseBoardUnits( "end x" );
2698  pt.y = parseBoardUnits( "end y" );
2699  track->SetEnd( pt );
2700  break;
2701 
2702  case T_width:
2703  track->SetWidth( parseBoardUnits( "width" ) );
2704  break;
2705 
2706  case T_layer:
2707  track->SetLayer( parseBoardItemLayer() );
2708  break;
2709 
2710  case T_net:
2711  if( ! track->SetNetCode( getNetCode( parseInt( "net number" ) ), /* aNoAssert */ true ) )
2713  wxString::Format( _( "Invalid net ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),
2714  GetChars( CurSource() ), CurLineNumber(), CurOffset() )
2715  );
2716  break;
2717 
2718  case T_tstamp:
2719  track->SetTimeStamp( parseHex() );
2720  break;
2721 
2722  case T_status:
2723  track->SetStatus( static_cast<STATUS_FLAGS>( parseHex() ) );
2724  break;
2725 
2726  default:
2727  Expecting( "start, end, width, layer, net, tstamp, or status" );
2728  }
2729 
2730  NeedRIGHT();
2731  }
2732 
2733  return track.release();
2734 }
int parseBoardUnits()
Definition: pcb_parser.h:223
PCB_LAYER_ID parseBoardItemLayer()
Function parseBoardItemLayer parses the layer definition of a BOARD_ITEM object.
Definition: pcb_parser.cpp:996
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 Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
int getNetCode(int aNetCode)
Converts net code using the mapping table if available, otherwise returns unchanged net code if < 0 o...
Definition: pcb_parser.h:79
BOARD * m_board
Definition: pcb_parser.h:70
long parseHex()
Definition: pcb_parser.h:258
int parseInt()
Definition: pcb_parser.h:247
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
int PCB_PARSER::parseVersion ( )
private

Parse a format version tag like (version 20160417) return the version.

Expects to start on 'version', and eats the closing paren.

Definition at line 169 of file pcb_parser.cpp.

References DSN::GetTokenText(), and parseInt().

Referenced by parseHex().

170 {
171  if( NextTok() != T_version )
172  Expecting( GetTokenText( T_version ) );
173 
174  int pcb_version = parseInt( FromUTF8().mb_str( wxConvUTF8 ) );
175 
176  NeedRIGHT();
177 
178  return pcb_version;
179 }
const char * GetTokenText(T aTok)
Function GetTokenText is in the DSN namespace and returns the C string representing a SPECCTRA_DB::ke...
Definition: specctra.cpp:69
int parseInt()
Definition: pcb_parser.h:247
VIA * PCB_PARSER::parseVIA ( )
private

Definition at line 2737 of file pcb_parser.cpp.

References Format(), GetChars(), parseHex(), parseInt(), THROW_IO_ERROR, VIA, VIA_BLIND_BURIED, VIA_MICROVIA, wxPoint::x, and wxPoint::y.

Referenced by getNetCode().

2738 {
2739  wxCHECK_MSG( CurTok() == T_via, NULL,
2740  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as VIA." ) );
2741 
2742  wxPoint pt;
2743  T token;
2744 
2745  std::unique_ptr< VIA > via( new VIA( m_board ) );
2746 
2747  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2748  {
2749  if( token == T_LEFT )
2750  token = NextTok();
2751 
2752  switch( token )
2753  {
2754  case T_blind:
2755  via->SetViaType( VIA_BLIND_BURIED );
2756  break;
2757 
2758  case T_micro:
2759  via->SetViaType( VIA_MICROVIA );
2760  break;
2761 
2762  case T_at:
2763  pt.x = parseBoardUnits( "start x" );
2764  pt.y = parseBoardUnits( "start y" );
2765  via->SetStart( pt );
2766  via->SetEnd( pt );
2767  NeedRIGHT();
2768  break;
2769 
2770  case T_size:
2771  via->SetWidth( parseBoardUnits( "via width" ) );
2772  NeedRIGHT();
2773  break;
2774 
2775  case T_drill:
2776  via->SetDrill( parseBoardUnits( "drill diameter" ) );
2777  NeedRIGHT();
2778  break;
2779 
2780  case T_layers:
2781  {
2782  PCB_LAYER_ID layer1, layer2;
2783  NextTok();
2784  layer1 = lookUpLayer<PCB_LAYER_ID>( m_layerIndices );
2785  NextTok();
2786  layer2 = lookUpLayer<PCB_LAYER_ID>( m_layerIndices );
2787  via->SetLayerPair( layer1, layer2 );
2788  NeedRIGHT();
2789  }
2790  break;
2791 
2792  case T_net:
2793  if(! via->SetNetCode( getNetCode( parseInt( "net number" ) ), /* aNoAssert */ true))
2795  wxString::Format( _( "Invalid net ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),
2796  GetChars( CurSource() ), CurLineNumber(), CurOffset() )
2797  );
2798  NeedRIGHT();
2799  break;
2800 
2801  case T_tstamp:
2802  via->SetTimeStamp( parseHex() );
2803  NeedRIGHT();
2804  break;
2805 
2806  case T_status:
2807  via->SetStatus( static_cast<STATUS_FLAGS>( parseHex() ) );
2808  NeedRIGHT();
2809  break;
2810 
2811  default:
2812  Expecting( "blind, micro, at, size, drill, layers, net, tstamp, or status" );
2813  }
2814  }
2815 
2816  return via.release();
2817 }
int parseBoardUnits()
Definition: pcb_parser.h:223
PCB_LAYER_ID
A quick note on layer IDs:
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 Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
int getNetCode(int aNetCode)
Converts net code using the mapping table if available, otherwise returns unchanged net code if < 0 o...
Definition: pcb_parser.h:79
BOARD * m_board
Definition: pcb_parser.h:70
LAYER_ID_MAP m_layerIndices
map layer name to it&#39;s index
Definition: pcb_parser.h:71
long parseHex()
Definition: pcb_parser.h:258
int parseInt()
Definition: pcb_parser.h:247
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
wxPoint PCB_PARSER::parseXY ( )
private

Function parseXY parses a coordinate pair (xy X Y) in board units (mm).

The parser checks if the previous token was T_LEFT and parses the remainder of the token syntax. This is used when parsing a list of coordinate points. This way the parser can be used in either case.

Exceptions
PARSE_ERRORif the coordinate pair syntax is incorrect.
Returns
A wxPoint object containing the coordinate pair.

Definition at line 206 of file pcb_parser.cpp.

References wxPoint::x, and wxPoint::y.

Referenced by getNetCode().

207 {
208  if( CurTok() != T_LEFT )
209  NeedLEFT();
210 
211  wxPoint pt;
212  T token = NextTok();
213 
214  if( token != T_xy )
215  Expecting( T_xy );
216 
217  pt.x = parseBoardUnits( "X coordinate" );
218  pt.y = parseBoardUnits( "Y coordinate" );
219 
220  NeedRIGHT();
221 
222  return pt;
223 }
int parseBoardUnits()
Definition: pcb_parser.h:223
void PCB_PARSER::parseXY ( int *  aX,
int *  aY 
)
private

Definition at line 226 of file pcb_parser.cpp.

References wxPoint::x, and wxPoint::y.

227 {
228  wxPoint pt = parseXY();
229 
230  if( aX )
231  *aX = pt.x;
232 
233  if( aY )
234  *aY = pt.y;
235 }
wxPoint parseXY()
Function parseXY parses a coordinate pair (xy X Y) in board units (mm).
Definition: pcb_parser.cpp:206
ZONE_CONTAINER * PCB_PARSER::parseZONE_CONTAINER ( )
private

Definition at line 2820 of file pcb_parser.cpp.

References SHAPE_POLY_SET::Append(), ZONE_CONTAINER::DIAGONAL_EDGE, ZONE_CONTAINER::DIAGONAL_FULL, DisplayError(), Format(), GetChars(), ZONE_CONTAINER::GetDefaultHatchPitch(), NETINFO_ITEM::GetNet(), SHAPE_POLY_SET::IsEmpty(), SHAPE_POLY_SET::NewOutline(), ZONE_CONTAINER::NO_HATCH, PAD_ZONE_CONN_FULL, PAD_ZONE_CONN_NONE, PAD_ZONE_CONN_THT_THERMAL, parseHex(), parseInt(), NETINFO_ITEM::SetNetCode(), ZONE_SETTINGS::SMOOTHING_CHAMFER, ZONE_SETTINGS::SMOOTHING_FILLET, ZONE_SETTINGS::SMOOTHING_NONE, THROW_IO_ERROR, NETINFO_LIST::UNCONNECTED, ZFM_POLYGONS, and ZFM_SEGMENTS.

Referenced by getNetCode().

2821 {
2822  wxCHECK_MSG( CurTok() == T_zone, NULL,
2823  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
2824  wxT( " as ZONE_CONTAINER." ) );
2825 
2827 
2828  int hatchPitch = ZONE_CONTAINER::GetDefaultHatchPitch();
2829  wxPoint pt;
2830  T token;
2831  int tmp;
2832  wxString netnameFromfile; // the zone net name find in file
2833 
2834  // bigger scope since each filled_polygon is concatenated in here
2835  SHAPE_POLY_SET pts;
2836 
2837  std::unique_ptr< ZONE_CONTAINER > zone( new ZONE_CONTAINER( m_board ) );
2838 
2839  zone->SetPriority( 0 );
2840 
2841  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2842  {
2843  if( token == T_LEFT )
2844  token = NextTok();
2845 
2846  switch( token )
2847  {
2848  case T_net:
2849  // Init the net code only, not the netname, to be sure
2850  // the zone net name is the name read in file.
2851  // (When mismatch, the user will be prompted in DRC, to fix the actual name)
2852  tmp = getNetCode( parseInt( "net number" ) );
2853 
2854  if( tmp < 0 )
2855  tmp = 0;
2856 
2857  if( ! zone->SetNetCode( tmp, /* aNoAssert */ true ) )
2859  wxString::Format( _( "Invalid net ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),
2860  GetChars( CurSource() ), CurLineNumber(), CurOffset() )
2861  );
2862 
2863  NeedRIGHT();
2864  break;
2865 
2866  case T_net_name:
2867  NeedSYMBOLorNUMBER();
2868  netnameFromfile = FromUTF8();
2869  NeedRIGHT();
2870  break;
2871 
2872  case T_layer: // keyword for zones that are on only one layer
2873  zone->SetLayer( parseBoardItemLayer() );
2874  NeedRIGHT();
2875  break;
2876 
2877  case T_layers: // keyword for zones that can live on a set of layer
2878  // currently: keepout zones
2879  zone->SetLayerSet( parseBoardItemLayersAsMask() );
2880  break;
2881 
2882  case T_tstamp:
2883  zone->SetTimeStamp( parseHex() );
2884  NeedRIGHT();
2885  break;
2886 
2887  case T_hatch:
2888  token = NextTok();
2889 
2890  if( token != T_none && token != T_edge && token != T_full )
2891  Expecting( "none, edge, or full" );
2892 
2893  switch( token )
2894  {
2895  default:
2896  case T_none: hatchStyle = ZONE_CONTAINER::NO_HATCH; break;
2897  case T_edge: hatchStyle = ZONE_CONTAINER::DIAGONAL_EDGE; break;
2898  case T_full: hatchStyle = ZONE_CONTAINER::DIAGONAL_FULL;
2899  }
2900 
2901  hatchPitch = parseBoardUnits( "hatch pitch" );
2902  NeedRIGHT();
2903  break;
2904 
2905  case T_priority:
2906  zone->SetPriority( parseInt( "zone priority" ) );
2907  NeedRIGHT();
2908  break;
2909 
2910  case T_connect_pads:
2911  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2912  {
2913  if( token == T_LEFT )
2914  token = NextTok();
2915 
2916  switch( token )
2917  {
2918  case T_yes:
2919  zone->SetPadConnection( PAD_ZONE_CONN_FULL );
2920  break;
2921 
2922  case T_no:
2923  zone->SetPadConnection( PAD_ZONE_CONN_NONE );
2924  break;
2925 
2926  case T_thru_hole_only:
2927  zone->SetPadConnection( PAD_ZONE_CONN_THT_THERMAL );
2928  break;
2929 
2930  case T_clearance:
2931  zone->SetZoneClearance( parseBoardUnits( "zone clearance" ) );
2932  NeedRIGHT();
2933  break;
2934 
2935  default:
2936  Expecting( "yes, no, or clearance" );
2937  }
2938  }
2939 
2940  break;
2941 
2942  case T_min_thickness:
2943  zone->SetMinThickness( parseBoardUnits( T_min_thickness ) );
2944  NeedRIGHT();
2945  break;
2946 
2947  case T_fill:
2948  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2949  {
2950  if( token == T_LEFT )
2951  token = NextTok();
2952 
2953  switch( token )
2954  {
2955  case T_yes:
2956  zone->SetIsFilled( true );
2957  break;
2958 
2959  case T_mode:
2960  token = NextTok();
2961 
2962  if( token != T_segment && token != T_polygon )
2963  Expecting( "segment or polygon" );
2964 
2965  // @todo Create an enum for fill modes.
2966  zone->SetFillMode( token == T_polygon ? ZFM_POLYGONS : ZFM_SEGMENTS );
2967  NeedRIGHT();
2968  break;
2969 
2970  case T_arc_segments:
2971  zone->SetArcSegmentCount( parseInt( "arc segment count" ) );
2972  NeedRIGHT();
2973  break;
2974 
2975  case T_thermal_gap:
2976  zone->SetThermalReliefGap( parseBoardUnits( T_thermal_gap ) );
2977  NeedRIGHT();
2978  break;
2979 
2980  case T_thermal_bridge_width:
2981  zone->SetThermalReliefCopperBridge( parseBoardUnits( T_thermal_bridge_width ) );
2982  NeedRIGHT();
2983  break;
2984 
2985  case T_smoothing:
2986  switch( NextTok() )
2987  {
2988  case T_none:
2989  zone->SetCornerSmoothingType( ZONE_SETTINGS::SMOOTHING_NONE );
2990  break;
2991 
2992  case T_chamfer:
2993  if( !zone->GetIsKeepout() ) // smoothing has meaning only for filled zones
2994  zone->SetCornerSmoothingType( ZONE_SETTINGS::SMOOTHING_CHAMFER );
2995  break;
2996 
2997  case T_fillet:
2998  if( !zone->GetIsKeepout() ) // smoothing has meaning only for filled zones
2999  zone->SetCornerSmoothingType( ZONE_SETTINGS::SMOOTHING_FILLET );
3000  break;
3001 
3002  default:
3003  Expecting( "none, chamfer, or fillet" );
3004  }
3005  NeedRIGHT();
3006  break;
3007 
3008  case T_radius:
3009  tmp = parseBoardUnits( "corner radius" );
3010  if( !zone->GetIsKeepout() ) // smoothing has meaning only for filled zones
3011  zone->SetCornerRadius( tmp );
3012  NeedRIGHT();
3013  break;
3014 
3015  default:
3016  Expecting( "mode, arc_segments, thermal_gap, thermal_bridge_width, "
3017  "smoothing, or radius" );
3018  }
3019  }
3020  break;
3021 
3022  case T_keepout:
3023  zone->SetIsKeepout( true );
3024 
3025  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3026  {
3027  if( token == T_LEFT )
3028  token = NextTok();
3029 
3030  switch( token )
3031  {
3032  case T_tracks:
3033  token = NextTok();
3034 
3035  if( token != T_allowed && token != T_not_allowed )
3036  Expecting( "allowed or not_allowed" );
3037  zone->SetDoNotAllowTracks( token == T_not_allowed );
3038  break;
3039 
3040  case T_vias:
3041  token = NextTok();
3042 
3043  if( token != T_allowed && token != T_not_allowed )
3044  Expecting( "allowed or not_allowed" );
3045  zone->SetDoNotAllowVias( token == T_not_allowed );
3046  break;
3047 
3048  case T_copperpour:
3049  token = NextTok();
3050 
3051  if( token != T_allowed && token != T_not_allowed )
3052  Expecting( "allowed or not_allowed" );
3053  zone->SetDoNotAllowCopperPour( token == T_not_allowed );
3054  break;
3055 
3056  default:
3057  Expecting( "tracks, vias or copperpour" );
3058  }
3059 
3060  NeedRIGHT();
3061  }
3062 
3063  break;
3064 
3065  case T_polygon:
3066  {
3067  std::vector< wxPoint > corners;
3068 
3069  NeedLEFT();
3070  token = NextTok();
3071 
3072  if( token != T_pts )
3073  Expecting( T_pts );
3074 
3075  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3076  {
3077  corners.push_back( parseXY() );
3078  }
3079 
3080  NeedRIGHT();
3081 
3082  // Remark: The first polygon is the main outline.
3083  // Others are holes inside the main outline.
3084  zone->AddPolygon( corners );
3085  }
3086  break;
3087 
3088  case T_filled_polygon:
3089  {
3090  // "(filled_polygon (pts"
3091  NeedLEFT();
3092  token = NextTok();
3093 
3094  if( token != T_pts )
3095  Expecting( T_pts );
3096 
3097  pts.NewOutline();
3098 
3099  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3100  {
3101  pts.Append( parseXY() );
3102  }
3103 
3104  NeedRIGHT();
3105  }
3106  break;
3107 
3108  case T_fill_segments:
3109  {
3110  ZONE_SEGMENT_FILL segs;
3111 
3112  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3113  {
3114  if( token != T_LEFT )
3115  Expecting( T_LEFT );
3116 
3117  token = NextTok();
3118 
3119  if( token != T_pts )
3120  Expecting( T_pts );
3121 
3122  SEG segment( parseXY(), parseXY() );
3123  NeedRIGHT();
3124  segs.push_back( segment );
3125  }
3126 
3127  zone->SetFillSegments( segs );
3128  }
3129  break;
3130 
3131  default:
3132  Expecting( "net, layer/layers, tstamp, hatch, priority, connect_pads, min_thickness, "
3133  "fill, polygon, filled_polygon, or fill_segments" );
3134  }
3135  }
3136 
3137  if( zone->GetNumCorners() > 2 )
3138  {
3139  if( !zone->IsOnCopperLayer() )
3140  {
3141  zone->SetFillMode( ZFM_POLYGONS );
3142  zone->SetNetCode( NETINFO_LIST::UNCONNECTED );
3143  }
3144 
3145  // Set hatch here, after outlines corners are read
3146  zone->SetHatch( hatchStyle, hatchPitch, true );
3147  }
3148 
3149  if( !pts.IsEmpty() )
3150  zone->SetFilledPolysList( pts );
3151 
3152  // Ensure keepout and non copper zones do not have a net
3153  // (which have no sense for these zones)
3154  // the netcode 0 is used for these zones
3155  bool zone_has_net = zone->IsOnCopperLayer() && !zone->GetIsKeepout();
3156 
3157  if( !zone_has_net )
3158  zone->SetNetCode( NETINFO_LIST::UNCONNECTED );
3159 
3160  // Ensure the zone net name is valid, and matches the net code, for copper zones
3161  if( zone_has_net && ( zone->GetNet()->GetNetname() != netnameFromfile ) )
3162  {
3163  // Can happens which old boards, with nonexistent nets ...
3164  // or after being edited by hand
3165  // We try to fix the mismatch.
3166  NETINFO_ITEM* net = m_board->FindNet( netnameFromfile );
3167 
3168  if( net ) // An existing net has the same net name. use it for the zone
3169  zone->SetNetCode( net->GetNet() );
3170  else // Not existing net: add a new net to keep trace of the zone netname
3171  {
3172  int newnetcode = m_board->GetNetCount();
3173  net = new NETINFO_ITEM( m_board, netnameFromfile, newnetcode );
3174  m_board->Add( net );
3175 
3176  // Store the new code mapping
3177  pushValueIntoMap( newnetcode, net->GetNet() );
3178  // and update the zone netcode
3179  zone->SetNetCode( net->GetNet() );
3180 
3181  // FIXME: a call to any GUI item is not allowed in io plugins:
3182  // Change this code to generate a warning message outside this plugin
3183  // Prompt the user
3184  wxString msg;
3185  msg.Printf( _( "There is a zone that belongs to a not existing net\n"
3186  "\"%s\"\n"
3187  "you should verify and edit it (run DRC test)." ),
3188  GetChars( netnameFromfile ) );
3189  DisplayError( NULL, msg );
3190  }
3191  }
3192 
3193  return zone.release();
3194 }
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:60
std::vector< SEG > ZONE_SEGMENT_FILL
Definition: class_zone.h:50
LSET parseBoardItemLayersAsMask()
Function parseBoardItemLayersAsMask parses the layers definition of a BOARD_ITEM object.
wxPoint parseXY()
Function parseXY parses a coordinate pair (xy X Y) in board units (mm).
Definition: pcb_parser.cpp:206
static int GetDefaultHatchPitch()
Function GetDefaultHatchPitchMils.
int parseBoardUnits()
Definition: pcb_parser.h:223
Pads are not covered.
Definition: zones.h:57
Class SHAPE_POLY_SET.
void SetNetCode(int aNetCode)
Definition: netinfo.h:229
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_INSERT) override
Adds an item to the container.
PCB_LAYER_ID parseBoardItemLayer()
Function parseBoardItemLayer parses the layer definition of a BOARD_ITEM object.
Definition: pcb_parser.cpp:996
HATCH_STYLE
Zone hatch styles.
Definition: class_zone.h:67
int GetNet() const
Function GetNet.
Definition: netinfo.h:227
int NewOutline()
Creates a new empty polygon in the set and returns its index
Thermal relief only for THT pads.
Definition: zones.h:60
Definition: seg.h:36
Class NETINFO_ITEM handles the data for a net.
Definition: netinfo.h:69
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 Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
int getNetCode(int aNetCode)
Converts net code using the mapping table if available, otherwise returns unchanged net code if < 0 o...
Definition: pcb_parser.h:79
BOARD * m_board
Definition: pcb_parser.h:70
void pushValueIntoMap(int aIndex, int aValue)
function pushValueIntoMap Add aValue value in netcode mapping (m_netCodes) at index aIndex ensure the...
Definition: pcb_parser.cpp:113
NETINFO_ITEM * FindNet(int aNetcode) const
Function FindNet searches for a net with the given netcode.
bool IsEmpty() const
Returns true if the set is empty (no polygons at all)
long parseHex()
Definition: pcb_parser.h:258
int parseInt()
Definition: pcb_parser.h:247
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:185
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
Definition: netinfo.h:461
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
unsigned GetNetCount() const
Function GetNetCount.
Definition: class_board.h:772
pads are covered by copper
Definition: zones.h:59
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline) ...
void PCB_PARSER::pushValueIntoMap ( int  aIndex,
int  aValue 
)
private

function pushValueIntoMap Add aValue value in netcode mapping (m_netCodes) at index aIndex ensure there is room in m_netCodes for that, and add room if needed.

Parameters
aIndex= the index ( expected >=0 )of the location to use in m_netCodes
aValue= the netcode value to map

Definition at line 113 of file pcb_parser.cpp.

Referenced by getNetCode().

114 {
115  // Add aValue in netcode mapping (m_netCodes) at index aNetCode
116  // ensure there is room in m_netCodes for that, and add room if needed.
117 
118  if( (int)m_netCodes.size() <= aIndex )
119  m_netCodes.resize( aIndex+1 );
120 
121  m_netCodes[aIndex] = aValue;
122 }
std::vector< int > m_netCodes
net codes mapping for boards being loaded
Definition: pcb_parser.h:73
void PCB_PARSER::SetBoard ( BOARD aBoard)
inline

Definition at line 296 of file pcb_parser.h.

References init(), Parse(), and parseMODULE().

Referenced by CLIPBOARD_IO::Load(), and PCB_IO::Load().

297  {
298  init();
299  m_board = aBoard;
300  }
BOARD * m_board
Definition: pcb_parser.h:70
void init()
Function init clears and re-establishes m_layerMap with the default layer names.
Definition: pcb_parser.cpp:56
LINE_READER* PCB_PARSER::SetLineReader ( LINE_READER aReader)
inline

Function SetLineReader sets aLineReader into the parser, and returns the previous one, if any.

Parameters
aReaderis what to read from for tokens, no ownership is received.
Returns
LINE_READER* - previous LINE_READER or NULL if none.

Definition at line 289 of file pcb_parser.h.

Referenced by GITHUB_PLUGIN::FootprintLoad(), CLIPBOARD_IO::Load(), and PCB_IO::Load().

290  {
291  LINE_READER* ret = PopReader();
292  PushReader( aReader );
293  return ret;
294  }
Class LINE_READER is an abstract class from which implementation specific LINE_READERs may be derived...
Definition: richio.h:81

Member Data Documentation

BOARD* PCB_PARSER::m_board
private

Definition at line 70 of file pcb_parser.h.

LAYER_ID_MAP PCB_PARSER::m_layerIndices
private

map layer name to it's index

Definition at line 71 of file pcb_parser.h.

LSET_MAP PCB_PARSER::m_layerMasks
private

map layer names to their masks

Definition at line 72 of file pcb_parser.h.

std::vector<int> PCB_PARSER::m_netCodes
private

net codes mapping for boards being loaded

Definition at line 73 of file pcb_parser.h.

int PCB_PARSER::m_requiredVersion
private

set to the KiCad format version this board requires

Definition at line 75 of file pcb_parser.h.

bool PCB_PARSER::m_tooRecent
private

true if version parses as later than supported

Definition at line 74 of file pcb_parser.h.

Referenced by IsTooRecent().


The documentation for this class was generated from the following files: