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 (bool aAllowCirclesZeroWidth=false)
 Read a DRAWSEGMENT description. More...
 
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::set< wxString > m_undefinedLayers
 set of layers not defined in layers section 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 279 of file pcb_parser.h.

References init().

279  :
280  PCB_LEXER( aReader ),
281  m_board( 0 )
282  {
283  init();
284  }
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 80 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().

81  {
82  if( ( aNetCode >= 0 ) && ( aNetCode < (int) m_netCodes.size() ) )
83  return m_netCodes[aNetCode];
84 
85  return aNetCode;
86  }
std::vector< int > m_netCodes
net codes mapping for boards being loaded
Definition: pcb_parser.h:74
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)
string & err
Definition: json11.cpp:598
int m_requiredVersion
set to the KiCad format version this board requires
Definition: pcb_parser.h:76
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, numEval::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:676
int StrPrintf(std::string *aResult, const char *aFormat,...)
Function StrPrintf is like sprintf() but the output is appended to a std::string instead of to a char...
Definition: richio.cpp:74
bool m_tooRecent
true if version parses as later than supported
Definition: pcb_parser.h:75
#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:76
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 319 of file pcb_parser.h.

References GetRequiredVersion(), and m_tooRecent.

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

320  {
321  return m_tooRecent;
322  }
bool m_tooRecent
true if version parses as later than supported
Definition: pcb_parser.h:75
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 1045 of file pcb_parser.cpp.

References Rescue.

Referenced by getNetCode().

1046 {
1047  // avoid constructing another std::string, use lexer's directly
1048  typename M::const_iterator it = aMap.find( curText );
1049 
1050  if( it == aMap.end() )
1051  {
1052 #if 0 && defined(DEBUG)
1053  // dump the whole darn table, there's something wrong with it.
1054  for( it = aMap.begin(); it != aMap.end(); ++it )
1055  {
1056  wxLogDebug( &aMap == (void*)&m_layerIndices ? wxT( "lm[%s] = %d" ) :
1057  wxT( "lm[%s] = %08X" ), it->first.c_str(), it->second );
1058  }
1059 #endif
1060 
1061  m_undefinedLayers.insert( curText );
1062  return Rescue;
1063  }
1064 
1065  return it->second;
1066 }
LAYER_ID_MAP m_layerIndices
map layer name to it&#39;s index
Definition: pcb_parser.h:71
std::set< wxString > m_undefinedLayers
set of layers not defined in layers section
Definition: pcb_parser.h:73
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 }
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown...
Definition: common.h:180
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)
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:171
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:75
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:123
Struct FUTURE_FORMAT_ERROR variant of PARSE_ERROR indicating that a syntax or related error was likel...
Definition: ki_exception.h:172
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, B_Cu, Cmts_User, err, F_Cu, Format(), GetChars(), VIA::GetViaType(), VIA::LayerPair(), TRACK::Next(), PCB_VIA_T, Rescue, VIA::SetLayerPair(), THROW_IO_ERROR, THROW_PARSE_ERROR, and VIA_THROUGH.

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  if( m_undefinedLayers.size() > 0 )
584  {
585  bool deleteItems;
586  std::vector<BOARD_ITEM*> deleteList;
587  wxString msg = wxString::Format( _( "Items found on undefined layers. Do you wish to\n"
588  "rescue them to the Cmts.User layer?" ) );
589  wxString details = wxString::Format( _( "Undefined layers:" ) );
590 
591  for( const wxString& undefinedLayer : m_undefinedLayers )
592  details += wxT( "\n " ) + undefinedLayer;
593 
594  wxRichMessageDialog dlg( nullptr, msg, _( "Warning" ),
595  wxYES_NO | wxCANCEL | wxCENTRE | wxICON_WARNING | wxSTAY_ON_TOP );
596  dlg.ShowDetailedText( details );
597  dlg.SetYesNoCancelLabels( _( "Rescue" ), _( "Delete" ), _( "Cancel" ) );
598 
599  switch( dlg.ShowModal() )
600  {
601  case wxID_YES: deleteItems = false; break;
602  case wxID_NO: deleteItems = true; break;
603  case wxID_CANCEL:
604  default: THROW_IO_ERROR( wxT( "CANCEL" ) );
605  }
606 
607  auto visitItem = [&]( BOARD_ITEM* item )
608  {
609  if( item->GetLayer() == Rescue )
610  {
611  if( deleteItems )
612  deleteList.push_back( item );
613  else
614  item->SetLayer( Cmts_User );
615  }
616  };
617 
618  for( TRACK* segm = m_board->m_Track; segm; segm = segm->Next() )
619  {
620  if( segm->Type() == PCB_VIA_T )
621  {
622  VIA* via = (VIA*) segm;
623  PCB_LAYER_ID top_layer, bottom_layer;
624 
625  if( via->GetViaType() == VIA_THROUGH )
626  continue;
627 
628  via->LayerPair( &top_layer, &bottom_layer );
629 
630  if( top_layer == Rescue || bottom_layer == Rescue )
631  {
632  if( deleteItems )
633  deleteList.push_back( via );
634  else
635  {
636  if( top_layer == Rescue )
637  top_layer = F_Cu;
638 
639  if( bottom_layer == Rescue )
640  bottom_layer = B_Cu;
641 
642  via->SetLayerPair( top_layer, bottom_layer );
643  }
644  }
645  }
646  else
647  visitItem( segm );
648  }
649 
650  for( TRACK* segm = m_board->m_SegZoneDeprecated; segm; segm = segm->Next() )
651  visitItem( segm );
652 
653  for( BOARD_ITEM* zone : m_board->Zones() )
654  visitItem( zone );
655 
656  for( BOARD_ITEM* drawing : m_board->Drawings() )
657  visitItem( drawing );
658 
659  for( BOARD_ITEM* item : deleteList )
660  m_board->Delete( item );
661 
662  m_undefinedLayers.clear();
663  }
664 
665  return m_board;
666 }
void parseHeader()
Definition: pcb_parser.cpp:669
DRAWSEGMENT * parseDRAWSEGMENT(bool aAllowCirclesZeroWidth=false)
Read a DRAWSEGMENT description.
Class BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class...
TRACK * parseTRACK()
VIA * parseVIA()
void parseNETINFO_ITEM()
DIMENSION * parseDIMENSION()
void parseTITLE_BLOCK()
Definition: pcb_parser.cpp:807
void parseLayers()
Definition: pcb_parser.cpp:932
SEGZONE * Next() const
Definition: class_track.h:367
void parsePAGE_INFO()
Definition: pcb_parser.cpp:751
PCB_LAYER_ID
A quick note on layer IDs:
VIATYPE_T GetViaType() const
Definition: class_track.h:461
DLIST< SEGZONE > m_SegZoneDeprecated
Definition: class_board.h:251
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_INSERT) override
Adds an item to the container.
PCB_TARGET * parsePCB_TARGET()
TEXTE_PCB * parseTEXTE_PCB()
void SetLayerPair(PCB_LAYER_ID aTopLayer, PCB_LAYER_ID aBottomLayer)
Function SetLayerPair For a via m_Layer contains the top layer, the other layer is in m_BottomLayer...
#define THROW_IO_ERROR(msg)
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
void parseNETCLASS()
string & err
Definition: json11.cpp:598
void LayerPair(PCB_LAYER_ID *top_layer, PCB_LAYER_ID *bottom_layer) const
Function LayerPair Return the 2 layers used by the via (the via actually uses all layers between thes...
ZONE_CONTAINER * parseZONE_CONTAINER()
ZONE_CONTAINERS & Zones()
Definition: class_board.h:257
TRACK * Next() const
Definition: class_track.h:103
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
BOARD * m_board
Definition: pcb_parser.h:70
void parseGeneralSection()
Definition: pcb_parser.cpp:705
virtual void Delete(BOARD_ITEM *aItem)
Removes an item from the containter and deletes it.
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
DLIST< TRACK > m_Track
Definition: class_board.h:250
MODULE * parseMODULE(wxArrayString *aInitialComments=0)
Function parseMODULE.
void parseSetup()
DLIST_ITERATOR_WRAPPER< BOARD_ITEM > Drawings()
Definition: class_board.h:256
std::set< wxString > m_undefinedLayers
set of layers not defined in layers section
Definition: pcb_parser.h:73
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 1069 of file pcb_parser.cpp.

References UNDEFINED_LAYER.

Referenced by getNetCode().

1070 {
1071  wxCHECK_MSG( CurTok() == T_layer, UNDEFINED_LAYER,
1072  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as layer." ) );
1073 
1074  NextTok();
1075 
1076  PCB_LAYER_ID layerIndex = lookUpLayer<PCB_LAYER_ID>( m_layerIndices );
1077 
1078  // Handle closing ) in object parser.
1079 
1080  return layerIndex;
1081 }
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 1084 of file pcb_parser.cpp.

Referenced by getNetCode().

1085 {
1086  wxCHECK_MSG( CurTok() == T_layers, LSET(),
1087  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
1088  wxT( " as item layer mask." ) );
1089 
1090  LSET layerMask;
1091 
1092  for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
1093  {
1094  LSET mask = lookUpLayer<LSET>( m_layerMasks );
1095  layerMask |= mask;
1096  }
1097 
1098  return layerMask;
1099 }
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 228 of file pcb_parser.h.

References KiROUND(), and parseDouble().

Referenced by parseBoardUnits().

229  {
230  // There should be no major rounding issues here, since the values in
231  // the file are in mm and get converted to nano-meters.
232  // See test program tools/test-nm-biu-to-ascii-mm-round-tripping.cpp
233  // to confirm or experiment. Use a similar strategy in both places, here
234  // and in the test program. Make that program with:
235  // $ make test-nm-biu-to-ascii-mm-round-tripping
236  return KiROUND( parseDouble() * IU_PER_MM );
237  }
static int KiROUND(double v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:121
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 239 of file pcb_parser.h.

References KiROUND(), and parseDouble().

240  {
241  // Use here KiROUND, not KIROUND (see comments about them)
242  // when having a function as argument, because it will be called twice
243  // with KIROUND
244  return KiROUND( parseDouble( aExpected ) * IU_PER_MM );
245  }
static int KiROUND(double v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:121
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 247 of file pcb_parser.h.

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

248  {
249  return parseBoardUnits( GetTokenText( aToken ) );
250  }
int parseBoardUnits()
Definition: pcb_parser.h:228
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 2388 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(), and THROW_IO_ERROR.

Referenced by getNetCode().

2389 {
2390  wxCHECK_MSG( CurTok() == T_pad, NULL,
2391  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as D_PAD." ) );
2392 
2393  wxSize sz;
2394  wxPoint pt;
2395 
2396  std::unique_ptr< D_PAD > pad( new D_PAD( aParent ) );
2397 
2398  NeedSYMBOLorNUMBER();
2399  pad->SetName( FromUTF8() );
2400 
2401  T token = NextTok();
2402 
2403  switch( token )
2404  {
2405  case T_thru_hole:
2406  pad->SetAttribute( PAD_ATTRIB_STANDARD );
2407  break;
2408 
2409  case T_smd:
2410  pad->SetAttribute( PAD_ATTRIB_SMD );
2411 
2412  // Default D_PAD object is thru hole with drill.
2413  // SMD pads have no hole
2414  pad->SetDrillSize( wxSize( 0, 0 ) );
2415  break;
2416 
2417  case T_connect:
2418  pad->SetAttribute( PAD_ATTRIB_CONN );
2419 
2420  // Default D_PAD object is thru hole with drill.
2421  // CONN pads have no hole
2422  pad->SetDrillSize( wxSize( 0, 0 ) );
2423  break;
2424 
2425  case T_np_thru_hole:
2426  pad->SetAttribute( PAD_ATTRIB_HOLE_NOT_PLATED );
2427  break;
2428 
2429  default:
2430  Expecting( "thru_hole, smd, connect, or np_thru_hole" );
2431  }
2432 
2433  token = NextTok();
2434 
2435  switch( token )
2436  {
2437  case T_circle:
2438  pad->SetShape( PAD_SHAPE_CIRCLE );
2439  break;
2440 
2441  case T_rect:
2442  pad->SetShape( PAD_SHAPE_RECT );
2443  break;
2444 
2445  case T_oval:
2446  pad->SetShape( PAD_SHAPE_OVAL );
2447  break;
2448 
2449  case T_trapezoid:
2450  pad->SetShape( PAD_SHAPE_TRAPEZOID );
2451  break;
2452 
2453  case T_roundrect:
2454  pad->SetShape( PAD_SHAPE_ROUNDRECT );
2455  break;
2456 
2457  case T_custom:
2458  pad->SetShape( PAD_SHAPE_CUSTOM );
2459  break;
2460 
2461  default:
2462  Expecting( "circle, rectangle, roundrect, oval, trapezoid or custom" );
2463  }
2464 
2465  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2466  {
2467  if( token != T_LEFT )
2468  Expecting( T_LEFT );
2469 
2470  token = NextTok();
2471 
2472  switch( token )
2473  {
2474  case T_size:
2475  sz.SetWidth( parseBoardUnits( "width value" ) );
2476  sz.SetHeight( parseBoardUnits( "height value" ) );
2477  pad->SetSize( sz );
2478  NeedRIGHT();
2479  break;
2480 
2481  case T_at:
2482  pt.x = parseBoardUnits( "X coordinate" );
2483  pt.y = parseBoardUnits( "Y coordinate" );
2484  pad->SetPos0( pt );
2485  token = NextTok();
2486 
2487  if( token == T_NUMBER )
2488  {
2489  pad->SetOrientation( parseDouble() * 10.0 );
2490  NeedRIGHT();
2491  }
2492  else if( token != T_RIGHT )
2493  {
2494  Expecting( ") or angle value" );
2495  }
2496 
2497  break;
2498 
2499  case T_rect_delta:
2500  {
2501  wxSize delta;
2502  delta.SetWidth( parseBoardUnits( "rectangle delta width" ) );
2503  delta.SetHeight( parseBoardUnits( "rectangle delta height" ) );
2504  pad->SetDelta( delta );
2505  NeedRIGHT();
2506  }
2507  break;
2508 
2509  case T_drill:
2510  {
2511  bool haveWidth = false;
2512  wxSize drillSize = pad->GetDrillSize();
2513 
2514  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2515  {
2516  if( token == T_LEFT )
2517  token = NextTok();
2518 
2519  switch( token )
2520  {
2521  case T_oval:
2522  pad->SetDrillShape( PAD_DRILL_SHAPE_OBLONG );
2523  break;
2524 
2525  case T_NUMBER:
2526  {
2527  if( !haveWidth )
2528  {
2529  drillSize.SetWidth( parseBoardUnits() );
2530 
2531  // If height is not defined the width and height are the same.
2532  drillSize.SetHeight( drillSize.GetWidth() );
2533  haveWidth = true;
2534  }
2535  else
2536  {
2537  drillSize.SetHeight( parseBoardUnits() );
2538  }
2539 
2540  }
2541  break;
2542 
2543  case T_offset:
2544  pt.x = parseBoardUnits( "drill offset x" );
2545  pt.y = parseBoardUnits( "drill offset y" );
2546  pad->SetOffset( pt );
2547  NeedRIGHT();
2548  break;
2549 
2550  default:
2551  Expecting( "oval, size, or offset" );
2552  }
2553  }
2554 
2555  // This fixes a bug caused by setting the default D_PAD drill size to a value
2556  // other than 0 used to fix a bunch of debug assertions even though it is defined
2557  // as a through hole pad. Wouldn't a though hole pad with no drill be a surface
2558  // mount pad (or a conn pad which is a smd pad with no solder paste)?
2559  if( ( pad->GetAttribute() != PAD_ATTRIB_SMD ) && ( pad->GetAttribute() != PAD_ATTRIB_CONN ) )
2560  pad->SetDrillSize( drillSize );
2561  else
2562  pad->SetDrillSize( wxSize( 0, 0 ) );
2563 
2564  }
2565  break;
2566 
2567  case T_layers:
2568  {
2569  LSET layerMask = parseBoardItemLayersAsMask();
2570  pad->SetLayerSet( layerMask );
2571  }
2572  break;
2573 
2574  case T_net:
2575  if( ! pad->SetNetCode( getNetCode( parseInt( "net number" ) ), /* aNoAssert */ true ) )
2577  wxString::Format( _( "Invalid net ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),
2578  GetChars( CurSource() ), CurLineNumber(), CurOffset() )
2579  );
2580  NeedSYMBOLorNUMBER();
2581  if( m_board && FromUTF8() != m_board->FindNet( pad->GetNetCode() )->GetNetname() )
2583  wxString::Format( _( "Invalid net ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),
2584  GetChars( CurSource() ), CurLineNumber(), CurOffset() )
2585  );
2586  NeedRIGHT();
2587  break;
2588 
2589  case T_die_length:
2590  pad->SetPadToDieLength( parseBoardUnits( T_die_length ) );
2591  NeedRIGHT();
2592  break;
2593 
2594  case T_solder_mask_margin:
2595  pad->SetLocalSolderMaskMargin( parseBoardUnits( T_solder_mask_margin ) );
2596  NeedRIGHT();
2597  break;
2598 
2599  case T_solder_paste_margin:
2600  pad->SetLocalSolderPasteMargin( parseBoardUnits( T_solder_paste_margin ) );
2601  NeedRIGHT();
2602  break;
2603 
2604  case T_solder_paste_margin_ratio:
2605  pad->SetLocalSolderPasteMarginRatio(
2606  parseDouble( "pad local solder paste margin ratio value" ) );
2607  NeedRIGHT();
2608  break;
2609 
2610  case T_clearance:
2611  pad->SetLocalClearance( parseBoardUnits( "local clearance value" ) );
2612  NeedRIGHT();
2613  break;
2614 
2615  case T_zone_connect:
2616  pad->SetZoneConnection( (ZoneConnection) parseInt( "zone connection value" ) );
2617  NeedRIGHT();
2618  break;
2619 
2620  case T_thermal_width:
2621  pad->SetThermalWidth( parseBoardUnits( T_thermal_width ) );
2622  NeedRIGHT();
2623  break;
2624 
2625  case T_thermal_gap:
2626  pad->SetThermalGap( parseBoardUnits( T_thermal_gap ) );
2627  NeedRIGHT();
2628  break;
2629 
2630  case T_roundrect_rratio:
2631  pad->SetRoundRectRadiusRatio( parseDouble( "roundrect radius ratio" ) );
2632  NeedRIGHT();
2633  break;
2634 
2635  case T_options:
2636  parseD_PAD_option( pad.get() );
2637  break;
2638 
2639  case T_primitives:
2640  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2641  {
2642  if( token == T_LEFT )
2643  token = NextTok();
2644 
2645  // Currently, I am using parseDRAWSEGMENT() to read basic shapes parameters,
2646  // because they are the same as a DRAWSEGMENT.
2647  // However it could be better to write a specific parser, to avoid possible issues
2648  // if the DRAWSEGMENT parser is modified.
2649  DRAWSEGMENT* dummysegm = NULL;
2650 
2651  switch( token )
2652  {
2653  case T_gr_arc:
2654  dummysegm = parseDRAWSEGMENT();
2655  pad->AddPrimitive( dummysegm->GetCenter(), dummysegm->GetArcStart(),
2656  dummysegm->GetAngle(), dummysegm->GetWidth() );
2657  break;
2658 
2659  case T_gr_line:
2660  dummysegm = parseDRAWSEGMENT();
2661  pad->AddPrimitive( dummysegm->GetStart(), dummysegm->GetEnd(),
2662  dummysegm->GetWidth() );
2663  break;
2664 
2665  case T_gr_circle:
2666  dummysegm = parseDRAWSEGMENT( true ); // Circles with 0 thickness are allowed
2667  // ( filled circles )
2668  pad->AddPrimitive( dummysegm->GetCenter(), dummysegm->GetRadius(),
2669  dummysegm->GetWidth() );
2670  break;
2671 
2672  case T_gr_poly:
2673  dummysegm = parseDRAWSEGMENT();
2674  pad->AddPrimitive( dummysegm->BuildPolyPointsList(), dummysegm->GetWidth() );
2675  break;
2676 
2677  default:
2678  Expecting( "gr_line, gr_arc, gr_circle or gr_poly" );
2679  break;
2680  }
2681 
2682  delete dummysegm;
2683  }
2684  break;
2685 
2686  default:
2687  Expecting( "at, drill, layers, net, die_length, solder_mask_margin, roundrect_rratio,\n"
2688  "solder_paste_margin, solder_paste_margin_ratio, clearance,\n"
2689  "zone_connect, fp_poly, primitives, thermal_width, or thermal_gap" );
2690  }
2691  }
2692 
2693  // Be sure the custom shape polygon is built:
2694  if( pad->GetShape() == PAD_SHAPE_CUSTOM )
2695  pad->MergePrimitivesAsPolygon();
2696 
2697  return pad.release();
2698 }
DRAWSEGMENT * parseDRAWSEGMENT(bool aAllowCirclesZeroWidth=false)
Read a DRAWSEGMENT description.
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:50
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:228
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.
#define THROW_IO_ERROR(msg)
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:80
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:252
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.
bool PCB_PARSER::parseD_PAD_option ( D_PAD aPad)
private

Definition at line 2701 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().

2702 {
2703  // Parse only the (option ...) inside a pad description
2704  for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
2705  {
2706  if( token != T_LEFT )
2707  Expecting( T_LEFT );
2708 
2709  token = NextTok();
2710 
2711  switch( token )
2712  {
2713  case T_anchor:
2714  token = NextTok();
2715  // Custom shaped pads have a "anchor pad", which is the reference
2716  // for connection calculations.
2717  // Because this is an anchor, only the 2 very basic shapes are managed:
2718  // circle and rect. The default is circle
2719  switch( token )
2720  {
2721  case T_circle: // default
2722  break;
2723 
2724  case T_rect:
2726  break;
2727 
2728  default:
2729  // Currently, because pad options is a moving target
2730  // just skip unknown keywords
2731  break;
2732  }
2733  NeedRIGHT();
2734  break;
2735 
2736  case T_clearance:
2737  token = NextTok();
2738  // Custom shaped pads have a clearance area that is the pad shape
2739  // (like usual pads) or the convew hull of the pad shape.
2740  switch( token )
2741  {
2742  case T_outline:
2744  break;
2745 
2746  case T_convexhull:
2748  break;
2749 
2750  default:
2751  // Currently, because pad options is a moving target
2752  // just skip unknown keywords
2753  break;
2754  }
2755  NeedRIGHT();
2756  break;
2757 
2758  default:
2759  // Currently, because pad options is a moving target
2760  // just skip unknown keywords
2761  while( (token = NextTok() ) != T_RIGHT )
2762  {}
2763  break;
2764  }
2765  }
2766 
2767  return true;
2768 }
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 1692 of file pcb_parser.cpp.

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

Referenced by getNetCode().

1693 {
1694  wxCHECK_MSG( CurTok() == T_dimension, NULL,
1695  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as DIMENSION." ) );
1696 
1697  T token;
1698 
1699  std::unique_ptr<DIMENSION> dimension( new DIMENSION( NULL ) );
1700 
1701  dimension->SetValue( parseBoardUnits( "dimension value" ) );
1702  NeedLEFT();
1703  token = NextTok();
1704 
1705  if( token != T_width )
1706  Expecting( T_width );
1707 
1708  dimension->SetWidth( parseBoardUnits( "dimension width value" ) );
1709  NeedRIGHT();
1710 
1711  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1712  {
1713  if( token != T_LEFT )
1714  Expecting( T_LEFT );
1715 
1716  token = NextTok();
1717 
1718  switch( token )
1719  {
1720  case T_layer:
1721  dimension->SetLayer( parseBoardItemLayer() );
1722  NeedRIGHT();
1723  break;
1724 
1725  case T_tstamp:
1726  dimension->SetTimeStamp( parseHex() );
1727  NeedRIGHT();
1728  break;
1729 
1730  case T_gr_text:
1731  {
1732  TEXTE_PCB* text = parseTEXTE_PCB();
1733 
1734  // This copy (using the copy constructor) rebuild the text timestamp,
1735  // that is not what we want.
1736  dimension->Text() = *text;
1737  // reinitialises the text time stamp to the right value (the dimension time stamp)
1738  dimension->Text().SetTimeStamp( dimension->GetTimeStamp() );
1739  dimension->SetPosition( text->GetTextPos() );
1740 
1741  EDA_UNITS_T units = INCHES;
1742  bool useMils = false;
1743  FetchUnitsFromString( text->GetText(), units, useMils );
1744  dimension->SetUnits( units, useMils );
1745 
1746  delete text;
1747  break;
1748  }
1749 
1750  case T_feature1:
1751  NeedLEFT();
1752  token = NextTok();
1753 
1754  if( token != T_pts )
1755  Expecting( T_pts );
1756 
1757  parseXY( &dimension->m_featureLineDO.x, &dimension->m_featureLineDO.y );
1758  parseXY( &dimension->m_featureLineDF.x, &dimension->m_featureLineDF.y );
1759  dimension->UpdateHeight();
1760  NeedRIGHT();
1761  NeedRIGHT();
1762  break;
1763 
1764  case T_feature2:
1765  NeedLEFT();
1766  token = NextTok();
1767 
1768  if( token != T_pts )
1769  Expecting( T_pts );
1770 
1771  parseXY( &dimension->m_featureLineGO.x, &dimension->m_featureLineGO.y );
1772  parseXY( &dimension->m_featureLineGF.x, &dimension->m_featureLineGF.y );
1773  dimension->UpdateHeight();
1774  NeedRIGHT();
1775  NeedRIGHT();
1776  break;
1777 
1778 
1779  case T_crossbar:
1780  NeedLEFT();
1781  token = NextTok();
1782 
1783  if( token != T_pts )
1784  Expecting( T_pts );
1785 
1786  parseXY( &dimension->m_crossBarO.x, &dimension->m_crossBarO.y );
1787  parseXY( &dimension->m_crossBarF.x, &dimension->m_crossBarF.y );
1788  dimension->UpdateHeight();
1789  NeedRIGHT();
1790  NeedRIGHT();
1791  break;
1792 
1793  case T_arrow1a:
1794  NeedLEFT();
1795  token = NextTok();
1796 
1797  if( token != T_pts )
1798  Expecting( T_pts );
1799 
1800  parseXY( &dimension->m_crossBarF.x, &dimension->m_crossBarF.y );
1801  parseXY( &dimension->m_arrowD1F.x, &dimension->m_arrowD1F.y );
1802  NeedRIGHT();
1803  NeedRIGHT();
1804  break;
1805 
1806  case T_arrow1b:
1807  NeedLEFT();
1808  token = NextTok();
1809 
1810  if( token != T_pts )
1811  Expecting( T_pts );
1812 
1813  parseXY( &dimension->m_crossBarF.x, &dimension->m_crossBarF.y );
1814  parseXY( &dimension->m_arrowD2F.x, &dimension->m_arrowD2F.y );
1815  NeedRIGHT();
1816  NeedRIGHT();
1817  break;
1818 
1819  case T_arrow2a:
1820  NeedLEFT();
1821  token = NextTok();
1822 
1823  if( token != T_pts )
1824  Expecting( T_pts );
1825 
1826  parseXY( &dimension->m_crossBarO.x, &dimension->m_crossBarO.y );
1827  parseXY( &dimension->m_arrowG1F.x, &dimension->m_arrowG1F.y );
1828  NeedRIGHT();
1829  NeedRIGHT();
1830  break;
1831 
1832  case T_arrow2b:
1833  NeedLEFT();
1834  token = NextTok();
1835 
1836  if( token != T_pts )
1837  Expecting( T_pts );
1838 
1839  parseXY( &dimension->m_crossBarO.x, &dimension->m_crossBarO.y );
1840  parseXY( &dimension->m_arrowG2F.x, &dimension->m_arrowG2F.y );
1841  NeedRIGHT();
1842  NeedRIGHT();
1843  break;
1844 
1845  default:
1846  Expecting( "layer, tstamp, gr_text, feature1, feature2 crossbar, arrow1a, "
1847  "arrow1b, arrow2a, or arrow2b" );
1848  }
1849  }
1850 
1851  return dimension.release();
1852 }
const wxPoint & GetTextPos() const
Definition: eda_text.h:237
wxPoint parseXY()
Function parseXY parses a coordinate pair (xy X Y) in board units (mm).
Definition: pcb_parser.cpp:206
void FetchUnitsFromString(const wxString &aTextValue, EDA_UNITS_T &aUnits, bool &aUseMils)
Function FetchUnitsFromString writes any unit info found in the string to aUnits and aUseMils...
Definition: base_units.cpp:370
int parseBoardUnits()
Definition: pcb_parser.h:228
const wxString & GetText() const
Function GetText returns the string associated with the text object.
Definition: eda_text.h:143
Definition: common.h:161
PCB_LAYER_ID parseBoardItemLayer()
Function parseBoardItemLayer parses the layer definition of a BOARD_ITEM object.
TEXTE_PCB * parseTEXTE_PCB()
long parseHex()
Definition: pcb_parser.h:263
EDA_UNITS_T
Definition: common.h:160
Class DIMENSION.
void SetTimeStamp(timestamp_t aNewTimeStamp)
Definition: base_struct.h:206
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 }
#define THROW_IO_ERROR(msg)
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 PCB_PARSER::parseDouble ( const char *  aExpected)
inlineprivate

Definition at line 217 of file pcb_parser.h.

References parseDouble().

218  {
219  NeedNUMBER( aExpected );
220  return parseDouble();
221  }
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 223 of file pcb_parser.h.

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

224  {
225  return parseDouble( GetTokenText( aToken ) );
226  }
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 ( bool  aAllowCirclesZeroWidth = false)
private

Read a DRAWSEGMENT description.

Parameters
aAllowCirclesZeroWidth= true to allow items with 0 width Only used in custom pad shapes for filled circles.

Definition at line 1451 of file pcb_parser.cpp.

References DEFAULT_LINE_WIDTH, parseDouble(), parseHex(), S_ARC, S_CIRCLE, S_CURVE, and S_POLYGON.

Referenced by getNetCode().

1452 {
1453  wxCHECK_MSG( CurTok() == T_gr_arc || CurTok() == T_gr_circle || CurTok() == T_gr_curve ||
1454  CurTok() == T_gr_line || CurTok() == T_gr_poly, NULL,
1455  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as DRAWSEGMENT." ) );
1456 
1457  T token;
1458  wxPoint pt;
1459  std::unique_ptr< DRAWSEGMENT > segment( new DRAWSEGMENT( NULL ) );
1460 
1461  switch( CurTok() )
1462  {
1463  case T_gr_arc:
1464  segment->SetShape( S_ARC );
1465  NeedLEFT();
1466  token = NextTok();
1467 
1468  // the start keyword actually gives the arc center
1469  // Allows also T_center for future change
1470  if( token != T_start && token != T_center )
1471  Expecting( T_start );
1472 
1473  pt.x = parseBoardUnits( "X coordinate" );
1474  pt.y = parseBoardUnits( "Y coordinate" );
1475  segment->SetCenter( pt );
1476  NeedRIGHT();
1477  NeedLEFT();
1478  token = NextTok();
1479 
1480  if( token != T_end ) // the end keyword actually gives the starting point of the arc
1481  Expecting( T_end );
1482 
1483  pt.x = parseBoardUnits( "X coordinate" );
1484  pt.y = parseBoardUnits( "Y coordinate" );
1485  segment->SetArcStart( pt );
1486  NeedRIGHT();
1487  break;
1488 
1489  case T_gr_circle:
1490  segment->SetShape( S_CIRCLE );
1491  NeedLEFT();
1492  token = NextTok();
1493 
1494  if( token != T_center )
1495  Expecting( T_center );
1496 
1497  pt.x = parseBoardUnits( "X coordinate" );
1498  pt.y = parseBoardUnits( "Y coordinate" );
1499  segment->SetCenter( pt );
1500  NeedRIGHT();
1501  NeedLEFT();
1502 
1503  token = NextTok();
1504 
1505  if( token != T_end )
1506  Expecting( T_end );
1507 
1508  pt.x = parseBoardUnits( "X coordinate" );
1509  pt.y = parseBoardUnits( "Y coordinate" );
1510  segment->SetEnd( pt );
1511  NeedRIGHT();
1512  break;
1513 
1514  case T_gr_curve:
1515  segment->SetShape( S_CURVE );
1516  NeedLEFT();
1517  token = NextTok();
1518 
1519  if( token != T_pts )
1520  Expecting( T_pts );
1521 
1522  segment->SetStart( parseXY() );
1523  segment->SetBezControl1( parseXY() );
1524  segment->SetBezControl2( parseXY() );
1525  segment->SetEnd( parseXY() );
1526  NeedRIGHT();
1527  break;
1528 
1529  case T_gr_line:
1530  // Default DRAWSEGMENT type is S_SEGMENT.
1531  NeedLEFT();
1532  token = NextTok();
1533 
1534  if( token != T_start )
1535  Expecting( T_start );
1536 
1537  pt.x = parseBoardUnits( "X coordinate" );
1538  pt.y = parseBoardUnits( "Y coordinate" );
1539  segment->SetStart( pt );
1540  NeedRIGHT();
1541  NeedLEFT();
1542  token = NextTok();
1543 
1544  if( token != T_end )
1545  Expecting( T_end );
1546 
1547  pt.x = parseBoardUnits( "X coordinate" );
1548  pt.y = parseBoardUnits( "Y coordinate" );
1549  segment->SetEnd( pt );
1550  NeedRIGHT();
1551  break;
1552 
1553  case T_gr_poly:
1554  {
1555  segment->SetShape( S_POLYGON );
1556  segment->SetWidth( 0 ); // this is the default value. will be (perhaps) modified later
1557  NeedLEFT();
1558  token = NextTok();
1559 
1560  if( token != T_pts )
1561  Expecting( T_pts );
1562 
1563  std::vector< wxPoint > pts;
1564 
1565  while( (token = NextTok()) != T_RIGHT )
1566  pts.push_back( parseXY() );
1567 
1568  segment->SetPolyPoints( pts );
1569  }
1570  break;
1571 
1572  default:
1573  Expecting( "gr_arc, gr_circle, gr_curve, gr_line, or gr_poly" );
1574  }
1575 
1576  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1577  {
1578  if( token != T_LEFT )
1579  Expecting( T_LEFT );
1580 
1581  token = NextTok();
1582 
1583  switch( token )
1584  {
1585  case T_angle:
1586  segment->SetAngle( parseDouble( "segment angle" ) * 10.0 );
1587  break;
1588 
1589  case T_layer:
1590  segment->SetLayer( parseBoardItemLayer() );
1591  break;
1592 
1593  case T_width:
1594  segment->SetWidth( parseBoardUnits( T_width ) );
1595  break;
1596 
1597  case T_tstamp:
1598  segment->SetTimeStamp( parseHex() );
1599  break;
1600 
1601  case T_status:
1602  segment->SetStatus( static_cast<STATUS_FLAGS>( parseHex() ) );
1603  break;
1604 
1605  default:
1606  Expecting( "layer, width, tstamp, or status" );
1607  }
1608 
1609  NeedRIGHT();
1610  }
1611 
1612  // Only filled polygons may have a zero-line width
1613  // This is not permitted in KiCad but some external tools generate invalid
1614  // files.
1615  // However in custom pad shapes, zero-line width is allowed for filled circles
1616  if( segment->GetShape() != S_POLYGON && segment->GetWidth() == 0 &&
1617  !( segment->GetShape() == S_CIRCLE && aAllowCirclesZeroWidth ) )
1618  segment->SetWidth( Millimeter2iu( DEFAULT_LINE_WIDTH ) );
1619 
1620  return segment.release();
1621 }
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
#define DEFAULT_LINE_WIDTH
int parseBoardUnits()
Definition: pcb_parser.h:228
Arcs (with rounded ends)
PCB_LAYER_ID parseBoardItemLayer()
Function parseBoardItemLayer parses the layer definition of a BOARD_ITEM object.
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:263
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:191
void SetItalic(bool isItalic)
Definition: eda_text.h:182
void SetVisible(bool aVisible)
Definition: eda_text.h:188
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:227
int parseBoardUnits()
Definition: pcb_parser.h:228
void SetVertJustify(EDA_TEXT_VJUSTIFY_T aType)
Definition: eda_text.h:207
void SetHorizJustify(EDA_TEXT_HJUSTIFY_T aType)
Definition: eda_text.h:206
void SetBold(bool aBold)
Definition: eda_text.h:185
void SetThickness(int aNewThickness)
Function SetThickness sets pen width.
Definition: eda_text.h:161
EDGE_MODULE * PCB_PARSER::parseEDGE_MODULE ( )
private

Definition at line 2213 of file pcb_parser.cpp.

References DEFAULT_LINE_WIDTH, parseDouble(), parseHex(), S_ARC, S_CIRCLE, S_CURVE, and S_POLYGON.

Referenced by getNetCode().

2214 {
2215  wxCHECK_MSG( CurTok() == T_fp_arc || CurTok() == T_fp_circle || CurTok() == T_fp_curve ||
2216  CurTok() == T_fp_line || CurTok() == T_fp_poly, NULL,
2217  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as EDGE_MODULE." ) );
2218 
2219  wxPoint pt;
2220  T token;
2221 
2222  std::unique_ptr< EDGE_MODULE > segment( new EDGE_MODULE( NULL ) );
2223 
2224  switch( CurTok() )
2225  {
2226  case T_fp_arc:
2227  segment->SetShape( S_ARC );
2228  NeedLEFT();
2229  token = NextTok();
2230 
2231  // the start keyword actually gives the arc center
2232  // Allows also T_center for future change
2233  if( token != T_start && token != T_center )
2234  Expecting( T_start );
2235 
2236  pt.x = parseBoardUnits( "X coordinate" );
2237  pt.y = parseBoardUnits( "Y coordinate" );
2238  segment->SetStart0( pt );
2239  NeedRIGHT();
2240  NeedLEFT();
2241  token = NextTok();
2242 
2243  if( token != T_end ) // end keyword actually gives the starting point of the arc
2244  Expecting( T_end );
2245 
2246  pt.x = parseBoardUnits( "X coordinate" );
2247  pt.y = parseBoardUnits( "Y coordinate" );
2248  segment->SetEnd0( pt );
2249  NeedRIGHT();
2250  NeedLEFT();
2251  token = NextTok();
2252 
2253  if( token != T_angle )
2254  Expecting( T_angle );
2255 
2256  segment->SetAngle( parseDouble( "segment angle" ) * 10.0 );
2257  NeedRIGHT();
2258  break;
2259 
2260  case T_fp_circle:
2261  segment->SetShape( S_CIRCLE );
2262  NeedLEFT();
2263  token = NextTok();
2264 
2265  if( token != T_center )
2266  Expecting( T_center );
2267 
2268  pt.x = parseBoardUnits( "X coordinate" );
2269  pt.y = parseBoardUnits( "Y coordinate" );
2270  segment->SetStart0( pt );
2271  NeedRIGHT();
2272  NeedLEFT();
2273  token = NextTok();
2274 
2275  if( token != T_end )
2276  Expecting( T_end );
2277 
2278  pt.x = parseBoardUnits( "X coordinate" );
2279  pt.y = parseBoardUnits( "Y coordinate" );
2280  segment->SetEnd0( pt );
2281  NeedRIGHT();
2282  break;
2283 
2284  case T_fp_curve:
2285  segment->SetShape( S_CURVE );
2286  NeedLEFT();
2287  token = NextTok();
2288 
2289  if( token != T_pts )
2290  Expecting( T_pts );
2291 
2292  segment->SetStart0( parseXY() );
2293  segment->SetBezier0_C1( parseXY() );
2294  segment->SetBezier0_C2( parseXY() );
2295  segment->SetEnd0( parseXY() );
2296  NeedRIGHT();
2297  break;
2298 
2299  case T_fp_line:
2300  // Default DRAWSEGMENT type is S_SEGMENT.
2301  NeedLEFT();
2302  token = NextTok();
2303 
2304  if( token != T_start )
2305  Expecting( T_start );
2306 
2307  pt.x = parseBoardUnits( "X coordinate" );
2308  pt.y = parseBoardUnits( "Y coordinate" );
2309  segment->SetStart0( pt );
2310 
2311  NeedRIGHT();
2312  NeedLEFT();
2313  token = NextTok();
2314 
2315  if( token != T_end )
2316  Expecting( T_end );
2317 
2318  pt.x = parseBoardUnits( "X coordinate" );
2319  pt.y = parseBoardUnits( "Y coordinate" );
2320  segment->SetEnd0( pt );
2321  NeedRIGHT();
2322  break;
2323 
2324  case T_fp_poly:
2325  {
2326  segment->SetShape( S_POLYGON );
2327  NeedLEFT();
2328  token = NextTok();
2329 
2330  if( token != T_pts )
2331  Expecting( T_pts );
2332 
2333  std::vector< wxPoint > pts;
2334 
2335  while( (token = NextTok()) != T_RIGHT )
2336  pts.push_back( parseXY() );
2337 
2338  segment->SetPolyPoints( pts );
2339  }
2340  break;
2341 
2342  default:
2343  Expecting( "fp_arc, fp_circle, fp_curve, fp_line, or fp_poly" );
2344  }
2345 
2346  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2347  {
2348  if( token != T_LEFT )
2349  Expecting( T_LEFT );
2350 
2351  token = NextTok();
2352 
2353  switch( token )
2354  {
2355  case T_layer:
2356  segment->SetLayer( parseBoardItemLayer() );
2357  break;
2358 
2359  case T_width:
2360  segment->SetWidth( parseBoardUnits( T_width ) );
2361  break;
2362 
2363  case T_tstamp:
2364  segment->SetTimeStamp( parseHex() );
2365  break;
2366 
2367  case T_status:
2368  segment->SetStatus( static_cast<STATUS_FLAGS>( parseHex() ) );
2369  break;
2370 
2371  default:
2372  Expecting( "layer or width" );
2373  }
2374 
2375  NeedRIGHT();
2376  }
2377 
2378  // Only filled polygons may have a zero-line width
2379  // This is not permitted in KiCad but some external tools generate invalid
2380  // files.
2381  if( segment->GetShape() != S_POLYGON && segment->GetWidth() == 0 )
2382  segment->SetWidth( Millimeter2iu( DEFAULT_LINE_WIDTH ) );
2383 
2384  return segment.release();
2385 }
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
#define DEFAULT_LINE_WIDTH
int parseBoardUnits()
Definition: pcb_parser.h:228
Arcs (with rounded ends)
PCB_LAYER_ID parseBoardItemLayer()
Function parseBoardItemLayer parses the layer definition of a BOARD_ITEM object.
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:263
void PCB_PARSER::parseGeneralSection ( )
private

Definition at line 705 of file pcb_parser.cpp.

References parseInt().

Referenced by getNetCode().

706 {
707  wxCHECK_RET( CurTok() == T_general,
708  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
709  wxT( " as a general section." ) );
710 
711  T token;
712 
713  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
714  {
715  if( token != T_LEFT )
716  Expecting( T_LEFT );
717 
718  token = NextTok();
719 
720  switch( token )
721  {
722  case T_thickness:
724  NeedRIGHT();
725  break;
726 
727  case T_nets:
728  m_netCodes.resize( parseInt( "nets number" ) );
729  NeedRIGHT();
730  break;
731 
732  case T_no_connects:
733  // ignore
734  parseInt( "no connect count" );
735  NeedRIGHT();
736  break;
737 
738  default: // Skip everything but the board thickness.
739  //wxLogDebug( wxT( "Skipping general section token %s " ), GetChars( GetTokenString( token ) ) );
740 
741  while( ( token = NextTok() ) != T_RIGHT )
742  {
743  if( !IsSymbol( token ) && token != T_NUMBER )
744  Expecting( "symbol or number" );
745  }
746  }
747  }
748 }
void SetBoardThickness(int aThickness)
int parseBoardUnits()
Definition: pcb_parser.h:228
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:539
std::vector< int > m_netCodes
net codes mapping for boards being loaded
Definition: pcb_parser.h:74
BOARD * m_board
Definition: pcb_parser.h:70
int parseInt()
Definition: pcb_parser.h:252
void PCB_PARSER::parseHeader ( )
private

Definition at line 669 of file pcb_parser.cpp.

References parseInt(), and SEXPR_BOARD_FILE_VERSION.

Referenced by getNetCode().

670 {
671  wxCHECK_RET( CurTok() == T_kicad_pcb,
672  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a header." ) );
673 
674  NeedLEFT();
675 
676  T tok = NextTok();
677  if( tok == T_version )
678  {
679  m_requiredVersion = parseInt( FromUTF8().mb_str( wxConvUTF8 ) );
681  NeedRIGHT();
682 
683  // Skip the host name and host build version information.
684  NeedLEFT();
685  NeedSYMBOL();
686  NeedSYMBOL();
687  NeedSYMBOL();
688  NeedRIGHT();
689  }
690  else
691  {
694 
695  // Skip the host name and host build version information.
696  NeedSYMBOL();
697  NeedSYMBOL();
698  NeedRIGHT();
699  }
700 
702 }
void SetFileFormatVersionAtLoad(int aVersion)
Definition: class_board.h:281
#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:75
int m_requiredVersion
set to the KiCad format version this board requires
Definition: pcb_parser.h:76
BOARD * m_board
Definition: pcb_parser.h:70
int parseInt()
Definition: pcb_parser.h:252
long PCB_PARSER::parseHex ( )
inlineprivate

Definition at line 263 of file pcb_parser.h.

References parseBool(), and parseVersion().

264  {
265  NextTok();
266  return strtol( CurText(), NULL, 16 );
267  }
int PCB_PARSER::parseInt ( )
inlineprivate

Definition at line 252 of file pcb_parser.h.

Referenced by parseInt().

253  {
254  return (int)strtol( CurText(), NULL, 10 );
255  }
int PCB_PARSER::parseInt ( const char *  aExpected)
inlineprivate

Definition at line 257 of file pcb_parser.h.

References parseInt().

258  {
259  NeedNUMBER( aExpected );
260  return parseInt();
261  }
int parseInt()
Definition: pcb_parser.h:252
void PCB_PARSER::parseLayer ( LAYER aLayer)
private

Definition at line 890 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().

891 {
892  T token;
893 
894  std::string name;
895  std::string type;
896  bool isVisible = true;
897 
898  aLayer->clear();
899 
900  if( CurTok() != T_LEFT )
901  Expecting( T_LEFT );
902 
903  // this layer_num is not used, we DO depend on LAYER_T however.
904  LAYER_NUM layer_num = parseInt( "layer index" );
905 
906  NeedSYMBOLorNUMBER();
907  name = CurText();
908 
909  NeedSYMBOL();
910  type = CurText();
911 
912  token = NextTok();
913 
914  if( token == T_hide )
915  {
916  isVisible = false;
917  NeedRIGHT();
918  }
919  else if( token != T_RIGHT )
920  {
921  Expecting( "hide or )" );
922  }
923 
924  aLayer->m_name = FROM_UTF8( name.c_str() );
925  aLayer->m_type = LAYER::ParseType( type.c_str() );
926  aLayer->m_number = layer_num;
927  aLayer->m_visible = isVisible;
928 }
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:113
LAYER_T m_type
The type of the layer.
Definition: class_board.h:115
bool m_visible
Definition: class_board.h:117
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:94
const char * name
Definition: DXF_plotter.cpp:61
int m_number
Definition: class_board.h:119
int parseInt()
Definition: pcb_parser.h:252
void PCB_PARSER::parseLayers ( )
private

Definition at line 932 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().

933 {
934  wxCHECK_RET( CurTok() == T_layers,
935  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as layers." ) );
936 
937  T token;
938  LSET visibleLayers;
939  LSET enabledLayers;
940  int copperLayerCount = 0;
941  LAYER layer;
942 
943  std::vector<LAYER> cu;
944 
945  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
946  {
947  parseLayer( &layer );
948 
949  if( layer.m_type == LT_UNDEFINED ) // it's a non-copper layer
950  break;
951 
952  cu.push_back( layer ); // it's copper
953  }
954 
955  // All Cu layers are parsed, but not the non-cu layers here.
956 
957  // The original *.kicad_pcb file format and the inverted
958  // Cu stack format both have all the Cu layers first, so use this
959  // trick to handle either. The layer number in the (layers ..)
960  // s-expression element are ignored.
961  if( cu.size() )
962  {
963  // Rework the layer numbers, which changed when the Cu stack
964  // was flipped. So we instead use position in the list.
965  cu[cu.size()-1].m_number = B_Cu;
966 
967  for( unsigned i=0; i < cu.size()-1; ++i )
968  {
969  cu[i].m_number = i;
970  }
971 
972  for( std::vector<LAYER>::const_iterator it = cu.begin(); it<cu.end(); ++it )
973  {
974  enabledLayers.set( it->m_number );
975 
976  if( it->m_visible )
977  visibleLayers.set( it->m_number );
978 
979  m_board->SetLayerDescr( PCB_LAYER_ID( it->m_number ), *it );
980 
981  UTF8 name = it->m_name;
982 
983  m_layerIndices[ name ] = PCB_LAYER_ID( it->m_number );
984  m_layerMasks[ name ] = LSET( PCB_LAYER_ID( it->m_number ) );
985  }
986 
987  copperLayerCount = cu.size();
988  }
989 
990  // process non-copper layers
991  while( token != T_RIGHT )
992  {
993  LAYER_ID_MAP::const_iterator it = m_layerIndices.find( UTF8( layer.m_name ) );
994 
995  if( it == m_layerIndices.end() )
996  {
997  wxString error = wxString::Format(
998  _( "Layer \"%s\" in file \"%s\" at line %d, is not in fixed layer hash" ),
999  GetChars( layer.m_name ),
1000  GetChars( CurSource() ),
1001  CurLineNumber(),
1002  CurOffset()
1003  );
1004 
1005  THROW_IO_ERROR( error );
1006  }
1007 
1008  layer.m_number = it->second;
1009 
1010  enabledLayers.set( layer.m_number );
1011 
1012  if( layer.m_visible )
1013  visibleLayers.set( layer.m_number );
1014 
1015  // DBG( printf( "aux m_visible:%s\n", layer.m_visible ? "true" : "false" );)
1016 
1017  m_board->SetLayerDescr( it->second, layer );
1018 
1019  token = NextTok();
1020 
1021  if( token != T_LEFT )
1022  break;
1023 
1024  parseLayer( &layer );
1025  }
1026 
1027  // We need at least 2 copper layers and there must be an even number of them.
1028  if( copperLayerCount < 2 || (copperLayerCount % 2) != 0 )
1029  {
1030  wxString err = wxString::Format(
1031  _( "%d is not a valid layer count" ), copperLayerCount );
1032 
1033  THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
1034  }
1035 
1036  m_board->SetCopperLayerCount( copperLayerCount );
1037  m_board->SetEnabledLayers( enabledLayers );
1038 
1039  // call SetEnabledLayers before SetVisibleLayers()
1040  m_board->SetVisibleLayers( visibleLayers );
1041 }
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:113
LAYER_T m_type
The type of the layer.
Definition: class_board.h:115
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.
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:117
#define THROW_IO_ERROR(msg)
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
string & err
Definition: json11.cpp:598
void parseLayer(LAYER *aLayer)
Definition: pcb_parser.cpp:890
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:87
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:119
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 1855 of file pcb_parser.cpp.

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

1856 {
1857  try
1858  {
1859  return parseMODULE_unchecked( aInitialComments );
1860  }
1861  catch( const PARSE_ERROR& parse_error )
1862  {
1863  if( m_tooRecent )
1864  throw FUTURE_FORMAT_ERROR( parse_error, GetRequiredVersion() );
1865  else
1866  throw;
1867  }
1868 }
bool m_tooRecent
true if version parses as later than supported
Definition: pcb_parser.h:75
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:123
Struct FUTURE_FORMAT_ERROR variant of PARSE_ERROR indicating that a syntax or related error was likel...
Definition: ki_exception.h:172
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 1871 of file pcb_parser.cpp.

References ADD_APPEND, B_Cu, F_Cu, GetChars(), D_PAD::GetPos0(), EDA_TEXT::GetTextAngle(), TEXTE_MODULE::GetType(), LIB_ID::ID_PCB, 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, and THROW_IO_ERROR.

Referenced by getNetCode().

1872 {
1873  wxCHECK_MSG( CurTok() == T_module, NULL,
1874  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as MODULE." ) );
1875 
1876  wxString name;
1877  wxPoint pt;
1878  T token;
1879  LIB_ID fpid;
1880 
1881  std::unique_ptr<MODULE> module( new MODULE( m_board ) );
1882 
1883  module->SetInitialComments( aInitialComments );
1884 
1885  token = NextTok();
1886 
1887  if( !IsSymbol( token ) && token != T_NUMBER )
1888  Expecting( "symbol|number" );
1889 
1890  name = FromUTF8();
1891 
1892  if( !name.IsEmpty() && fpid.Parse( name, LIB_ID::ID_PCB, true ) >= 0 )
1893  {
1894  wxString error;
1895  error.Printf( _( "Invalid footprint ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),
1896  GetChars( CurSource() ), CurLineNumber(), CurOffset() );
1897  THROW_IO_ERROR( error );
1898  }
1899 
1900  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1901  {
1902  if( token == T_LEFT )
1903  token = NextTok();
1904 
1905  switch( token )
1906  {
1907  case T_version:
1908  {
1909  // Theoretically a module nested in a PCB could declare its own version, though
1910  // as of writing this comment we don't do that. Just in case, take the greater
1911  // version.
1912  int this_version = parseInt( FromUTF8().mb_str( wxConvUTF8 ) );
1913  NeedRIGHT();
1914  m_requiredVersion = std::max( m_requiredVersion, this_version );
1916  break;
1917  }
1918 
1919  case T_locked:
1920  module->SetLocked( true );
1921  break;
1922 
1923  case T_placed:
1924  module->SetIsPlaced( true );
1925  break;
1926 
1927  case T_layer:
1928  {
1929  // Footprints can be only on the front side or the back side.
1930  // but because we can find some stupid layer in file, ensure a
1931  // acceptable layer is set for the footprint
1933  module->SetLayer( layer == B_Cu ? B_Cu : F_Cu );
1934  }
1935  NeedRIGHT();
1936  break;
1937 
1938  case T_tedit:
1939  module->SetLastEditTime( parseHex() );
1940  NeedRIGHT();
1941  break;
1942 
1943  case T_tstamp:
1944  module->SetTimeStamp( parseHex() );
1945  NeedRIGHT();
1946  break;
1947 
1948  case T_at:
1949  pt.x = parseBoardUnits( "X coordinate" );
1950  pt.y = parseBoardUnits( "Y coordinate" );
1951  module->SetPosition( pt );
1952  token = NextTok();
1953 
1954  if( token == T_NUMBER )
1955  {
1956  module->SetOrientation( parseDouble() * 10.0 );
1957  NeedRIGHT();
1958  }
1959  else if( token != T_RIGHT )
1960  {
1961  Expecting( T_RIGHT );
1962  }
1963 
1964  break;
1965 
1966  case T_descr:
1967  NeedSYMBOLorNUMBER(); // some symbols can be 0508, so a number is also a symbol here
1968  module->SetDescription( FromUTF8() );
1969  NeedRIGHT();
1970  break;
1971 
1972  case T_tags:
1973  NeedSYMBOLorNUMBER(); // some symbols can be 0508, so a number is also a symbol here
1974  module->SetKeywords( FromUTF8() );
1975  NeedRIGHT();
1976  break;
1977 
1978  case T_path:
1979  NeedSYMBOLorNUMBER(); // Paths can be numerical so a number is also a symbol here
1980  module->SetPath( FromUTF8() );
1981  NeedRIGHT();
1982  break;
1983 
1984  case T_autoplace_cost90:
1985  module->SetPlacementCost90( parseInt( "auto place cost at 90 degrees" ) );
1986  NeedRIGHT();
1987  break;
1988 
1989  case T_autoplace_cost180:
1990  module->SetPlacementCost180( parseInt( "auto place cost at 180 degrees" ) );
1991  NeedRIGHT();
1992  break;
1993 
1994  case T_solder_mask_margin:
1995  module->SetLocalSolderMaskMargin( parseBoardUnits( "local solder mask margin value" ) );
1996  NeedRIGHT();
1997  break;
1998 
1999  case T_solder_paste_margin:
2000  module->SetLocalSolderPasteMargin(
2001  parseBoardUnits( "local solder paste margin value" ) );
2002  NeedRIGHT();
2003  break;
2004 
2005  case T_solder_paste_ratio:
2006  module->SetLocalSolderPasteMarginRatio(
2007  parseDouble( "local solder paste margin ratio value" ) );
2008  NeedRIGHT();
2009  break;
2010 
2011  case T_clearance:
2012  module->SetLocalClearance( parseBoardUnits( "local clearance value" ) );
2013  NeedRIGHT();
2014  break;
2015 
2016  case T_zone_connect:
2017  module->SetZoneConnection( (ZoneConnection) parseInt( "zone connection value" ) );
2018  NeedRIGHT();
2019  break;
2020 
2021  case T_thermal_width:
2022  module->SetThermalWidth( parseBoardUnits( "thermal width value" ) );
2023  NeedRIGHT();
2024  break;
2025 
2026  case T_thermal_gap:
2027  module->SetThermalGap( parseBoardUnits( "thermal gap value" ) );
2028  NeedRIGHT();
2029  break;
2030 
2031  case T_attr:
2032  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2033  {
2034  switch( token )
2035  {
2036  case T_smd:
2037  module->SetAttributes( module->GetAttributes() | MOD_CMS );
2038  break;
2039 
2040  case T_virtual:
2041  module->SetAttributes( module->GetAttributes() | MOD_VIRTUAL );
2042  break;
2043 
2044  default:
2045  Expecting( "smd and/or virtual" );
2046  }
2047  }
2048  break;
2049 
2050  case T_fp_text:
2051  {
2052  TEXTE_MODULE* text = parseTEXTE_MODULE();
2053  text->SetParent( module.get() );
2054  double orientation = text->GetTextAngle();
2055  orientation -= module->GetOrientation();
2056  text->SetTextAngle( orientation );
2057  text->SetDrawCoord();
2058 
2059  switch( text->GetType() )
2060  {
2062  module->Reference() = *text;
2063  delete text;
2064  break;
2065 
2067  module->Value() = *text;
2068  delete text;
2069  break;
2070 
2071  default:
2072  module->GraphicalItemsList().PushBack( text );
2073  }
2074  }
2075  break;
2076 
2077  case T_fp_arc:
2078  case T_fp_circle:
2079  case T_fp_curve:
2080  case T_fp_line:
2081  case T_fp_poly:
2082  {
2083  EDGE_MODULE* em = parseEDGE_MODULE();
2084  em->SetParent( module.get() );
2085  em->SetDrawCoord();
2086  module->GraphicalItemsList().PushBack( em );
2087  }
2088  break;
2089 
2090  case T_pad:
2091  {
2092  D_PAD* pad = parseD_PAD( module.get() );
2093  pt = pad->GetPos0();
2094 
2095  RotatePoint( &pt, module->GetOrientation() );
2096  pad->SetPosition( pt + module->GetPosition() );
2097  module->Add( pad, ADD_APPEND );
2098  }
2099  break;
2100 
2101  case T_model:
2102  module->Add3DModel( parse3DModel() );
2103  break;
2104 
2105  default:
2106  Expecting( "locked, placed, tedit, tstamp, at, descr, tags, path, "
2107  "autoplace_cost90, autoplace_cost180, solder_mask_margin, "
2108  "solder_paste_margin, solder_paste_ratio, clearance, "
2109  "zone_connect, thermal_width, thermal_gap, attr, fp_text, "
2110  "fp_arc, fp_circle, fp_curve, fp_line, fp_poly, pad, or model" );
2111  }
2112  }
2113 
2114  module->SetFPID( fpid );
2115  module->CalculateBoundingBox();
2116 
2117  return module.release();
2118 }
TEXT_TYPE GetType() const
ZoneConnection
How pads are covered by copper in zone.
Definition: zones.h:50
Set for modules listed in the automatic insertion list (usually SMD footprints)
Definition: class_module.h:76
#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
bool m_tooRecent
true if version parses as later than supported
Definition: pcb_parser.h:75
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:228
double GetTextAngle() const
Definition: eda_text.h:177
PCB_LAYER_ID
A quick note on layer IDs:
void SetParent(EDA_ITEM *aParent)
Definition: base_struct.h:216
PCB_LAYER_ID parseBoardItemLayer()
Function parseBoardItemLayer parses the layer definition of a BOARD_ITEM object.
#define THROW_IO_ERROR(msg)
int m_requiredVersion
set to the KiCad format version this board requires
Definition: pcb_parser.h:76
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:78
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:263
int parseInt()
Definition: pcb_parser.h:252
int Parse(const UTF8 &aId, LIB_ID_TYPE aType, bool aFix=false)
Parse LIB_ID with the information from aId.
Definition: lib_id.cpp:122
MODULE_3D_SETTINGS * parse3DModel()
Definition: pcb_parser.cpp:350
void PCB_PARSER::parseNETCLASS ( )
private

Definition at line 1368 of file pcb_parser.cpp.

References THROW_IO_ERROR.

Referenced by getNetCode().

1369 {
1370  wxCHECK_RET( CurTok() == T_net_class,
1371  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as net class." ) );
1372 
1373  T token;
1374 
1375  NETCLASSPTR nc = std::make_shared<NETCLASS>( wxEmptyString );
1376 
1377  // Read netclass name (can be a name or just a number like track width)
1378  NeedSYMBOLorNUMBER();
1379  nc->SetName( FromUTF8() );
1380  NeedSYMBOL();
1381  nc->SetDescription( FromUTF8() );
1382 
1383  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1384  {
1385  if( token != T_LEFT )
1386  Expecting( T_LEFT );
1387 
1388  token = NextTok();
1389 
1390  switch( token )
1391  {
1392  case T_clearance:
1393  nc->SetClearance( parseBoardUnits( T_clearance ) );
1394  break;
1395 
1396  case T_trace_width:
1397  nc->SetTrackWidth( parseBoardUnits( T_trace_width ) );
1398  break;
1399 
1400  case T_via_dia:
1401  nc->SetViaDiameter( parseBoardUnits( T_via_dia ) );
1402  break;
1403 
1404  case T_via_drill:
1405  nc->SetViaDrill( parseBoardUnits( T_via_drill ) );
1406  break;
1407 
1408  case T_uvia_dia:
1409  nc->SetuViaDiameter( parseBoardUnits( T_uvia_dia ) );
1410  break;
1411 
1412  case T_uvia_drill:
1413  nc->SetuViaDrill( parseBoardUnits( T_uvia_drill ) );
1414  break;
1415 
1416  case T_diff_pair_width:
1417  nc->SetDiffPairWidth( parseBoardUnits( T_diff_pair_width ) );
1418  break;
1419 
1420  case T_diff_pair_gap:
1421  nc->SetDiffPairGap( parseBoardUnits( T_diff_pair_gap ) );
1422  break;
1423 
1424  case T_add_net:
1425  NeedSYMBOLorNUMBER();
1426  nc->Add( FromUTF8() );
1427  break;
1428 
1429  default:
1430  Expecting( "clearance, trace_width, via_dia, via_drill, uvia_dia, uvia_drill, diff_pair_width, diff_pair_gap or add_net" );
1431  }
1432 
1433  NeedRIGHT();
1434  }
1435 
1436  if( !m_board->GetDesignSettings().m_NetClasses.Add( nc ) )
1437  {
1438  // Must have been a name conflict, this is a bad board file.
1439  // User may have done a hand edit to the file.
1440 
1441  // unique_ptr will delete nc on this code path
1442 
1443  wxString error;
1444  error.Printf( _( "Duplicate NETCLASS name \"%s\" in file \"%s\" at line %d, offset %d" ),
1445  nc->GetName().GetData(), CurSource().GetData(), CurLineNumber(), CurOffset() );
1446  THROW_IO_ERROR( error );
1447  }
1448 }
int parseBoardUnits()
Definition: pcb_parser.h:228
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:539
#define THROW_IO_ERROR(msg)
bool Add(const NETCLASSPTR &aNetclass)
Function Add takes aNetclass and puts it into this NETCLASSES container.
Definition: netclass.cpp:99
BOARD * m_board
Definition: pcb_parser.h:70
void PCB_PARSER::parseNETINFO_ITEM ( )
private

Definition at line 1342 of file pcb_parser.cpp.

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

Referenced by getNetCode().

1343 {
1344  wxCHECK_RET( CurTok() == T_net,
1345  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as net." ) );
1346 
1347  int netCode = parseInt( "net number" );
1348 
1349  NeedSYMBOLorNUMBER();
1350  wxString name = FromUTF8();
1351 
1352  NeedRIGHT();
1353 
1354  // net 0 should be already in list, so store this net
1355  // if it is not the net 0, or if the net 0 does not exists.
1356  // (TODO: a better test.)
1358  {
1359  NETINFO_ITEM* net = new NETINFO_ITEM( m_board, name, netCode );
1360  m_board->Add( net );
1361 
1362  // Store the new code mapping
1363  pushValueIntoMap( netCode, net->GetNet() );
1364  }
1365 }
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:231
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:252
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
Definition: netinfo.h:469
void PCB_PARSER::parsePAGE_INFO ( )
private

Definition at line 751 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().

752 {
753  wxCHECK_RET( CurTok() == T_page,
754  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a PAGE_INFO." ) );
755 
756  T token;
757  PAGE_INFO pageInfo;
758 
759  NeedSYMBOL();
760 
761  wxString pageType = FromUTF8();
762 
763  if( !pageInfo.SetType( pageType ) )
764  {
765  wxString err;
766  err.Printf( _( "Page type \"%s\" is not valid " ), GetChars( FromUTF8() ) );
767  THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
768  }
769 
770  if( pageType == PAGE_INFO::Custom )
771  {
772  double width = parseDouble( "width" ); // width in mm
773 
774  // Perform some controls to avoid crashes if the size is edited by hands
775  if( width < 100.0 )
776  width = 100.0;
777  else if( width > 1200.0 )
778  width = 1200.0;
779 
780  double height = parseDouble( "height" ); // height in mm
781 
782  if( height < 100.0 )
783  height = 100.0;
784  else if( height > 1200.0 )
785  height = 1200.0;
786 
787  pageInfo.SetWidthMils( Mm2mils( width ) );
788  pageInfo.SetHeightMils( Mm2mils( height ) );
789  }
790 
791  token = NextTok();
792 
793  if( token == T_portrait )
794  {
795  pageInfo.SetPortrait( true );
796  NeedRIGHT();
797  }
798  else if( token != T_RIGHT )
799  {
800  Expecting( "portrait|)" );
801  }
802 
803  m_board->SetPageSettings( pageInfo );
804 }
int Mm2mils(double x)
Convert mm to mils.
Definition: base_units.h:51
void SetPageSettings(const PAGE_INFO &aPageSettings)
Definition: class_board.h:555
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:78
Class PAGE_INFO describes the page size and margins of a paper page on which to eventually print or p...
Definition: page_info.h:54
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
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 3297 of file pcb_parser.cpp.

References parseHex().

Referenced by getNetCode().

3298 {
3299  wxCHECK_MSG( CurTok() == T_target, NULL,
3300  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as PCB_TARGET." ) );
3301 
3302  wxPoint pt;
3303  T token;
3304 
3305  std::unique_ptr< PCB_TARGET > target( new PCB_TARGET( NULL ) );
3306 
3307  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3308  {
3309  if( token == T_LEFT )
3310  token = NextTok();
3311 
3312  switch( token )
3313  {
3314  case T_x:
3315  target->SetShape( 1 );
3316  break;
3317 
3318  case T_plus:
3319  target->SetShape( 0 );
3320  break;
3321 
3322  case T_at:
3323  pt.x = parseBoardUnits( "target x position" );
3324  pt.y = parseBoardUnits( "target y position" );
3325  target->SetPosition( pt );
3326  NeedRIGHT();
3327  break;
3328 
3329  case T_size:
3330  target->SetSize( parseBoardUnits( "target size" ) );
3331  NeedRIGHT();
3332  break;
3333 
3334  case T_width:
3335  target->SetWidth( parseBoardUnits( "target thickness" ) );
3336  NeedRIGHT();
3337  break;
3338 
3339  case T_layer:
3340  target->SetLayer( parseBoardItemLayer() );
3341  NeedRIGHT();
3342  break;
3343 
3344  case T_tstamp:
3345  target->SetTimeStamp( parseHex() );
3346  NeedRIGHT();
3347  break;
3348 
3349  default:
3350  Expecting( "x, plus, at, size, width, layer or tstamp" );
3351  }
3352  }
3353 
3354  return target.release();
3355 }
int parseBoardUnits()
Definition: pcb_parser.h:228
PCB_LAYER_ID parseBoardItemLayer()
Function parseBoardItemLayer parses the layer definition of a BOARD_ITEM object.
long parseHex()
Definition: pcb_parser.h:263
void PCB_PARSER::parseSetup ( )
private

Definition at line 1102 of file pcb_parser.cpp.

References LAYER_CLASS_COPPER, LAYER_CLASS_EDGES, LAYER_CLASS_SILK, BOARD_DESIGN_SETTINGS::m_AuxOrigin, BOARD_DESIGN_SETTINGS::m_BlindBuriedViaAllowed, BOARD_DESIGN_SETTINGS::m_GridOrigin, BOARD_DESIGN_SETTINGS::m_LineThickness, BOARD_DESIGN_SETTINGS::m_MicroViasAllowed, BOARD_DESIGN_SETTINGS::m_MicroViasMinDrill, BOARD_DESIGN_SETTINGS::m_MicroViasMinSize, BOARD_DESIGN_SETTINGS::m_Pad_Master, BOARD_DESIGN_SETTINGS::m_SolderMaskMargin, BOARD_DESIGN_SETTINGS::m_SolderMaskMinWidth, BOARD_DESIGN_SETTINGS::m_SolderPasteMargin, BOARD_DESIGN_SETTINGS::m_SolderPasteMarginRatio, BOARD_DESIGN_SETTINGS::m_TextSize, BOARD_DESIGN_SETTINGS::m_TextThickness, 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().

1103 {
1104  wxCHECK_RET( CurTok() == T_setup,
1105  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as setup." ) );
1106 
1107  T token;
1108  NETCLASSPTR defaultNetClass = m_board->GetDesignSettings().GetDefault();
1109  // TODO Orson: is it really necessary to first operate on a copy and then apply it?
1110  // would not it be better to use reference here and apply all the changes instantly?
1111  BOARD_DESIGN_SETTINGS designSettings = m_board->GetDesignSettings();
1112  ZONE_SETTINGS zoneSettings = m_board->GetZoneSettings();
1113 
1114  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1115  {
1116  if( token != T_LEFT )
1117  Expecting( T_LEFT );
1118 
1119  token = NextTok();
1120 
1121  switch( token )
1122  {
1123  case T_last_trace_width: // not used now
1124  /* lastTraceWidth =*/ parseBoardUnits( T_last_trace_width );
1125  NeedRIGHT();
1126  break;
1127 
1128  case T_user_trace_width:
1129  designSettings.m_TrackWidthList.push_back( parseBoardUnits( T_user_trace_width ) );
1130  NeedRIGHT();
1131  break;
1132 
1133  case T_trace_clearance:
1134  defaultNetClass->SetClearance( parseBoardUnits( T_trace_clearance ) );
1135  NeedRIGHT();
1136  break;
1137 
1138  case T_zone_clearance:
1139  zoneSettings.m_ZoneClearance = parseBoardUnits( T_zone_clearance );
1140  NeedRIGHT();
1141  break;
1142 
1143  case T_zone_45_only:
1144  zoneSettings.m_Zone_45_Only = parseBool();
1145  NeedRIGHT();
1146  break;
1147 
1148  case T_trace_min:
1149  designSettings.m_TrackMinWidth = parseBoardUnits( T_trace_min );
1150  NeedRIGHT();
1151  break;
1152 
1153  case T_via_size:
1154  defaultNetClass->SetViaDiameter( parseBoardUnits( T_via_size ) );
1155  NeedRIGHT();
1156  break;
1157 
1158  case T_via_drill:
1159  defaultNetClass->SetViaDrill( parseBoardUnits( T_via_drill ) );
1160  NeedRIGHT();
1161  break;
1162 
1163  case T_via_min_size:
1164  designSettings.m_ViasMinSize = parseBoardUnits( T_via_min_size );
1165  NeedRIGHT();
1166  break;
1167 
1168  case T_via_min_drill:
1169  designSettings.m_ViasMinDrill = parseBoardUnits( T_via_min_drill );
1170  NeedRIGHT();
1171  break;
1172 
1173  case T_user_via:
1174  {
1175  int viaSize = parseBoardUnits( "user via size" );
1176  int viaDrill = parseBoardUnits( "user via drill" );
1177  designSettings.m_ViasDimensionsList.push_back( VIA_DIMENSION( viaSize, viaDrill ) );
1178  NeedRIGHT();
1179  }
1180  break;
1181 
1182  case T_uvia_size:
1183  defaultNetClass->SetuViaDiameter( parseBoardUnits( T_uvia_size ) );
1184  NeedRIGHT();
1185  break;
1186 
1187  case T_uvia_drill:
1188  defaultNetClass->SetuViaDrill( parseBoardUnits( T_uvia_drill ) );
1189  NeedRIGHT();
1190  break;
1191 
1192  case T_uvias_allowed:
1193  designSettings.m_MicroViasAllowed = parseBool();
1194  NeedRIGHT();
1195  break;
1196 
1197  case T_blind_buried_vias_allowed:
1198  designSettings.m_BlindBuriedViaAllowed = parseBool();
1199  NeedRIGHT();
1200  break;
1201 
1202  case T_uvia_min_size:
1203  designSettings.m_MicroViasMinSize = parseBoardUnits( T_uvia_min_size );
1204  NeedRIGHT();
1205  break;
1206 
1207  case T_uvia_min_drill:
1208  designSettings.m_MicroViasMinDrill = parseBoardUnits( T_uvia_min_drill );
1209  NeedRIGHT();
1210  break;
1211 
1212  // 6.0 TODO: change these names, or leave them?
1213  // 6.0 TODO: add LAYER_CLASS_OTHERS read/write
1214  // 6.0 TODO: add m_TextItalic read/write
1215  // 6.0 TODO: add m_TextUpright read/write
1216 
1217  case T_segment_width:
1218  designSettings.m_LineThickness[ LAYER_CLASS_COPPER ] = parseBoardUnits( T_segment_width );
1219  NeedRIGHT();
1220  break;
1221 
1222  case T_edge_width:
1223  designSettings.m_LineThickness[ LAYER_CLASS_EDGES ] = parseBoardUnits( T_edge_width );
1224  NeedRIGHT();
1225  break;
1226 
1227  case T_mod_edge_width:
1228  designSettings.m_LineThickness[ LAYER_CLASS_SILK ] = parseBoardUnits( T_mod_edge_width );
1229  NeedRIGHT();
1230  break;
1231 
1232  case T_pcb_text_width:
1233  designSettings.m_TextThickness[ LAYER_CLASS_COPPER ] = parseBoardUnits( T_pcb_text_width );
1234  NeedRIGHT();
1235  break;
1236 
1237  case T_mod_text_width:
1238  designSettings.m_TextThickness[ LAYER_CLASS_SILK ] = parseBoardUnits( T_mod_text_width );
1239  NeedRIGHT();
1240  break;
1241 
1242  case T_pcb_text_size:
1243  designSettings.m_TextSize[ LAYER_CLASS_COPPER ].x = parseBoardUnits( "pcb text width" );
1244  designSettings.m_TextSize[ LAYER_CLASS_COPPER ].y = parseBoardUnits( "pcb text height" );
1245  NeedRIGHT();
1246  break;
1247 
1248  case T_mod_text_size:
1249  designSettings.m_TextSize[ LAYER_CLASS_SILK ].x = parseBoardUnits( "module text width" );
1250  designSettings.m_TextSize[ LAYER_CLASS_SILK ].y = parseBoardUnits( "module text height" );
1251  NeedRIGHT();
1252  break;
1253 
1254  case T_pad_size:
1255  {
1256  wxSize sz;
1257  sz.SetWidth( parseBoardUnits( "master pad width" ) );
1258  sz.SetHeight( parseBoardUnits( "master pad height" ) );
1259  designSettings.m_Pad_Master.SetSize( sz );
1260  NeedRIGHT();
1261  }
1262  break;
1263 
1264  case T_pad_drill:
1265  {
1266  int drillSize = parseBoardUnits( T_pad_drill );
1267  designSettings.m_Pad_Master.SetDrillSize( wxSize( drillSize, drillSize ) );
1268  NeedRIGHT();
1269  }
1270  break;
1271 
1272  case T_pad_to_mask_clearance:
1273  designSettings.m_SolderMaskMargin = parseBoardUnits( T_pad_to_mask_clearance );
1274  NeedRIGHT();
1275  break;
1276 
1277  case T_solder_mask_min_width:
1278  designSettings.m_SolderMaskMinWidth = parseBoardUnits( T_solder_mask_min_width );
1279  NeedRIGHT();
1280  break;
1281 
1282  case T_pad_to_paste_clearance:
1283  designSettings.m_SolderPasteMargin = parseBoardUnits( T_pad_to_paste_clearance );
1284  NeedRIGHT();
1285  break;
1286 
1287  case T_pad_to_paste_clearance_ratio:
1288  designSettings.m_SolderPasteMarginRatio = parseDouble( T_pad_to_paste_clearance_ratio );
1289  NeedRIGHT();
1290  break;
1291 
1292  case T_aux_axis_origin:
1293  {
1294  int x = parseBoardUnits( "auxiliary origin X" );
1295  int y = parseBoardUnits( "auxiliary origin Y" );
1296  // m_board->SetAuxOrigin( wxPoint( x, y ) ); gets overwritten via SetDesignSettings below
1297  designSettings.m_AuxOrigin = wxPoint( x, y );
1298  NeedRIGHT();
1299  }
1300  break;
1301 
1302  case T_grid_origin:
1303  {
1304  int x = parseBoardUnits( "grid origin X" );
1305  int y = parseBoardUnits( "grid origin Y" );
1306  // m_board->SetGridOrigin( wxPoint( x, y ) ); gets overwritten SetDesignSettings below
1307  designSettings.m_GridOrigin = wxPoint( x, y );
1308  NeedRIGHT();
1309  }
1310  break;
1311 
1312  case T_visible_elements:
1313  designSettings.SetVisibleElements( parseHex() | MIN_VISIBILITY_MASK );
1314  NeedRIGHT();
1315  break;
1316 
1317  case T_pcbplotparams:
1318  {
1319  PCB_PLOT_PARAMS plotParams;
1320  PCB_PLOT_PARAMS_PARSER parser( reader );
1321  // parser must share the same current line as our current PCB parser
1322  // synchronize it.
1323  parser.SyncLineReaderWith( *this );
1324 
1325  plotParams.Parse( &parser );
1326  SyncLineReaderWith( parser );
1327 
1328  m_board->SetPlotOptions( plotParams );
1329  }
1330  break;
1331 
1332  default:
1333  Unexpected( CurText() );
1334  }
1335  }
1336 
1337  m_board->SetDesignSettings( designSettings );
1338  m_board->SetZoneSettings( zoneSettings );
1339 }
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:564
const ZONE_SETTINGS & GetZoneSettings() const
Definition: class_board.h:563
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.
std::vector< int > m_TrackWidthList
void SetDrillSize(const wxSize &aSize)
Definition: class_pad.h:274
int parseBoardUnits()
Definition: pcb_parser.h:228
wxSize m_TextSize[LAYER_CLASS_COUNT]
bool parseBool()
Definition: pcb_parser.cpp:154
int m_TextThickness[LAYER_CLASS_COUNT]
#define MIN_VISIBILITY_MASK
int m_TrackMinWidth
track min value for width ((min copper size value
int m_ViasMinSize
vias (not micro vias) min diameter
int m_ViasMinDrill
vias (not micro vias) min drill diameter
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:539
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:549
bool m_BlindBuriedViaAllowed
true to allow blind/buried vias
void SetPlotOptions(const PCB_PLOT_PARAMS &aOptions)
Definition: class_board.h:558
int m_MicroViasMinSize
micro vias (not vias) min diameter
Class PCB_PLOT_PARAMS handles plot parameters and options when plotting/printing a board...
int m_LineThickness[LAYER_CLASS_COUNT]
Class ZONE_SETTINGS handles zones parameters.
Definition: zone_settings.h:48
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
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:263
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 2121 of file pcb_parser.cpp.

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

Referenced by getNetCode().

2122 {
2123  wxCHECK_MSG( CurTok() == T_fp_text, NULL,
2124  wxString::Format( wxT( "Cannot parse %s as TEXTE_MODULE at line %d, offset %d." ),
2125  GetChars( GetTokenString( CurTok() ) ),
2126  CurLineNumber(), CurOffset() ) );
2127 
2128  T token = NextTok();
2129 
2130  std::unique_ptr<TEXTE_MODULE> text( new TEXTE_MODULE( NULL ) );
2131 
2132  switch( token )
2133  {
2134  case T_reference:
2135  text->SetType( TEXTE_MODULE::TEXT_is_REFERENCE );
2136  break;
2137 
2138  case T_value:
2139  text->SetType( TEXTE_MODULE::TEXT_is_VALUE );
2140  break;
2141 
2142  case T_user:
2143  break; // Default type is user text.
2144 
2145  default:
2146  THROW_IO_ERROR( wxString::Format( _( "Cannot handle footprint text type %s" ),
2147  GetChars( FromUTF8() ) ) );
2148  }
2149 
2150  NeedSYMBOLorNUMBER();
2151 
2152  text->SetText( FromUTF8() );
2153  NeedLEFT();
2154  token = NextTok();
2155 
2156  if( token != T_at )
2157  Expecting( T_at );
2158 
2159  wxPoint pt;
2160 
2161  pt.x = parseBoardUnits( "X coordinate" );
2162  pt.y = parseBoardUnits( "Y coordinate" );
2163  text->SetPos0( pt );
2164 
2165  NextTok();
2166 
2167  if( CurTok() == T_NUMBER )
2168  {
2169  text->SetTextAngle( parseDouble() * 10.0 );
2170  NextTok();
2171  }
2172 
2173  if( CurTok() == T_unlocked )
2174  {
2175  text->SetKeepUpright( false );
2176  NextTok();
2177  }
2178 
2179  if( CurTok() != T_RIGHT )
2180  {
2181  Unexpected( CurText() );
2182  }
2183 
2184  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2185  {
2186  if( token == T_LEFT )
2187  token = NextTok();
2188 
2189  switch( token )
2190  {
2191  case T_layer:
2192  text->SetLayer( parseBoardItemLayer() );
2193  NeedRIGHT();
2194  break;
2195 
2196  case T_hide:
2197  text->SetVisible( false );
2198  break;
2199 
2200  case T_effects:
2201  parseEDA_TEXT( (EDA_TEXT*) text.get() );
2202  break;
2203 
2204  default:
2205  Expecting( "hide or effects" );
2206  }
2207  }
2208 
2209  return text.release();
2210 }
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:228
Class EDA_TEXT is a mix-in class (via multiple inheritance) that handles texts such as labels...
Definition: eda_text.h:127
PCB_LAYER_ID parseBoardItemLayer()
Function parseBoardItemLayer parses the layer definition of a BOARD_ITEM object.
#define THROW_IO_ERROR(msg)
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
TEXTE_PCB * PCB_PARSER::parseTEXTE_PCB ( )
private

Definition at line 1624 of file pcb_parser.cpp.

References parseDouble(), and parseHex().

Referenced by getNetCode().

1625 {
1626  wxCHECK_MSG( CurTok() == T_gr_text, NULL,
1627  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as TEXTE_PCB." ) );
1628 
1629  T token;
1630 
1631  std::unique_ptr<TEXTE_PCB> text( new TEXTE_PCB( m_board ) );
1632  NeedSYMBOLorNUMBER();
1633 
1634  text->SetText( FromUTF8() );
1635  NeedLEFT();
1636  token = NextTok();
1637 
1638  if( token != T_at )
1639  Expecting( T_at );
1640 
1641  wxPoint pt;
1642 
1643  pt.x = parseBoardUnits( "X coordinate" );
1644  pt.y = parseBoardUnits( "Y coordinate" );
1645  text->SetTextPos( pt );
1646 
1647  // If there is no orientation defined, then it is the default value of 0 degrees.
1648  token = NextTok();
1649 
1650  if( token == T_NUMBER )
1651  {
1652  text->SetTextAngle( parseDouble() * 10.0 );
1653  NeedRIGHT();
1654  }
1655  else if( token != T_RIGHT )
1656  {
1657  Unexpected( CurText() );
1658  }
1659 
1660  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1661  {
1662  if( token != T_LEFT )
1663  Expecting( T_LEFT );
1664 
1665  token = NextTok();
1666 
1667  switch( token )
1668  {
1669  case T_layer:
1670  text->SetLayer( parseBoardItemLayer() );
1671  NeedRIGHT();
1672  break;
1673 
1674  case T_tstamp:
1675  text->SetTimeStamp( parseHex() );
1676  NeedRIGHT();
1677  break;
1678 
1679  case T_effects:
1680  parseEDA_TEXT( (EDA_TEXT*) text.get() );
1681  break;
1682 
1683  default:
1684  Expecting( "layer, tstamp or effects" );
1685  }
1686  }
1687 
1688  return text.release();
1689 }
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:228
Class EDA_TEXT is a mix-in class (via multiple inheritance) that handles texts such as labels...
Definition: eda_text.h:127
PCB_LAYER_ID parseBoardItemLayer()
Function parseBoardItemLayer parses the layer definition of a BOARD_ITEM object.
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:263
void PCB_PARSER::parseTITLE_BLOCK ( )
private

Definition at line 807 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().

808 {
809  wxCHECK_RET( CurTok() == T_title_block,
810  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
811  wxT( " as TITLE_BLOCK." ) );
812 
813  T token;
814  TITLE_BLOCK titleBlock;
815 
816  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
817  {
818  if( token != T_LEFT )
819  Expecting( T_LEFT );
820 
821  token = NextTok();
822 
823  switch( token )
824  {
825  case T_title:
826  NextTok();
827  titleBlock.SetTitle( FromUTF8() );
828  break;
829 
830  case T_date:
831  NextTok();
832  titleBlock.SetDate( FromUTF8() );
833  break;
834 
835  case T_rev:
836  NextTok();
837  titleBlock.SetRevision( FromUTF8() );
838  break;
839 
840  case T_company:
841  NextTok();
842  titleBlock.SetCompany( FromUTF8() );
843  break;
844 
845  case T_comment:
846  {
847  int commentNumber = parseInt( "comment" );
848 
849  switch( commentNumber )
850  {
851  case 1:
852  NextTok();
853  titleBlock.SetComment1( FromUTF8() );
854  break;
855 
856  case 2:
857  NextTok();
858  titleBlock.SetComment2( FromUTF8() );
859  break;
860 
861  case 3:
862  NextTok();
863  titleBlock.SetComment3( FromUTF8() );
864  break;
865 
866  case 4:
867  NextTok();
868  titleBlock.SetComment4( FromUTF8() );
869  break;
870 
871  default:
872  wxString err;
873  err.Printf( wxT( "%d is not a valid title block comment number" ), commentNumber );
874  THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
875  }
876  }
877  break;
878 
879  default:
880  Expecting( "title, date, rev, company, or comment" );
881  }
882 
883  NeedRIGHT();
884  }
885 
886  m_board->SetTitleBlock( titleBlock );
887 }
void SetComment1(const wxString &aComment)
Definition: title_block.h:117
void SetRevision(const wxString &aRevision)
Definition: title_block.h:84
void SetTitleBlock(const TITLE_BLOCK &aTitleBlock)
Definition: class_board.h:561
void SetDate(const wxString &aDate)
Function SetDate sets the date field, and defaults to the current time and date.
Definition: title_block.h:74
Class TITLE_BLOCK holds the information shown in the lower right corner of a plot, printout, or editing view.
Definition: title_block.h:40
void SetComment4(const wxString &aComment)
Definition: title_block.h:120
void SetCompany(const wxString &aCompany)
Definition: title_block.h:94
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
void SetTitle(const wxString &aTitle)
Definition: title_block.h:60
string & err
Definition: json11.cpp:598
void SetComment2(const wxString &aComment)
Definition: title_block.h:118
BOARD * m_board
Definition: pcb_parser.h:70
void SetComment3(const wxString &aComment)
Definition: title_block.h:119
int parseInt()
Definition: pcb_parser.h:252
TRACK * PCB_PARSER::parseTRACK ( )
private

Definition at line 2771 of file pcb_parser.cpp.

References Format(), GetChars(), parseHex(), parseInt(), and THROW_IO_ERROR.

Referenced by getNetCode().

2772 {
2773  wxCHECK_MSG( CurTok() == T_segment, NULL,
2774  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as TRACK." ) );
2775 
2776  wxPoint pt;
2777  T token;
2778 
2779  std::unique_ptr< TRACK > track( new TRACK( m_board ) );
2780 
2781  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2782  {
2783  if( token != T_LEFT )
2784  Expecting( T_LEFT );
2785 
2786  token = NextTok();
2787 
2788  switch( token )
2789  {
2790  case T_start:
2791  pt.x = parseBoardUnits( "start x" );
2792  pt.y = parseBoardUnits( "start y" );
2793  track->SetStart( pt );
2794  break;
2795 
2796  case T_end:
2797  pt.x = parseBoardUnits( "end x" );
2798  pt.y = parseBoardUnits( "end y" );
2799  track->SetEnd( pt );
2800  break;
2801 
2802  case T_width:
2803  track->SetWidth( parseBoardUnits( "width" ) );
2804  break;
2805 
2806  case T_layer:
2807  track->SetLayer( parseBoardItemLayer() );
2808  break;
2809 
2810  case T_net:
2811  if( ! track->SetNetCode( getNetCode( parseInt( "net number" ) ), /* aNoAssert */ true ) )
2813  wxString::Format( _( "Invalid net ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),
2814  GetChars( CurSource() ), CurLineNumber(), CurOffset() )
2815  );
2816  break;
2817 
2818  case T_tstamp:
2819  track->SetTimeStamp( parseHex() );
2820  break;
2821 
2822  case T_status:
2823  track->SetStatus( static_cast<STATUS_FLAGS>( parseHex() ) );
2824  break;
2825 
2826  default:
2827  Expecting( "start, end, width, layer, net, tstamp, or status" );
2828  }
2829 
2830  NeedRIGHT();
2831  }
2832 
2833  return track.release();
2834 }
int parseBoardUnits()
Definition: pcb_parser.h:228
PCB_LAYER_ID parseBoardItemLayer()
Function parseBoardItemLayer parses the layer definition of a BOARD_ITEM object.
#define THROW_IO_ERROR(msg)
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:80
BOARD * m_board
Definition: pcb_parser.h:70
long parseHex()
Definition: pcb_parser.h:263
int parseInt()
Definition: pcb_parser.h:252
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:252
VIA * PCB_PARSER::parseVIA ( )
private

Definition at line 2837 of file pcb_parser.cpp.

References Format(), GetChars(), parseHex(), parseInt(), THROW_IO_ERROR, VIA, VIA_BLIND_BURIED, and VIA_MICROVIA.

Referenced by getNetCode().

2838 {
2839  wxCHECK_MSG( CurTok() == T_via, NULL,
2840  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as VIA." ) );
2841 
2842  wxPoint pt;
2843  T token;
2844 
2845  std::unique_ptr< VIA > via( new VIA( m_board ) );
2846 
2847  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2848  {
2849  if( token == T_LEFT )
2850  token = NextTok();
2851 
2852  switch( token )
2853  {
2854  case T_blind:
2855  via->SetViaType( VIA_BLIND_BURIED );
2856  break;
2857 
2858  case T_micro:
2859  via->SetViaType( VIA_MICROVIA );
2860  break;
2861 
2862  case T_at:
2863  pt.x = parseBoardUnits( "start x" );
2864  pt.y = parseBoardUnits( "start y" );
2865  via->SetStart( pt );
2866  via->SetEnd( pt );
2867  NeedRIGHT();
2868  break;
2869 
2870  case T_size:
2871  via->SetWidth( parseBoardUnits( "via width" ) );
2872  NeedRIGHT();
2873  break;
2874 
2875  case T_drill:
2876  via->SetDrill( parseBoardUnits( "drill diameter" ) );
2877  NeedRIGHT();
2878  break;
2879 
2880  case T_layers:
2881  {
2882  PCB_LAYER_ID layer1, layer2;
2883  NextTok();
2884  layer1 = lookUpLayer<PCB_LAYER_ID>( m_layerIndices );
2885  NextTok();
2886  layer2 = lookUpLayer<PCB_LAYER_ID>( m_layerIndices );
2887  via->SetLayerPair( layer1, layer2 );
2888  NeedRIGHT();
2889  }
2890  break;
2891 
2892  case T_net:
2893  if(! via->SetNetCode( getNetCode( parseInt( "net number" ) ), /* aNoAssert */ true))
2895  wxString::Format( _( "Invalid net ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),
2896  GetChars( CurSource() ), CurLineNumber(), CurOffset() )
2897  );
2898  NeedRIGHT();
2899  break;
2900 
2901  case T_tstamp:
2902  via->SetTimeStamp( parseHex() );
2903  NeedRIGHT();
2904  break;
2905 
2906  case T_status:
2907  via->SetStatus( static_cast<STATUS_FLAGS>( parseHex() ) );
2908  NeedRIGHT();
2909  break;
2910 
2911  default:
2912  Expecting( "blind, micro, at, size, drill, layers, net, tstamp, or status" );
2913  }
2914  }
2915 
2916  return via.release();
2917 }
int parseBoardUnits()
Definition: pcb_parser.h:228
PCB_LAYER_ID
A quick note on layer IDs:
#define THROW_IO_ERROR(msg)
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:80
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:263
int parseInt()
Definition: pcb_parser.h:252
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.

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:228
void PCB_PARSER::parseXY ( int *  aX,
int *  aY 
)
private

Definition at line 226 of file pcb_parser.cpp.

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 2920 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().

2921 {
2922  wxCHECK_MSG( CurTok() == T_zone, NULL,
2923  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
2924  wxT( " as ZONE_CONTAINER." ) );
2925 
2927 
2928  int hatchPitch = ZONE_CONTAINER::GetDefaultHatchPitch();
2929  wxPoint pt;
2930  T token;
2931  int tmp;
2932  wxString netnameFromfile; // the zone net name find in file
2933 
2934  // bigger scope since each filled_polygon is concatenated in here
2935  SHAPE_POLY_SET pts;
2936 
2937  std::unique_ptr< ZONE_CONTAINER > zone( new ZONE_CONTAINER( m_board ) );
2938 
2939  zone->SetPriority( 0 );
2940 
2941  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2942  {
2943  if( token == T_LEFT )
2944  token = NextTok();
2945 
2946  switch( token )
2947  {
2948  case T_net:
2949  // Init the net code only, not the netname, to be sure
2950  // the zone net name is the name read in file.
2951  // (When mismatch, the user will be prompted in DRC, to fix the actual name)
2952  tmp = getNetCode( parseInt( "net number" ) );
2953 
2954  if( tmp < 0 )
2955  tmp = 0;
2956 
2957  if( ! zone->SetNetCode( tmp, /* aNoAssert */ true ) )
2959  wxString::Format( _( "Invalid net ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),
2960  GetChars( CurSource() ), CurLineNumber(), CurOffset() )
2961  );
2962 
2963  NeedRIGHT();
2964  break;
2965 
2966  case T_net_name:
2967  NeedSYMBOLorNUMBER();
2968  netnameFromfile = FromUTF8();
2969  NeedRIGHT();
2970  break;
2971 
2972  case T_layer: // keyword for zones that are on only one layer
2973  zone->SetLayer( parseBoardItemLayer() );
2974  NeedRIGHT();
2975  break;
2976 
2977  case T_layers: // keyword for zones that can live on a set of layer
2978  // currently: keepout zones
2979  zone->SetLayerSet( parseBoardItemLayersAsMask() );
2980  break;
2981 
2982  case T_tstamp:
2983  zone->SetTimeStamp( parseHex() );
2984  NeedRIGHT();
2985  break;
2986 
2987  case T_hatch:
2988  token = NextTok();
2989 
2990  if( token != T_none && token != T_edge && token != T_full )
2991  Expecting( "none, edge, or full" );
2992 
2993  switch( token )
2994  {
2995  default:
2996  case T_none: hatchStyle = ZONE_CONTAINER::NO_HATCH; break;
2997  case T_edge: hatchStyle = ZONE_CONTAINER::DIAGONAL_EDGE; break;
2998  case T_full: hatchStyle = ZONE_CONTAINER::DIAGONAL_FULL;
2999  }
3000 
3001  hatchPitch = parseBoardUnits( "hatch pitch" );
3002  NeedRIGHT();
3003  break;
3004 
3005  case T_priority:
3006  zone->SetPriority( parseInt( "zone priority" ) );
3007  NeedRIGHT();
3008  break;
3009 
3010  case T_connect_pads:
3011  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3012  {
3013  if( token == T_LEFT )
3014  token = NextTok();
3015 
3016  switch( token )
3017  {
3018  case T_yes:
3019  zone->SetPadConnection( PAD_ZONE_CONN_FULL );
3020  break;
3021 
3022  case T_no:
3023  zone->SetPadConnection( PAD_ZONE_CONN_NONE );
3024  break;
3025 
3026  case T_thru_hole_only:
3027  zone->SetPadConnection( PAD_ZONE_CONN_THT_THERMAL );
3028  break;
3029 
3030  case T_clearance:
3031  zone->SetZoneClearance( parseBoardUnits( "zone clearance" ) );
3032  NeedRIGHT();
3033  break;
3034 
3035  default:
3036  Expecting( "yes, no, or clearance" );
3037  }
3038  }
3039 
3040  break;
3041 
3042  case T_min_thickness:
3043  zone->SetMinThickness( parseBoardUnits( T_min_thickness ) );
3044  NeedRIGHT();
3045  break;
3046 
3047  case T_fill:
3048  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3049  {
3050  if( token == T_LEFT )
3051  token = NextTok();
3052 
3053  switch( token )
3054  {
3055  case T_yes:
3056  zone->SetIsFilled( true );
3057  break;
3058 
3059  case T_mode:
3060  token = NextTok();
3061 
3062  if( token != T_segment && token != T_polygon )
3063  Expecting( "segment or polygon" );
3064 
3065  // @todo Create an enum for fill modes.
3066  zone->SetFillMode( token == T_polygon ? ZFM_POLYGONS : ZFM_SEGMENTS );
3067  NeedRIGHT();
3068  break;
3069 
3070  case T_arc_segments:
3071  zone->SetArcSegmentCount( parseInt( "arc segment count" ) );
3072  NeedRIGHT();
3073  break;
3074 
3075  case T_thermal_gap:
3076  zone->SetThermalReliefGap( parseBoardUnits( T_thermal_gap ) );
3077  NeedRIGHT();
3078  break;
3079 
3080  case T_thermal_bridge_width:
3081  zone->SetThermalReliefCopperBridge( parseBoardUnits( T_thermal_bridge_width ) );
3082  NeedRIGHT();
3083  break;
3084 
3085  case T_smoothing:
3086  switch( NextTok() )
3087  {
3088  case T_none:
3089  zone->SetCornerSmoothingType( ZONE_SETTINGS::SMOOTHING_NONE );
3090  break;
3091 
3092  case T_chamfer:
3093  if( !zone->GetIsKeepout() ) // smoothing has meaning only for filled zones
3094  zone->SetCornerSmoothingType( ZONE_SETTINGS::SMOOTHING_CHAMFER );
3095  break;
3096 
3097  case T_fillet:
3098  if( !zone->GetIsKeepout() ) // smoothing has meaning only for filled zones
3099  zone->SetCornerSmoothingType( ZONE_SETTINGS::SMOOTHING_FILLET );
3100  break;
3101 
3102  default:
3103  Expecting( "none, chamfer, or fillet" );
3104  }
3105  NeedRIGHT();
3106  break;
3107 
3108  case T_radius:
3109  tmp = parseBoardUnits( "corner radius" );
3110  if( !zone->GetIsKeepout() ) // smoothing has meaning only for filled zones
3111  zone->SetCornerRadius( tmp );
3112  NeedRIGHT();
3113  break;
3114 
3115  default:
3116  Expecting( "mode, arc_segments, thermal_gap, thermal_bridge_width, "
3117  "smoothing, or radius" );
3118  }
3119  }
3120  break;
3121 
3122  case T_keepout:
3123  zone->SetIsKeepout( true );
3124 
3125  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3126  {
3127  if( token == T_LEFT )
3128  token = NextTok();
3129 
3130  switch( token )
3131  {
3132  case T_tracks:
3133  token = NextTok();
3134 
3135  if( token != T_allowed && token != T_not_allowed )
3136  Expecting( "allowed or not_allowed" );
3137  zone->SetDoNotAllowTracks( token == T_not_allowed );
3138  break;
3139 
3140  case T_vias:
3141  token = NextTok();
3142 
3143  if( token != T_allowed && token != T_not_allowed )
3144  Expecting( "allowed or not_allowed" );
3145  zone->SetDoNotAllowVias( token == T_not_allowed );
3146  break;
3147 
3148  case T_copperpour:
3149  token = NextTok();
3150 
3151  if( token != T_allowed && token != T_not_allowed )
3152  Expecting( "allowed or not_allowed" );
3153  zone->SetDoNotAllowCopperPour( token == T_not_allowed );
3154  break;
3155 
3156  default:
3157  Expecting( "tracks, vias or copperpour" );
3158  }
3159 
3160  NeedRIGHT();
3161  }
3162 
3163  break;
3164 
3165  case T_polygon:
3166  {
3167  std::vector< wxPoint > corners;
3168 
3169  NeedLEFT();
3170  token = NextTok();
3171 
3172  if( token != T_pts )
3173  Expecting( T_pts );
3174 
3175  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3176  {
3177  corners.push_back( parseXY() );
3178  }
3179 
3180  NeedRIGHT();
3181 
3182  // Remark: The first polygon is the main outline.
3183  // Others are holes inside the main outline.
3184  zone->AddPolygon( corners );
3185  }
3186  break;
3187 
3188  case T_filled_polygon:
3189  {
3190  // "(filled_polygon (pts"
3191  NeedLEFT();
3192  token = NextTok();
3193 
3194  if( token != T_pts )
3195  Expecting( T_pts );
3196 
3197  pts.NewOutline();
3198 
3199  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3200  {
3201  pts.Append( parseXY() );
3202  }
3203 
3204  NeedRIGHT();
3205  }
3206  break;
3207 
3208  case T_fill_segments:
3209  {
3210  ZONE_SEGMENT_FILL segs;
3211 
3212  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3213  {
3214  if( token != T_LEFT )
3215  Expecting( T_LEFT );
3216 
3217  token = NextTok();
3218 
3219  if( token != T_pts )
3220  Expecting( T_pts );
3221 
3222  SEG segment( parseXY(), parseXY() );
3223  NeedRIGHT();
3224  segs.push_back( segment );
3225  }
3226 
3227  zone->SetFillSegments( segs );
3228  }
3229  break;
3230 
3231  default:
3232  Expecting( "net, layer/layers, tstamp, hatch, priority, connect_pads, min_thickness, "
3233  "fill, polygon, filled_polygon, or fill_segments" );
3234  }
3235  }
3236 
3237  if( zone->GetNumCorners() > 2 )
3238  {
3239  if( !zone->IsOnCopperLayer() )
3240  {
3241  zone->SetFillMode( ZFM_POLYGONS );
3242  zone->SetNetCode( NETINFO_LIST::UNCONNECTED );
3243  }
3244 
3245  // Set hatch here, after outlines corners are read
3246  zone->SetHatch( hatchStyle, hatchPitch, true );
3247  }
3248 
3249  if( !pts.IsEmpty() )
3250  zone->SetFilledPolysList( pts );
3251 
3252  // Ensure keepout and non copper zones do not have a net
3253  // (which have no sense for these zones)
3254  // the netcode 0 is used for these zones
3255  bool zone_has_net = zone->IsOnCopperLayer() && !zone->GetIsKeepout();
3256 
3257  if( !zone_has_net )
3258  zone->SetNetCode( NETINFO_LIST::UNCONNECTED );
3259 
3260  // Ensure the zone net name is valid, and matches the net code, for copper zones
3261  if( zone_has_net && ( zone->GetNet()->GetNetname() != netnameFromfile ) )
3262  {
3263  // Can happens which old boards, with nonexistent nets ...
3264  // or after being edited by hand
3265  // We try to fix the mismatch.
3266  NETINFO_ITEM* net = m_board->FindNet( netnameFromfile );
3267 
3268  if( net ) // An existing net has the same net name. use it for the zone
3269  zone->SetNetCode( net->GetNet() );
3270  else // Not existing net: add a new net to keep trace of the zone netname
3271  {
3272  int newnetcode = m_board->GetNetCount();
3273  net = new NETINFO_ITEM( m_board, netnameFromfile, newnetcode );
3274  m_board->Add( net );
3275 
3276  // Store the new code mapping
3277  pushValueIntoMap( newnetcode, net->GetNet() );
3278  // and update the zone netcode
3279  zone->SetNetCode( net->GetNet() );
3280 
3281  // FIXME: a call to any GUI item is not allowed in io plugins:
3282  // Change this code to generate a warning message outside this plugin
3283  // Prompt the user
3284  wxString msg;
3285  msg.Printf( _( "There is a zone that belongs to a not existing net\n"
3286  "\"%s\"\n"
3287  "you should verify and edit it (run DRC test)." ),
3288  GetChars( netnameFromfile ) );
3289  DisplayError( NULL, msg );
3290  }
3291  }
3292 
3293  return zone.release();
3294 }
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:59
std::vector< SEG > ZONE_SEGMENT_FILL
Definition: class_zone.h:49
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:228
Pads are not covered.
Definition: zones.h:52
Class SHAPE_POLY_SET.
void SetNetCode(int aNetCode)
Definition: netinfo.h:233
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.
#define THROW_IO_ERROR(msg)
HATCH_STYLE
Zone hatch styles.
Definition: class_zone.h:66
int GetNet() const
Function GetNet.
Definition: netinfo.h:231
int NewOutline()
Creates a new empty polygon in the set and returns its index
Thermal relief only for THT pads.
Definition: zones.h:55
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:80
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:263
int parseInt()
Definition: pcb_parser.h:252
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:245
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
Definition: netinfo.h:469
unsigned GetNetCount() const
Function GetNetCount.
Definition: class_board.h:785
pads are covered by copper
Definition: zones.h:54
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:74
void PCB_PARSER::SetBoard ( BOARD aBoard)
inline

Definition at line 301 of file pcb_parser.h.

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

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

302  {
303  init();
304  m_board = aBoard;
305  }
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 294 of file pcb_parser.h.

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

295  {
296  LINE_READER* ret = PopReader();
297  PushReader( aReader );
298  return ret;
299  }
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 74 of file pcb_parser.h.

int PCB_PARSER::m_requiredVersion
private

set to the KiCad format version this board requires

Definition at line 76 of file pcb_parser.h.

bool PCB_PARSER::m_tooRecent
private

true if version parses as later than supported

Definition at line 75 of file pcb_parser.h.

Referenced by IsTooRecent().

std::set<wxString> PCB_PARSER::m_undefinedLayers
private

set of layers not defined in layers section

Definition at line 73 of file pcb_parser.h.


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