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 createOldLayerMapping (std::unordered_map< std::string, std::string > &aMap)
 Creates a mapping from the (short-lived) bug where layer names were translated TODO: Remove this once we support custom 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...
 
bool m_showLegacyZoneWarning
 

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

◆ LAYER_ID_MAP

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

Definition at line 67 of file pcb_parser.h.

◆ LSET_MAP

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::PCB_PARSER ( LINE_READER aReader = NULL)
inline

Definition at line 303 of file pcb_parser.h.

303  :
304  PCB_LEXER( aReader ),
305  m_board( 0 )
306  {
307  init();
308  }
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:57

References init().

Member Function Documentation

◆ createOldLayerMapping()

void PCB_PARSER::createOldLayerMapping ( std::unordered_map< std::string, std::string > &  aMap)
private

Creates a mapping from the (short-lived) bug where layer names were translated TODO: Remove this once we support custom layer names.

Parameters
aMapstring mapping from translated to English layer names

Definition at line 930 of file pcb_parser.cpp.

931 {
932  // N.B. This mapping only includes Italian, Polish and French as they were the only languages that
933  // mapped the layer names as of cc2022b1ac739aa673d2a0b7a2047638aa7a47b3 (kicad-i18n) when the
934  // bug was fixed in KiCad source.
935 
936  // Italian
937  aMap["Adesivo.Retro"] = "B.Adhes";
938  aMap["Adesivo.Fronte"] = "F.Adhes";
939  aMap["Pasta.Retro"] = "B.Paste";
940  aMap["Pasta.Fronte"] = "F.Paste";
941  aMap["Serigrafia.Retro"] = "B.SilkS";
942  aMap["Serigrafia.Fronte"] = "F.SilkS";
943  aMap["Maschera.Retro"] = "B.Mask";
944  aMap["Maschera.Fronte"] = "F.Mask";
945  aMap["Grafica"] = "Dwgs.User";
946  aMap["Commenti"] = "Cmts.User";
947  aMap["Eco1"] = "Eco1.User";
948  aMap["Eco2"] = "Eco2.User";
949  aMap["Contorno.scheda"] = "Edge.Cuts";
950 
951  // Polish
952  aMap["Kleju_Dolna"] = "B.Adhes";
953  aMap["Kleju_Gorna"] = "F.Adhes";
954  aMap["Pasty_Dolna"] = "B.Paste";
955  aMap["Pasty_Gorna"] = "F.Paste";
956  aMap["Opisowa_Dolna"] = "B.SilkS";
957  aMap["Opisowa_Gorna"] = "F.SilkS";
958  aMap["Maski_Dolna"] = "B.Mask";
959  aMap["Maski_Gorna"] = "F.Mask";
960  aMap["Rysunkowa"] = "Dwgs.User";
961  aMap["Komentarzy"] = "Cmts.User";
962  aMap["ECO1"] = "Eco1.User";
963  aMap["ECO2"] = "Eco2.User";
964  aMap["Krawedziowa"] = "Edge.Cuts";
965 
966  // French
967  aMap["Dessous.Adhes"] = "B.Adhes";
968  aMap["Dessus.Adhes"] = "F.Adhes";
969  aMap["Dessous.Pate"] = "B.Paste";
970  aMap["Dessus.Pate"] = "F.Paste";
971  aMap["Dessous.SilkS"] = "B.SilkS";
972  aMap["Dessus.SilkS"] = "F.SilkS";
973  aMap["Dessous.Masque"] = "B.Mask";
974  aMap["Dessus.Masque"] = "F.Mask";
975  aMap["Dessin.User"] = "Dwgs.User";
976  aMap["Contours.Ci"] = "Edge.Cuts";
977 }

◆ getNetCode()

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 82 of file pcb_parser.h.

83  {
84  if( ( aNetCode >= 0 ) && ( aNetCode < (int) m_netCodes.size() ) )
85  return m_netCodes[aNetCode];
86 
87  return aNetCode;
88  }
std::vector< int > m_netCodes
net codes mapping for boards being loaded
Definition: pcb_parser.h:74

References m_netCodes.

◆ GetRequiredVersion()

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 184 of file pcb_parser.cpp.

185 {
186  int year, month, day;
187 
188  year = m_requiredVersion / 10000;
189  month = ( m_requiredVersion / 100 ) - ( year * 100 );
190  day = m_requiredVersion - ( year * 10000 ) - ( month * 100 );
191 
192  // wx throws an assertion, not a catchable exception, when the date is invalid.
193  // User input shouldn't give wx asserts, so check manually and throw a proper
194  // error instead
195  if( day <= 0 || month <= 0 || month > 12 ||
196  day > wxDateTime::GetNumberOfDays( (wxDateTime::Month)( month - 1 ), year ) )
197  {
198  wxString err;
199  err.Printf( _( "Cannot interpret date code %d" ), m_requiredVersion );
200  THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
201  }
202 
203  wxDateTime date( day, (wxDateTime::Month)( month - 1 ), year, 0, 0, 0, 0 );
204  return date.FormatDate();
205 }
#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

References err, and THROW_PARSE_ERROR.

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

◆ init()

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 57 of file pcb_parser.cpp.

58 {
60  m_tooRecent = false;
62  m_layerIndices.clear();
63  m_layerMasks.clear();
64 
65  // Add untranslated default (i.e. english) layernames.
66  // Some may be overridden later if parsing a board rather than a footprint.
67  // The english name will survive if parsing only a footprint.
68  for( LAYER_NUM layer = 0; layer < PCB_LAYER_ID_COUNT; ++layer )
69  {
70  std::string untranslated = TO_UTF8( wxString( LSET::Name( PCB_LAYER_ID( layer ) ) ) );
71 
72  m_layerIndices[ untranslated ] = PCB_LAYER_ID( layer );
73  m_layerMasks[ untranslated ] = LSET( PCB_LAYER_ID( layer ) );
74  }
75 
76  m_layerMasks[ "*.Cu" ] = LSET::AllCuMask();
77  m_layerMasks[ "F&B.Cu" ] = LSET( 2, F_Cu, B_Cu );
78  m_layerMasks[ "*.Adhes" ] = LSET( 2, B_Adhes, F_Adhes );
79  m_layerMasks[ "*.Paste" ] = LSET( 2, B_Paste, F_Paste );
80  m_layerMasks[ "*.Mask" ] = LSET( 2, B_Mask, F_Mask );
81  m_layerMasks[ "*.SilkS" ] = LSET( 2, B_SilkS, F_SilkS );
82  m_layerMasks[ "*.Fab" ] = LSET( 2, B_Fab, F_Fab );
83  m_layerMasks[ "*.CrtYd" ] = LSET( 2, B_CrtYd, F_CrtYd );
84 
85  // This is for the first pretty & *.kicad_pcb formats, which had
86  // Inner1_Cu - Inner14_Cu with the numbering sequence
87  // reversed from the subsequent format's In1_Cu - In30_Cu numbering scheme.
88  // The newer format brought in an additional 16 Cu layers and flipped the cu stack but
89  // kept the gap between one of the outside layers and the last cu internal.
90 
91  for( int i=1; i<=14; ++i )
92  {
93  std::string key = StrPrintf( "Inner%d.Cu", i );
94 
95  m_layerMasks[ key ] = LSET( PCB_LAYER_ID( In15_Cu - i ) );
96  }
97 
98 #if defined(DEBUG) && 0
99  printf( "m_layerMasks:\n" );
100  for( LSET_MAP::const_iterator it = m_layerMasks.begin(); it != m_layerMasks.end(); ++it )
101  {
102  printf( " [%s] == 0x%s\n", it->first.c_str(), it->second.FmtHex().c_str() );
103  }
104 
105  printf( "m_layerIndices:\n" );
106  for( LAYER_ID_MAP::const_iterator it = m_layerIndices.begin(); it != m_layerIndices.end(); ++it )
107  {
108  printf( " [%s] == %d\n", it->first.c_str(), it->second );
109  }
110 #endif
111 
112 }
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
bool m_showLegacyZoneWarning
Definition: pcb_parser.h:78
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's index
Definition: pcb_parser.h:71
LSET_MAP m_layerMasks
map layer names to their masks
Definition: pcb_parser.h:72

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 PCB_PARSER(), and SetBoard().

◆ IsTooRecent()

bool PCB_PARSER::IsTooRecent ( )
inline

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

Definition at line 343 of file pcb_parser.h.

344  {
345  return m_tooRecent;
346  }
bool m_tooRecent
true if version parses as later than supported
Definition: pcb_parser.h:75

References m_tooRecent.

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

◆ lookUpLayer()

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 1107 of file pcb_parser.cpp.

1108 {
1109  // avoid constructing another std::string, use lexer's directly
1110  typename M::const_iterator it = aMap.find( curText );
1111 
1112  if( it == aMap.end() )
1113  {
1114 #if 0 && defined(DEBUG)
1115  // dump the whole darn table, there's something wrong with it.
1116  for( it = aMap.begin(); it != aMap.end(); ++it )
1117  {
1118  wxLogDebug( &aMap == (void*)&m_layerIndices ? wxT( "lm[%s] = %d" ) :
1119  wxT( "lm[%s] = %08X" ), it->first.c_str(), it->second );
1120  }
1121 #endif
1122 
1123  m_undefinedLayers.insert( curText );
1124  return Rescue;
1125  }
1126 
1127  return it->second;
1128 }
LAYER_ID_MAP m_layerIndices
map layer name to it'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

References Rescue.

◆ Parse()

BOARD_ITEM * PCB_PARSER::Parse ( )

Definition at line 444 of file pcb_parser.cpp.

445 {
446  T token;
447  BOARD_ITEM* item;
448  LOCALE_IO toggle;
449 
450  // MODULEs can be prefixed with an initial block of single line comments and these
451  // are kept for Format() so they round trip in s-expression form. BOARDs might
452  // eventually do the same, but currently do not.
453  std::unique_ptr<wxArrayString> initial_comments( ReadCommentLines() );
454 
455  token = CurTok();
456 
457  if( token != T_LEFT )
458  Expecting( T_LEFT );
459 
460  switch( NextTok() )
461  {
462  case T_kicad_pcb:
463  if( m_board == NULL )
464  m_board = new BOARD();
465 
466  item = (BOARD_ITEM*) parseBOARD();
467  break;
468 
469  case T_module:
470  item = (BOARD_ITEM*) parseMODULE( initial_comments.release() );
471  break;
472 
473  default:
474  wxString err;
475  err.Printf( _( "Unknown token \"%s\"" ), GetChars( FromUTF8() ) );
476  THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
477  }
478 
479  return item;
480 }
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: common.h:177
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:483
#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:100
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:170
BOARD * m_board
Definition: pcb_parser.h:70
MODULE * parseMODULE(wxArrayString *aInitialComments=0)
Function parseMODULE.

References err, GetChars(), and THROW_PARSE_ERROR.

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

◆ parse3DModel()

MODULE_3D_SETTINGS * PCB_PARSER::parse3DModel ( )
private

Definition at line 352 of file pcb_parser.cpp.

353 {
354  wxCHECK_MSG( CurTok() == T_model, NULL,
355  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as MODULE_3D_SETTINGS." ) );
356 
357  T token;
358 
360  NeedSYMBOLorNUMBER();
361  n3D->m_Filename = FromUTF8();
362 
363  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
364  {
365  if( token != T_LEFT )
366  Expecting( T_LEFT );
367 
368  token = NextTok();
369 
370  switch( token )
371  {
372  case T_at:
373  NeedLEFT();
374  token = NextTok();
375 
376  if( token != T_xyz )
377  Expecting( T_xyz );
378 
379  /* Note:
380  * Prior to KiCad v5, model offset was designated by "at",
381  * and the units were in inches.
382  * Now we use mm, but support reading of legacy files
383  */
384 
385  n3D->m_Offset.x = parseDouble( "x value" ) * 25.4f;
386  n3D->m_Offset.y = parseDouble( "y value" ) * 25.4f;
387  n3D->m_Offset.z = parseDouble( "z value" ) * 25.4f;
388  NeedRIGHT();
389  break;
390 
391  case T_offset:
392  NeedLEFT();
393  token = NextTok();
394 
395  if( token != T_xyz )
396  Expecting( T_xyz );
397 
398  /*
399  * 3D model offset is in mm
400  */
401  n3D->m_Offset.x = parseDouble( "x value" );
402  n3D->m_Offset.y = parseDouble( "y value" );
403  n3D->m_Offset.z = parseDouble( "z value" );
404  NeedRIGHT();
405  break;
406 
407  case T_scale:
408  NeedLEFT();
409  token = NextTok();
410 
411  if( token != T_xyz )
412  Expecting( T_xyz );
413 
414  n3D->m_Scale.x = parseDouble( "x value" );
415  n3D->m_Scale.y = parseDouble( "y value" );
416  n3D->m_Scale.z = parseDouble( "z value" );
417  NeedRIGHT();
418  break;
419 
420  case T_rotate:
421  NeedLEFT();
422  token = NextTok();
423 
424  if( token != T_xyz )
425  Expecting( T_xyz );
426 
427  n3D->m_Rotation.x = parseDouble( "x value" );
428  n3D->m_Rotation.y = parseDouble( "y value" );
429  n3D->m_Rotation.z = parseDouble( "z value" );
430  NeedRIGHT();
431  break;
432 
433  default:
434  Expecting( "at, offset, scale, or rotate" );
435  }
436 
437  NeedRIGHT();
438  }
439 
440  return n3D;
441 }
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:126

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.

◆ parseBOARD()

BOARD * PCB_PARSER::parseBOARD ( )
private

Definition at line 483 of file pcb_parser.cpp.

484 {
485  try
486  {
487  return parseBOARD_unchecked();
488  }
489  catch( const PARSE_ERROR& parse_error )
490  {
491  if( m_tooRecent )
492  throw FUTURE_FORMAT_ERROR( parse_error, GetRequiredVersion() );
493  else
494  throw;
495  }
496 }
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:184
BOARD * parseBOARD_unchecked()
Function parseBOARD_unchecked Parse a module, but do not replace PARSE_ERROR with FUTURE_FORMAT_ERROR...
Definition: pcb_parser.cpp:499
Struct PARSE_ERROR contains a filename or source description, a problem input line,...
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

◆ parseBOARD_unchecked()

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 499 of file pcb_parser.cpp.

500 {
501  T token;
502 
503  parseHeader();
504 
505  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
506  {
507  if( token != T_LEFT )
508  Expecting( T_LEFT );
509 
510  token = NextTok();
511 
512  switch( token )
513  {
514  case T_general:
516  break;
517 
518  case T_page:
519  parsePAGE_INFO();
520  break;
521 
522  case T_title_block:
524  break;
525 
526  case T_layers:
527  parseLayers();
528  break;
529 
530  case T_setup:
531  parseSetup();
532  break;
533 
534  case T_net:
536  break;
537 
538  case T_net_class:
539  parseNETCLASS();
540  break;
541 
542  case T_gr_arc:
543  case T_gr_circle:
544  case T_gr_curve:
545  case T_gr_line:
546  case T_gr_poly:
548  break;
549 
550  case T_gr_text:
552  break;
553 
554  case T_dimension:
556  break;
557 
558  case T_module:
560  break;
561 
562  case T_segment:
564  break;
565 
566  case T_via:
568  break;
569 
570  case T_zone:
572  break;
573 
574  case T_target:
576  break;
577 
578  default:
579  wxString err;
580  err.Printf( _( "Unknown token \"%s\"" ), GetChars( FromUTF8() ) );
581  THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
582  }
583  }
584 
585  if( m_undefinedLayers.size() > 0 )
586  {
587  bool deleteItems;
588  std::vector<BOARD_ITEM*> deleteList;
589  wxString msg = wxString::Format( _( "Items found on undefined layers. Do you wish to\n"
590  "rescue them to the Cmts.User layer?" ) );
591  wxString details = wxString::Format( _( "Undefined layers:" ) );
592 
593  for( const wxString& undefinedLayer : m_undefinedLayers )
594  details += wxT( "\n " ) + undefinedLayer;
595 
596  wxRichMessageDialog dlg( nullptr, msg, _( "Warning" ),
597  wxYES_NO | wxCANCEL | wxCENTRE | wxICON_WARNING | wxSTAY_ON_TOP );
598  dlg.ShowDetailedText( details );
599  dlg.SetYesNoCancelLabels( _( "Rescue" ), _( "Delete" ), _( "Cancel" ) );
600 
601  switch( dlg.ShowModal() )
602  {
603  case wxID_YES: deleteItems = false; break;
604  case wxID_NO: deleteItems = true; break;
605  case wxID_CANCEL:
606  default: THROW_IO_ERROR( wxT( "CANCEL" ) );
607  }
608 
609  auto visitItem = [&]( BOARD_ITEM* item )
610  {
611  if( item->GetLayer() == Rescue )
612  {
613  if( deleteItems )
614  deleteList.push_back( item );
615  else
616  item->SetLayer( Cmts_User );
617  }
618  };
619 
620  for( TRACK* segm = m_board->m_Track; segm; segm = segm->Next() )
621  {
622  if( segm->Type() == PCB_VIA_T )
623  {
624  VIA* via = (VIA*) segm;
625  PCB_LAYER_ID top_layer, bottom_layer;
626 
627  if( via->GetViaType() == VIA_THROUGH )
628  continue;
629 
630  via->LayerPair( &top_layer, &bottom_layer );
631 
632  if( top_layer == Rescue || bottom_layer == Rescue )
633  {
634  if( deleteItems )
635  deleteList.push_back( via );
636  else
637  {
638  if( top_layer == Rescue )
639  top_layer = F_Cu;
640 
641  if( bottom_layer == Rescue )
642  bottom_layer = B_Cu;
643 
644  via->SetLayerPair( top_layer, bottom_layer );
645  }
646  }
647  }
648  else
649  visitItem( segm );
650  }
651 
652  for( BOARD_ITEM* zone : m_board->Zones() )
653  visitItem( zone );
654 
655  for( BOARD_ITEM* drawing : m_board->Drawings() )
656  visitItem( drawing );
657 
658  for( BOARD_ITEM* item : deleteList )
659  m_board->Delete( item );
660 
661  m_undefinedLayers.clear();
662  }
663 
664  return m_board;
665 }
void parseHeader()
Definition: pcb_parser.cpp:668
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...
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:806
void parseLayers()
Definition: pcb_parser.cpp:980
void parsePAGE_INFO()
Definition: pcb_parser.cpp:750
PCB_LAYER_ID
A quick note on layer IDs:
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_INSERT) override
Adds an item to the container.
PCB_TARGET * parsePCB_TARGET()
VIATYPE_T GetViaType() const
Definition: class_track.h:437
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
ZONE_CONTAINER * parseZONE_CONTAINER()
ZONE_CONTAINERS & Zones()
Definition: class_board.h:254
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:100
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:704
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:249
MODULE * parseMODULE(wxArrayString *aInitialComments=0)
Function parseMODULE.
void parseSetup()
DLIST_ITERATOR_WRAPPER< BOARD_ITEM > Drawings()
Definition: class_board.h:253
std::set< wxString > m_undefinedLayers
set of layers not defined in layers section
Definition: pcb_parser.h:73

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.

◆ parseBoardItemLayer()

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 1131 of file pcb_parser.cpp.

1132 {
1133  wxCHECK_MSG( CurTok() == T_layer, UNDEFINED_LAYER,
1134  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as layer." ) );
1135 
1136  NextTok();
1137 
1138  PCB_LAYER_ID layerIndex = lookUpLayer<PCB_LAYER_ID>( m_layerIndices );
1139 
1140  // Handle closing ) in object parser.
1141 
1142  return layerIndex;
1143 }
PCB_LAYER_ID
A quick note on layer IDs:
LAYER_ID_MAP m_layerIndices
map layer name to it's index
Definition: pcb_parser.h:71

References UNDEFINED_LAYER.

◆ parseBoardItemLayersAsMask()

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 1146 of file pcb_parser.cpp.

1147 {
1148  wxCHECK_MSG( CurTok() == T_layers, LSET(),
1149  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
1150  wxT( " as item layer mask." ) );
1151 
1152  LSET layerMask;
1153 
1154  for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
1155  {
1156  LSET mask = lookUpLayer<LSET>( m_layerMasks );
1157  layerMask |= mask;
1158  }
1159 
1160  return layerMask;
1161 }
Class LSET is a set of PCB_LAYER_IDs.
LSET_MAP m_layerMasks
map layer names to their masks
Definition: pcb_parser.h:72

◆ parseBoardUnits() [1/3]

int PCB_PARSER::parseBoardUnits ( )
inlineprivate

Definition at line 238 of file pcb_parser.h.

239  {
240  // There should be no major rounding issues here, since the values in
241  // the file are in mm and get converted to nano-meters.
242  // See test program tools/test-nm-biu-to-ascii-mm-round-tripping.cpp
243  // to confirm or experiment. Use a similar strategy in both places, here
244  // and in the test program. Make that program with:
245  // $ make test-nm-biu-to-ascii-mm-round-tripping
246  auto retval = parseDouble() * IU_PER_MM;
247 
248  // N.B. we currently represent board units as integers. Any values that are
249  // larger or smaller than those board units represent undefined behavior for
250  // the system. We limit values to the largest that is visible on the screen
251  // This is the diagonal distance of the full screen ~1.5m
252  double int_limit = std::numeric_limits<int>::max() * 0.7071; // 0.7071 = roughly 1/sqrt(2)
253  return KiROUND( Clamp<double>( -int_limit, retval, int_limit ) );
254  }
static int KiROUND(double v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:118
#define max(a, b)
Definition: auxiliary.h:86
double parseDouble()
Function parseDouble parses the current token as an ASCII numeric string with possible leading whites...
Definition: pcb_parser.cpp:126

References KiROUND(), max, and parseDouble().

Referenced by parseBoardUnits().

◆ parseBoardUnits() [2/3]

int PCB_PARSER::parseBoardUnits ( const char *  aExpected)
inlineprivate

Definition at line 256 of file pcb_parser.h.

257  {
258  auto retval = parseDouble( aExpected ) * IU_PER_MM;
259 
260  // N.B. we currently represent board units as integers. Any values that are
261  // larger or smaller than those board units represent undefined behavior for
262  // the system. We limit values to the largest that is visible on the screen
263  double int_limit = std::numeric_limits<int>::max() * 0.7071;
264 
265  // Use here KiROUND, not KIROUND (see comments about them)
266  // when having a function as argument, because it will be called twice
267  // with KIROUND
268  return KiROUND( Clamp<double>( -int_limit, retval, int_limit ) );
269  }
static int KiROUND(double v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:118
#define max(a, b)
Definition: auxiliary.h:86
double parseDouble()
Function parseDouble parses the current token as an ASCII numeric string with possible leading whites...
Definition: pcb_parser.cpp:126

References KiROUND(), max, and parseDouble().

◆ parseBoardUnits() [3/3]

int PCB_PARSER::parseBoardUnits ( PCB_KEYS_T::T  aToken)
inlineprivate

Definition at line 271 of file pcb_parser.h.

272  {
273  return parseBoardUnits( GetTokenText( aToken ) );
274  }
int parseBoardUnits()
Definition: pcb_parser.h:238
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

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

◆ parseBool()

bool PCB_PARSER::parseBool ( )
private

Definition at line 156 of file pcb_parser.cpp.

157 {
158  T token = NextTok();
159 
160  if( token == T_yes )
161  return true;
162  else if( token == T_no )
163  return false;
164  else
165  Expecting( "yes or no" );
166 
167  return false;
168 }

◆ parseD_PAD()

D_PAD * PCB_PARSER::parseD_PAD ( MODULE aParent = NULL)
private

Definition at line 2454 of file pcb_parser.cpp.

2455 {
2456  wxCHECK_MSG( CurTok() == T_pad, NULL,
2457  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as D_PAD." ) );
2458 
2459  wxSize sz;
2460  wxPoint pt;
2461 
2462  std::unique_ptr< D_PAD > pad( new D_PAD( aParent ) );
2463 
2464  NeedSYMBOLorNUMBER();
2465  pad->SetName( FromUTF8() );
2466 
2467  T token = NextTok();
2468 
2469  switch( token )
2470  {
2471  case T_thru_hole:
2472  pad->SetAttribute( PAD_ATTRIB_STANDARD );
2473  break;
2474 
2475  case T_smd:
2476  pad->SetAttribute( PAD_ATTRIB_SMD );
2477 
2478  // Default D_PAD object is thru hole with drill.
2479  // SMD pads have no hole
2480  pad->SetDrillSize( wxSize( 0, 0 ) );
2481  break;
2482 
2483  case T_connect:
2484  pad->SetAttribute( PAD_ATTRIB_CONN );
2485 
2486  // Default D_PAD object is thru hole with drill.
2487  // CONN pads have no hole
2488  pad->SetDrillSize( wxSize( 0, 0 ) );
2489  break;
2490 
2491  case T_np_thru_hole:
2492  pad->SetAttribute( PAD_ATTRIB_HOLE_NOT_PLATED );
2493  break;
2494 
2495  default:
2496  Expecting( "thru_hole, smd, connect, or np_thru_hole" );
2497  }
2498 
2499  token = NextTok();
2500 
2501  switch( token )
2502  {
2503  case T_circle:
2504  pad->SetShape( PAD_SHAPE_CIRCLE );
2505  break;
2506 
2507  case T_rect:
2508  pad->SetShape( PAD_SHAPE_RECT );
2509  break;
2510 
2511  case T_oval:
2512  pad->SetShape( PAD_SHAPE_OVAL );
2513  break;
2514 
2515  case T_trapezoid:
2516  pad->SetShape( PAD_SHAPE_TRAPEZOID );
2517  break;
2518 
2519  case T_roundrect:
2520  // Note: the shape can be PAD_SHAPE_ROUNDRECT or PAD_SHAPE_CHAMFERED_RECT
2521  // (if champfer parameters are found later in pad descr.)
2522  pad->SetShape( PAD_SHAPE_ROUNDRECT );
2523  break;
2524 
2525  case T_custom:
2526  pad->SetShape( PAD_SHAPE_CUSTOM );
2527  break;
2528 
2529  default:
2530  Expecting( "circle, rectangle, roundrect, oval, trapezoid or custom" );
2531  }
2532 
2533  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2534  {
2535  if( token != T_LEFT )
2536  Expecting( T_LEFT );
2537 
2538  token = NextTok();
2539 
2540  switch( token )
2541  {
2542  case T_size:
2543  sz.SetWidth( parseBoardUnits( "width value" ) );
2544  sz.SetHeight( parseBoardUnits( "height value" ) );
2545  pad->SetSize( sz );
2546  NeedRIGHT();
2547  break;
2548 
2549  case T_at:
2550  pt.x = parseBoardUnits( "X coordinate" );
2551  pt.y = parseBoardUnits( "Y coordinate" );
2552  pad->SetPos0( pt );
2553  token = NextTok();
2554 
2555  if( token == T_NUMBER )
2556  {
2557  pad->SetOrientation( parseDouble() * 10.0 );
2558  NeedRIGHT();
2559  }
2560  else if( token != T_RIGHT )
2561  {
2562  Expecting( ") or angle value" );
2563  }
2564 
2565  break;
2566 
2567  case T_rect_delta:
2568  {
2569  wxSize delta;
2570  delta.SetWidth( parseBoardUnits( "rectangle delta width" ) );
2571  delta.SetHeight( parseBoardUnits( "rectangle delta height" ) );
2572  pad->SetDelta( delta );
2573  NeedRIGHT();
2574  }
2575  break;
2576 
2577  case T_drill:
2578  {
2579  bool haveWidth = false;
2580  wxSize drillSize = pad->GetDrillSize();
2581 
2582  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2583  {
2584  if( token == T_LEFT )
2585  token = NextTok();
2586 
2587  switch( token )
2588  {
2589  case T_oval:
2590  pad->SetDrillShape( PAD_DRILL_SHAPE_OBLONG );
2591  break;
2592 
2593  case T_NUMBER:
2594  {
2595  if( !haveWidth )
2596  {
2597  drillSize.SetWidth( parseBoardUnits() );
2598 
2599  // If height is not defined the width and height are the same.
2600  drillSize.SetHeight( drillSize.GetWidth() );
2601  haveWidth = true;
2602  }
2603  else
2604  {
2605  drillSize.SetHeight( parseBoardUnits() );
2606  }
2607 
2608  }
2609  break;
2610 
2611  case T_offset:
2612  pt.x = parseBoardUnits( "drill offset x" );
2613  pt.y = parseBoardUnits( "drill offset y" );
2614  pad->SetOffset( pt );
2615  NeedRIGHT();
2616  break;
2617 
2618  default:
2619  Expecting( "oval, size, or offset" );
2620  }
2621  }
2622 
2623  // This fixes a bug caused by setting the default D_PAD drill size to a value
2624  // other than 0 used to fix a bunch of debug assertions even though it is defined
2625  // as a through hole pad. Wouldn't a though hole pad with no drill be a surface
2626  // mount pad (or a conn pad which is a smd pad with no solder paste)?
2627  if( ( pad->GetAttribute() != PAD_ATTRIB_SMD ) && ( pad->GetAttribute() != PAD_ATTRIB_CONN ) )
2628  pad->SetDrillSize( drillSize );
2629  else
2630  pad->SetDrillSize( wxSize( 0, 0 ) );
2631 
2632  }
2633  break;
2634 
2635  case T_layers:
2636  {
2637  LSET layerMask = parseBoardItemLayersAsMask();
2638  pad->SetLayerSet( layerMask );
2639  }
2640  break;
2641 
2642  case T_net:
2643  if( ! pad->SetNetCode( getNetCode( parseInt( "net number" ) ), /* aNoAssert */ true ) )
2645  wxString::Format( _( "Invalid net ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),
2646  GetChars( CurSource() ), CurLineNumber(), CurOffset() )
2647  );
2648  NeedSYMBOLorNUMBER();
2649  if( m_board && FromUTF8() != m_board->FindNet( pad->GetNetCode() )->GetNetname() )
2651  wxString::Format( _( "Invalid net ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),
2652  GetChars( CurSource() ), CurLineNumber(), CurOffset() )
2653  );
2654  NeedRIGHT();
2655  break;
2656 
2657  case T_die_length:
2658  pad->SetPadToDieLength( parseBoardUnits( T_die_length ) );
2659  NeedRIGHT();
2660  break;
2661 
2662  case T_solder_mask_margin:
2663  pad->SetLocalSolderMaskMargin( parseBoardUnits( T_solder_mask_margin ) );
2664  NeedRIGHT();
2665  break;
2666 
2667  case T_solder_paste_margin:
2668  pad->SetLocalSolderPasteMargin( parseBoardUnits( T_solder_paste_margin ) );
2669  NeedRIGHT();
2670  break;
2671 
2672  case T_solder_paste_margin_ratio:
2673  pad->SetLocalSolderPasteMarginRatio(
2674  parseDouble( "pad local solder paste margin ratio value" ) );
2675  NeedRIGHT();
2676  break;
2677 
2678  case T_clearance:
2679  pad->SetLocalClearance( parseBoardUnits( "local clearance value" ) );
2680  NeedRIGHT();
2681  break;
2682 
2683  case T_zone_connect:
2684  pad->SetZoneConnection( (ZoneConnection) parseInt( "zone connection value" ) );
2685  NeedRIGHT();
2686  break;
2687 
2688  case T_thermal_width:
2689  pad->SetThermalWidth( parseBoardUnits( T_thermal_width ) );
2690  NeedRIGHT();
2691  break;
2692 
2693  case T_thermal_gap:
2694  pad->SetThermalGap( parseBoardUnits( T_thermal_gap ) );
2695  NeedRIGHT();
2696  break;
2697 
2698  case T_roundrect_rratio:
2699  pad->SetRoundRectRadiusRatio( parseDouble( "roundrect radius ratio" ) );
2700  NeedRIGHT();
2701  break;
2702 
2703  case T_chamfer_ratio:
2704  pad->SetChamferRectRatio( parseDouble( "chamfer ratio" ) );
2705 
2706  if( pad->GetChamferRectRatio() > 0 )
2707  pad->SetShape( PAD_SHAPE_CHAMFERED_RECT );
2708 
2709  NeedRIGHT();
2710  break;
2711 
2712  case T_chamfer:
2713  {
2714  int chamfers = 0;
2715  bool end_list = false;
2716 
2717  while( !end_list )
2718  {
2719  token = NextTok();
2720  switch( token )
2721  {
2722  case T_top_left:
2723  chamfers |= RECT_CHAMFER_TOP_LEFT;
2724  break;
2725 
2726  case T_top_right:
2727  chamfers |= RECT_CHAMFER_TOP_RIGHT;
2728  break;
2729 
2730  case T_bottom_left:
2731  chamfers |= RECT_CHAMFER_BOTTOM_LEFT;
2732  break;
2733 
2734  case T_bottom_right:
2735  chamfers |= RECT_CHAMFER_BOTTOM_RIGHT;
2736  break;
2737 
2738  case T_RIGHT:
2739  pad->SetChamferPositions( chamfers );
2740  end_list = true;
2741  break;
2742 
2743  default:
2744  Expecting( "chamfer_top_left chamfer_top_right chamfer_bottom_left or chamfer_bottom_right" );
2745  }
2746  }
2747 
2748  if( pad->GetChamferPositions() != RECT_NO_CHAMFER )
2749  pad->SetShape( PAD_SHAPE_CHAMFERED_RECT );
2750  }
2751  break;
2752 
2753  case T_options:
2754  parseD_PAD_option( pad.get() );
2755  break;
2756 
2757  case T_primitives:
2758  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2759  {
2760  if( token == T_LEFT )
2761  token = NextTok();
2762 
2763  // Currently, I am using parseDRAWSEGMENT() to read basic shapes parameters,
2764  // because they are the same as a DRAWSEGMENT.
2765  // However it could be better to write a specific parser, to avoid possible issues
2766  // if the DRAWSEGMENT parser is modified.
2767  DRAWSEGMENT* dummysegm = NULL;
2768 
2769  switch( token )
2770  {
2771  case T_gr_arc:
2772  dummysegm = parseDRAWSEGMENT();
2773  pad->AddPrimitive( dummysegm->GetCenter(), dummysegm->GetArcStart(),
2774  dummysegm->GetAngle(), dummysegm->GetWidth() );
2775  break;
2776 
2777  case T_gr_line:
2778  dummysegm = parseDRAWSEGMENT();
2779  pad->AddPrimitive( dummysegm->GetStart(), dummysegm->GetEnd(),
2780  dummysegm->GetWidth() );
2781  break;
2782 
2783  case T_gr_circle:
2784  dummysegm = parseDRAWSEGMENT( true ); // Circles with 0 thickness are allowed
2785  // ( filled circles )
2786  pad->AddPrimitive( dummysegm->GetCenter(), dummysegm->GetRadius(),
2787  dummysegm->GetWidth() );
2788  break;
2789 
2790  case T_gr_poly:
2791  dummysegm = parseDRAWSEGMENT();
2792  pad->AddPrimitive( dummysegm->BuildPolyPointsList(), dummysegm->GetWidth() );
2793  break;
2794 
2795  case T_gr_curve:
2796  dummysegm = parseDRAWSEGMENT();
2797  pad->AddPrimitive( dummysegm->GetStart(), dummysegm->GetEnd(),
2798  dummysegm->GetBezControl1(), dummysegm->GetBezControl2(),
2799  dummysegm->GetWidth() );
2800  break;
2801 
2802  default:
2803  Expecting( "gr_line, gr_arc, gr_circle, gr_curve or gr_poly" );
2804  break;
2805  }
2806 
2807  delete dummysegm;
2808  }
2809  break;
2810 
2811  default:
2812  Expecting( "at, drill, layers, net, die_length, solder_mask_margin, roundrect_rratio,\n"
2813  "solder_paste_margin, solder_paste_margin_ratio, clearance,\n"
2814  "zone_connect, fp_poly, primitives, thermal_width, or thermal_gap" );
2815  }
2816  }
2817 
2818  // Be sure the custom shape polygon is built:
2819  if( pad->GetShape() == PAD_SHAPE_CUSTOM )
2820  pad->MergePrimitivesAsPolygon();
2821 
2822  return pad.release();
2823 }
NETINFO_ITEM * FindNet(int aNetcode) const
Function FindNet searches for a net with the given netcode.
DRAWSEGMENT * parseDRAWSEGMENT(bool aAllowCirclesZeroWidth=false)
Read a DRAWSEGMENT description.
LSET parseBoardItemLayersAsMask()
Function parseBoardItemLayersAsMask parses the layers definition of a BOARD_ITEM object.
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:66
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:62
bool parseD_PAD_option(D_PAD *aPad)
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...
const wxPoint & GetEnd() const
Function GetEnd returns the ending point of the graphic.
static const int delta[8][2]
Definition: solve.cpp:112
int parseBoardUnits()
Definition: pcb_parser.h:238
Class LSET is a set of PCB_LAYER_IDs.
const wxPoint & GetArcStart() const
#define THROW_IO_ERROR(msg)
int GetRadius() const
Function GetRadius returns the radius of this item Has meaning only for arc and circle.
Like smd, does not appear on the solder paste layer (default) note also has a special attribute in Ge...
Definition: pad_shapes.h:63
int GetWidth() const
double GetAngle() const
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:100
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:82
BOARD * m_board
Definition: pcb_parser.h:70
const wxPoint & GetBezControl2() const
double parseDouble()
Function parseDouble parses the current token as an ASCII numeric string with possible leading whites...
Definition: pcb_parser.cpp:126
const wxPoint & GetBezControl1() const
const wxPoint & GetStart() const
Function GetStart returns the starting point of the graphic.
int parseInt()
Definition: pcb_parser.h:276

References DRAWSEGMENT::BuildPolyPointsList(), delta, Format(), DRAWSEGMENT::GetAngle(), DRAWSEGMENT::GetArcStart(), DRAWSEGMENT::GetBezControl1(), DRAWSEGMENT::GetBezControl2(), 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_CHAMFERED_RECT, PAD_SHAPE_CIRCLE, PAD_SHAPE_CUSTOM, PAD_SHAPE_OVAL, PAD_SHAPE_RECT, PAD_SHAPE_ROUNDRECT, PAD_SHAPE_TRAPEZOID, parseDouble(), parseInt(), RECT_CHAMFER_BOTTOM_LEFT, RECT_CHAMFER_BOTTOM_RIGHT, RECT_CHAMFER_TOP_LEFT, RECT_CHAMFER_TOP_RIGHT, RECT_NO_CHAMFER, and THROW_IO_ERROR.

◆ parseD_PAD_option()

bool PCB_PARSER::parseD_PAD_option ( D_PAD aPad)
private

Definition at line 2826 of file pcb_parser.cpp.

2827 {
2828  // Parse only the (option ...) inside a pad description
2829  for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
2830  {
2831  if( token != T_LEFT )
2832  Expecting( T_LEFT );
2833 
2834  token = NextTok();
2835 
2836  switch( token )
2837  {
2838  case T_anchor:
2839  token = NextTok();
2840  // Custom shaped pads have a "anchor pad", which is the reference
2841  // for connection calculations.
2842  // Because this is an anchor, only the 2 very basic shapes are managed:
2843  // circle and rect. The default is circle
2844  switch( token )
2845  {
2846  case T_circle: // default
2847  break;
2848 
2849  case T_rect:
2851  break;
2852 
2853  default:
2854  // Currently, because pad options is a moving target
2855  // just skip unknown keywords
2856  break;
2857  }
2858  NeedRIGHT();
2859  break;
2860 
2861  case T_clearance:
2862  token = NextTok();
2863  // Custom shaped pads have a clearance area that is the pad shape
2864  // (like usual pads) or the convew hull of the pad shape.
2865  switch( token )
2866  {
2867  case T_outline:
2869  break;
2870 
2871  case T_convexhull:
2873  break;
2874 
2875  default:
2876  // Currently, because pad options is a moving target
2877  // just skip unknown keywords
2878  break;
2879  }
2880  NeedRIGHT();
2881  break;
2882 
2883  default:
2884  // Currently, because pad options is a moving target
2885  // just skip unknown keywords
2886  while( (token = NextTok() ) != T_RIGHT )
2887  {}
2888  break;
2889  }
2890  }
2891 
2892  return true;
2893 }
void SetAnchorPadShape(PAD_SHAPE_T aShape)
Function SetAnchorPadShape Set the shape of the anchor pad for custm shped pads.
Definition: class_pad.h:255
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:244

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

◆ parseDIMENSION()

DIMENSION * PCB_PARSER::parseDIMENSION ( )
private

Definition at line 1758 of file pcb_parser.cpp.

1759 {
1760  wxCHECK_MSG( CurTok() == T_dimension, NULL,
1761  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as DIMENSION." ) );
1762 
1763  T token;
1764 
1765  std::unique_ptr<DIMENSION> dimension( new DIMENSION( NULL ) );
1766 
1767  dimension->SetValue( parseBoardUnits( "dimension value" ) );
1768  NeedLEFT();
1769  token = NextTok();
1770 
1771  if( token != T_width )
1772  Expecting( T_width );
1773 
1774  dimension->SetWidth( parseBoardUnits( "dimension width value" ) );
1775  NeedRIGHT();
1776 
1777  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1778  {
1779  if( token != T_LEFT )
1780  Expecting( T_LEFT );
1781 
1782  token = NextTok();
1783 
1784  switch( token )
1785  {
1786  case T_layer:
1787  dimension->SetLayer( parseBoardItemLayer() );
1788  NeedRIGHT();
1789  break;
1790 
1791  case T_tstamp:
1792  dimension->SetTimeStamp( parseHex() );
1793  NeedRIGHT();
1794  break;
1795 
1796  case T_gr_text:
1797  {
1798  TEXTE_PCB* text = parseTEXTE_PCB();
1799 
1800  // This copy (using the copy constructor) rebuild the text timestamp,
1801  // that is not what we want.
1802  dimension->Text() = *text;
1803  // reinitialises the text time stamp to the right value (the dimension time stamp)
1804  dimension->Text().SetTimeStamp( dimension->GetTimeStamp() );
1805  dimension->SetPosition( text->GetTextPos() );
1806 
1807  EDA_UNITS_T units = INCHES;
1808  bool useMils = false;
1809  FetchUnitsFromString( text->GetText(), units, useMils );
1810  dimension->SetUnits( units, useMils );
1811 
1812  delete text;
1813  break;
1814  }
1815 
1816  case T_feature1:
1817  NeedLEFT();
1818  token = NextTok();
1819 
1820  if( token != T_pts )
1821  Expecting( T_pts );
1822 
1823  parseXY( &dimension->m_featureLineDO.x, &dimension->m_featureLineDO.y );
1824  parseXY( &dimension->m_featureLineDF.x, &dimension->m_featureLineDF.y );
1825  dimension->UpdateHeight();
1826  NeedRIGHT();
1827  NeedRIGHT();
1828  break;
1829 
1830  case T_feature2:
1831  NeedLEFT();
1832  token = NextTok();
1833 
1834  if( token != T_pts )
1835  Expecting( T_pts );
1836 
1837  parseXY( &dimension->m_featureLineGO.x, &dimension->m_featureLineGO.y );
1838  parseXY( &dimension->m_featureLineGF.x, &dimension->m_featureLineGF.y );
1839  dimension->UpdateHeight();
1840  NeedRIGHT();
1841  NeedRIGHT();
1842  break;
1843 
1844 
1845  case T_crossbar:
1846  NeedLEFT();
1847  token = NextTok();
1848 
1849  if( token != T_pts )
1850  Expecting( T_pts );
1851 
1852  parseXY( &dimension->m_crossBarO.x, &dimension->m_crossBarO.y );
1853  parseXY( &dimension->m_crossBarF.x, &dimension->m_crossBarF.y );
1854  dimension->UpdateHeight();
1855  NeedRIGHT();
1856  NeedRIGHT();
1857  break;
1858 
1859  case T_arrow1a:
1860  NeedLEFT();
1861  token = NextTok();
1862 
1863  if( token != T_pts )
1864  Expecting( T_pts );
1865 
1866  parseXY( &dimension->m_crossBarF.x, &dimension->m_crossBarF.y );
1867  parseXY( &dimension->m_arrowD1F.x, &dimension->m_arrowD1F.y );
1868  NeedRIGHT();
1869  NeedRIGHT();
1870  break;
1871 
1872  case T_arrow1b:
1873  NeedLEFT();
1874  token = NextTok();
1875 
1876  if( token != T_pts )
1877  Expecting( T_pts );
1878 
1879  parseXY( &dimension->m_crossBarF.x, &dimension->m_crossBarF.y );
1880  parseXY( &dimension->m_arrowD2F.x, &dimension->m_arrowD2F.y );
1881  NeedRIGHT();
1882  NeedRIGHT();
1883  break;
1884 
1885  case T_arrow2a:
1886  NeedLEFT();
1887  token = NextTok();
1888 
1889  if( token != T_pts )
1890  Expecting( T_pts );
1891 
1892  parseXY( &dimension->m_crossBarO.x, &dimension->m_crossBarO.y );
1893  parseXY( &dimension->m_arrowG1F.x, &dimension->m_arrowG1F.y );
1894  NeedRIGHT();
1895  NeedRIGHT();
1896  break;
1897 
1898  case T_arrow2b:
1899  NeedLEFT();
1900  token = NextTok();
1901 
1902  if( token != T_pts )
1903  Expecting( T_pts );
1904 
1905  parseXY( &dimension->m_crossBarO.x, &dimension->m_crossBarO.y );
1906  parseXY( &dimension->m_arrowG2F.x, &dimension->m_arrowG2F.y );
1907  NeedRIGHT();
1908  NeedRIGHT();
1909  break;
1910 
1911  default:
1912  Expecting( "layer, tstamp, gr_text, feature1, feature2 crossbar, arrow1a, "
1913  "arrow1b, arrow2a, or arrow2b" );
1914  }
1915  }
1916 
1917  return dimension.release();
1918 }
wxPoint parseXY()
Function parseXY parses a coordinate pair (xy X Y) in board units (mm).
Definition: pcb_parser.cpp:208
virtual const wxString GetText() const
Function GetText returns the string associated with the text object.
Definition: eda_text.h:147
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:238
Definition: common.h:158
PCB_LAYER_ID parseBoardItemLayer()
Function parseBoardItemLayer parses the layer definition of a BOARD_ITEM object.
TEXTE_PCB * parseTEXTE_PCB()
const wxPoint & GetTextPos() const
Definition: eda_text.h:241
long parseHex()
Definition: pcb_parser.h:287
EDA_UNITS_T
Definition: common.h:157
Class DIMENSION.
void SetTimeStamp(timestamp_t aNewTimeStamp)
Definition: base_struct.h:209

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

◆ parseDouble() [1/3]

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 126 of file pcb_parser.cpp.

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

References GetChars(), and THROW_IO_ERROR.

Referenced by parseBoardUnits(), and parseDouble().

◆ parseDouble() [2/3]

double PCB_PARSER::parseDouble ( const char *  aExpected)
inlineprivate

Definition at line 227 of file pcb_parser.h.

228  {
229  NeedNUMBER( aExpected );
230  return parseDouble();
231  }
double parseDouble()
Function parseDouble parses the current token as an ASCII numeric string with possible leading whites...
Definition: pcb_parser.cpp:126

References parseDouble().

◆ parseDouble() [3/3]

double PCB_PARSER::parseDouble ( PCB_KEYS_T::T  aToken)
inlineprivate

Definition at line 233 of file pcb_parser.h.

234  {
235  return parseDouble( GetTokenText( aToken ) );
236  }
double parseDouble()
Function parseDouble parses the current token as an ASCII numeric string with possible leading whites...
Definition: pcb_parser.cpp:126
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

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

◆ parseDRAWSEGMENT()

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 1517 of file pcb_parser.cpp.

1518 {
1519  wxCHECK_MSG( CurTok() == T_gr_arc || CurTok() == T_gr_circle || CurTok() == T_gr_curve ||
1520  CurTok() == T_gr_line || CurTok() == T_gr_poly, NULL,
1521  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as DRAWSEGMENT." ) );
1522 
1523  T token;
1524  wxPoint pt;
1525  std::unique_ptr< DRAWSEGMENT > segment( new DRAWSEGMENT( NULL ) );
1526 
1527  switch( CurTok() )
1528  {
1529  case T_gr_arc:
1530  segment->SetShape( S_ARC );
1531  NeedLEFT();
1532  token = NextTok();
1533 
1534  // the start keyword actually gives the arc center
1535  // Allows also T_center for future change
1536  if( token != T_start && token != T_center )
1537  Expecting( T_start );
1538 
1539  pt.x = parseBoardUnits( "X coordinate" );
1540  pt.y = parseBoardUnits( "Y coordinate" );
1541  segment->SetCenter( pt );
1542  NeedRIGHT();
1543  NeedLEFT();
1544  token = NextTok();
1545 
1546  if( token != T_end ) // the end keyword actually gives the starting point of the arc
1547  Expecting( T_end );
1548 
1549  pt.x = parseBoardUnits( "X coordinate" );
1550  pt.y = parseBoardUnits( "Y coordinate" );
1551  segment->SetArcStart( pt );
1552  NeedRIGHT();
1553  break;
1554 
1555  case T_gr_circle:
1556  segment->SetShape( S_CIRCLE );
1557  NeedLEFT();
1558  token = NextTok();
1559 
1560  if( token != T_center )
1561  Expecting( T_center );
1562 
1563  pt.x = parseBoardUnits( "X coordinate" );
1564  pt.y = parseBoardUnits( "Y coordinate" );
1565  segment->SetCenter( pt );
1566  NeedRIGHT();
1567  NeedLEFT();
1568 
1569  token = NextTok();
1570 
1571  if( token != T_end )
1572  Expecting( T_end );
1573 
1574  pt.x = parseBoardUnits( "X coordinate" );
1575  pt.y = parseBoardUnits( "Y coordinate" );
1576  segment->SetEnd( pt );
1577  NeedRIGHT();
1578  break;
1579 
1580  case T_gr_curve:
1581  segment->SetShape( S_CURVE );
1582  NeedLEFT();
1583  token = NextTok();
1584 
1585  if( token != T_pts )
1586  Expecting( T_pts );
1587 
1588  segment->SetStart( parseXY() );
1589  segment->SetBezControl1( parseXY() );
1590  segment->SetBezControl2( parseXY() );
1591  segment->SetEnd( parseXY() );
1592  NeedRIGHT();
1593  break;
1594 
1595  case T_gr_line:
1596  // Default DRAWSEGMENT type is S_SEGMENT.
1597  NeedLEFT();
1598  token = NextTok();
1599 
1600  if( token != T_start )
1601  Expecting( T_start );
1602 
1603  pt.x = parseBoardUnits( "X coordinate" );
1604  pt.y = parseBoardUnits( "Y coordinate" );
1605  segment->SetStart( pt );
1606  NeedRIGHT();
1607  NeedLEFT();
1608  token = NextTok();
1609 
1610  if( token != T_end )
1611  Expecting( T_end );
1612 
1613  pt.x = parseBoardUnits( "X coordinate" );
1614  pt.y = parseBoardUnits( "Y coordinate" );
1615  segment->SetEnd( pt );
1616  NeedRIGHT();
1617  break;
1618 
1619  case T_gr_poly:
1620  {
1621  segment->SetShape( S_POLYGON );
1622  segment->SetWidth( 0 ); // this is the default value. will be (perhaps) modified later
1623  NeedLEFT();
1624  token = NextTok();
1625 
1626  if( token != T_pts )
1627  Expecting( T_pts );
1628 
1629  std::vector< wxPoint > pts;
1630 
1631  while( (token = NextTok()) != T_RIGHT )
1632  pts.push_back( parseXY() );
1633 
1634  segment->SetPolyPoints( pts );
1635  }
1636  break;
1637 
1638  default:
1639  Expecting( "gr_arc, gr_circle, gr_curve, gr_line, or gr_poly" );
1640  }
1641 
1642  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1643  {
1644  if( token != T_LEFT )
1645  Expecting( T_LEFT );
1646 
1647  token = NextTok();
1648 
1649  switch( token )
1650  {
1651  case T_angle:
1652  segment->SetAngle( parseDouble( "segment angle" ) * 10.0 );
1653  break;
1654 
1655  case T_layer:
1656  segment->SetLayer( parseBoardItemLayer() );
1657  break;
1658 
1659  case T_width:
1660  segment->SetWidth( parseBoardUnits( T_width ) );
1661  break;
1662 
1663  case T_tstamp:
1664  segment->SetTimeStamp( parseHex() );
1665  break;
1666 
1667  case T_status:
1668  segment->SetStatus( static_cast<STATUS_FLAGS>( parseHex() ) );
1669  break;
1670 
1671  default:
1672  Expecting( "layer, width, tstamp, or status" );
1673  }
1674 
1675  NeedRIGHT();
1676  }
1677 
1678  // Only filled polygons may have a zero-line width
1679  // This is not permitted in KiCad but some external tools generate invalid
1680  // files.
1681  // However in custom pad shapes, zero-line width is allowed for filled circles
1682  if( segment->GetShape() != S_POLYGON && segment->GetWidth() == 0 &&
1683  !( segment->GetShape() == S_CIRCLE && aAllowCirclesZeroWidth ) )
1684  segment->SetWidth( Millimeter2iu( DEFAULT_LINE_WIDTH ) );
1685 
1686  return segment.release();
1687 }
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:208
#define DEFAULT_LINE_WIDTH
int parseBoardUnits()
Definition: pcb_parser.h:238
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:126
long parseHex()
Definition: pcb_parser.h:287

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

◆ parseEDA_TEXT()

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 240 of file pcb_parser.cpp.

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

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

◆ parseEDGE_MODULE()

EDGE_MODULE * PCB_PARSER::parseEDGE_MODULE ( )
private

Definition at line 2279 of file pcb_parser.cpp.

2280 {
2281  wxCHECK_MSG( CurTok() == T_fp_arc || CurTok() == T_fp_circle || CurTok() == T_fp_curve ||
2282  CurTok() == T_fp_line || CurTok() == T_fp_poly, NULL,
2283  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as EDGE_MODULE." ) );
2284 
2285  wxPoint pt;
2286  T token;
2287 
2288  std::unique_ptr< EDGE_MODULE > segment( new EDGE_MODULE( NULL ) );
2289 
2290  switch( CurTok() )
2291  {
2292  case T_fp_arc:
2293  segment->SetShape( S_ARC );
2294  NeedLEFT();
2295  token = NextTok();
2296 
2297  // the start keyword actually gives the arc center
2298  // Allows also T_center for future change
2299  if( token != T_start && token != T_center )
2300  Expecting( T_start );
2301 
2302  pt.x = parseBoardUnits( "X coordinate" );
2303  pt.y = parseBoardUnits( "Y coordinate" );
2304  segment->SetStart0( pt );
2305  NeedRIGHT();
2306  NeedLEFT();
2307  token = NextTok();
2308 
2309  if( token != T_end ) // end keyword actually gives the starting point of the arc
2310  Expecting( T_end );
2311 
2312  pt.x = parseBoardUnits( "X coordinate" );
2313  pt.y = parseBoardUnits( "Y coordinate" );
2314  segment->SetEnd0( pt );
2315  NeedRIGHT();
2316  NeedLEFT();
2317  token = NextTok();
2318 
2319  if( token != T_angle )
2320  Expecting( T_angle );
2321 
2322  segment->SetAngle( parseDouble( "segment angle" ) * 10.0 );
2323  NeedRIGHT();
2324  break;
2325 
2326  case T_fp_circle:
2327  segment->SetShape( S_CIRCLE );
2328  NeedLEFT();
2329  token = NextTok();
2330 
2331  if( token != T_center )
2332  Expecting( T_center );
2333 
2334  pt.x = parseBoardUnits( "X coordinate" );
2335  pt.y = parseBoardUnits( "Y coordinate" );
2336  segment->SetStart0( pt );
2337  NeedRIGHT();
2338  NeedLEFT();
2339  token = NextTok();
2340 
2341  if( token != T_end )
2342  Expecting( T_end );
2343 
2344  pt.x = parseBoardUnits( "X coordinate" );
2345  pt.y = parseBoardUnits( "Y coordinate" );
2346  segment->SetEnd0( pt );
2347  NeedRIGHT();
2348  break;
2349 
2350  case T_fp_curve:
2351  segment->SetShape( S_CURVE );
2352  NeedLEFT();
2353  token = NextTok();
2354 
2355  if( token != T_pts )
2356  Expecting( T_pts );
2357 
2358  segment->SetStart0( parseXY() );
2359  segment->SetBezier0_C1( parseXY() );
2360  segment->SetBezier0_C2( parseXY() );
2361  segment->SetEnd0( parseXY() );
2362  NeedRIGHT();
2363  break;
2364 
2365  case T_fp_line:
2366  // Default DRAWSEGMENT type is S_SEGMENT.
2367  NeedLEFT();
2368  token = NextTok();
2369 
2370  if( token != T_start )
2371  Expecting( T_start );
2372 
2373  pt.x = parseBoardUnits( "X coordinate" );
2374  pt.y = parseBoardUnits( "Y coordinate" );
2375  segment->SetStart0( pt );
2376 
2377  NeedRIGHT();
2378  NeedLEFT();
2379  token = NextTok();
2380 
2381  if( token != T_end )
2382  Expecting( T_end );
2383 
2384  pt.x = parseBoardUnits( "X coordinate" );
2385  pt.y = parseBoardUnits( "Y coordinate" );
2386  segment->SetEnd0( pt );
2387  NeedRIGHT();
2388  break;
2389 
2390  case T_fp_poly:
2391  {
2392  segment->SetShape( S_POLYGON );
2393  NeedLEFT();
2394  token = NextTok();
2395 
2396  if( token != T_pts )
2397  Expecting( T_pts );
2398 
2399  std::vector< wxPoint > pts;
2400 
2401  while( (token = NextTok()) != T_RIGHT )
2402  pts.push_back( parseXY() );
2403 
2404  segment->SetPolyPoints( pts );
2405  }
2406  break;
2407 
2408  default:
2409  Expecting( "fp_arc, fp_circle, fp_curve, fp_line, or fp_poly" );
2410  }
2411 
2412  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2413  {
2414  if( token != T_LEFT )
2415  Expecting( T_LEFT );
2416 
2417  token = NextTok();
2418 
2419  switch( token )
2420  {
2421  case T_layer:
2422  segment->SetLayer( parseBoardItemLayer() );
2423  break;
2424 
2425  case T_width:
2426  segment->SetWidth( parseBoardUnits( T_width ) );
2427  break;
2428 
2429  case T_tstamp:
2430  segment->SetTimeStamp( parseHex() );
2431  break;
2432 
2433  case T_status:
2434  segment->SetStatus( static_cast<STATUS_FLAGS>( parseHex() ) );
2435  break;
2436 
2437  default:
2438  Expecting( "layer or width" );
2439  }
2440 
2441  NeedRIGHT();
2442  }
2443 
2444  // Only filled polygons may have a zero-line width
2445  // This is not permitted in KiCad but some external tools generate invalid
2446  // files.
2447  if( segment->GetShape() != S_POLYGON && segment->GetWidth() == 0 )
2448  segment->SetWidth( Millimeter2iu( DEFAULT_LINE_WIDTH ) );
2449 
2450  return segment.release();
2451 }
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:208
#define DEFAULT_LINE_WIDTH
int parseBoardUnits()
Definition: pcb_parser.h:238
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:126
long parseHex()
Definition: pcb_parser.h:287

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

◆ parseGeneralSection()

void PCB_PARSER::parseGeneralSection ( )
private

Definition at line 704 of file pcb_parser.cpp.

705 {
706  wxCHECK_RET( CurTok() == T_general,
707  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
708  wxT( " as a general section." ) );
709 
710  T token;
711 
712  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
713  {
714  if( token != T_LEFT )
715  Expecting( T_LEFT );
716 
717  token = NextTok();
718 
719  switch( token )
720  {
721  case T_thickness:
723  NeedRIGHT();
724  break;
725 
726  case T_nets:
727  m_netCodes.resize( parseInt( "nets number" ) );
728  NeedRIGHT();
729  break;
730 
731  case T_no_connects:
732  // ignore
733  parseInt( "no connect count" );
734  NeedRIGHT();
735  break;
736 
737  default: // Skip everything but the board thickness.
738  //wxLogDebug( wxT( "Skipping general section token %s " ), GetChars( GetTokenString( token ) ) );
739 
740  while( ( token = NextTok() ) != T_RIGHT )
741  {
742  if( !IsSymbol( token ) && token != T_NUMBER )
743  Expecting( "symbol or number" );
744  }
745  }
746  }
747 }
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:534
void SetBoardThickness(int aThickness)
int parseBoardUnits()
Definition: pcb_parser.h:238
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:276

References parseInt().

◆ parseHeader()

void PCB_PARSER::parseHeader ( )
private

Definition at line 668 of file pcb_parser.cpp.

669 {
670  wxCHECK_RET( CurTok() == T_kicad_pcb,
671  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a header." ) );
672 
673  NeedLEFT();
674 
675  T tok = NextTok();
676  if( tok == T_version )
677  {
678  m_requiredVersion = parseInt( FromUTF8().mb_str( wxConvUTF8 ) );
680  NeedRIGHT();
681 
682  // Skip the host name and host build version information.
683  NeedLEFT();
684  NeedSYMBOL();
685  NeedSYMBOL();
686  NeedSYMBOL();
687  NeedRIGHT();
688  }
689  else
690  {
693 
694  // Skip the host name and host build version information.
695  NeedSYMBOL();
696  NeedSYMBOL();
697  NeedRIGHT();
698  }
699 
701 }
void SetFileFormatVersionAtLoad(int aVersion)
Definition: class_board.h:276
#define SEXPR_BOARD_FILE_VERSION
Current s-expression file format version. 2 was the last legacy format version.
bool m_tooRecent
true if version parses as later than supported
Definition: pcb_parser.h: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:276

References parseInt(), and SEXPR_BOARD_FILE_VERSION.

◆ parseHex()

long PCB_PARSER::parseHex ( )
inlineprivate

Definition at line 287 of file pcb_parser.h.

288  {
289  NextTok();
290  return strtol( CurText(), NULL, 16 );
291  }

◆ parseInt() [1/2]

int PCB_PARSER::parseInt ( )
inlineprivate

Definition at line 276 of file pcb_parser.h.

277  {
278  return (int)strtol( CurText(), NULL, 10 );
279  }

Referenced by parseInt().

◆ parseInt() [2/2]

int PCB_PARSER::parseInt ( const char *  aExpected)
inlineprivate

Definition at line 281 of file pcb_parser.h.

282  {
283  NeedNUMBER( aExpected );
284  return parseInt();
285  }
int parseInt()
Definition: pcb_parser.h:276

References parseInt().

◆ parseLayer()

void PCB_PARSER::parseLayer ( LAYER aLayer)
private

Definition at line 889 of file pcb_parser.cpp.

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

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

◆ parseLayers()

void PCB_PARSER::parseLayers ( )
private

Definition at line 980 of file pcb_parser.cpp.

981 {
982  wxCHECK_RET( CurTok() == T_layers,
983  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as layers." ) );
984 
985  T token;
986  LSET visibleLayers;
987  LSET enabledLayers;
988  int copperLayerCount = 0;
989  LAYER layer;
990 
991  std::unordered_map< std::string, std::string > v3_layer_names;
992  std::vector<LAYER> cu;
993 
994  createOldLayerMapping( v3_layer_names );
995 
996  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
997  {
998  parseLayer( &layer );
999 
1000  if( layer.m_type == LT_UNDEFINED ) // it's a non-copper layer
1001  break;
1002 
1003  cu.push_back( layer ); // it's copper
1004  }
1005 
1006  // All Cu layers are parsed, but not the non-cu layers here.
1007 
1008  // The original *.kicad_pcb file format and the inverted
1009  // Cu stack format both have all the Cu layers first, so use this
1010  // trick to handle either. The layer number in the (layers ..)
1011  // s-expression element are ignored.
1012  if( cu.size() )
1013  {
1014  // Rework the layer numbers, which changed when the Cu stack
1015  // was flipped. So we instead use position in the list.
1016  cu[cu.size()-1].m_number = B_Cu;
1017 
1018  for( unsigned i=0; i < cu.size()-1; ++i )
1019  {
1020  cu[i].m_number = i;
1021  }
1022 
1023  for( std::vector<LAYER>::const_iterator it = cu.begin(); it<cu.end(); ++it )
1024  {
1025  enabledLayers.set( it->m_number );
1026 
1027  if( it->m_visible )
1028  visibleLayers.set( it->m_number );
1029 
1030  m_board->SetLayerDescr( PCB_LAYER_ID( it->m_number ), *it );
1031 
1032  UTF8 name = it->m_name;
1033 
1034  m_layerIndices[ name ] = PCB_LAYER_ID( it->m_number );
1035  m_layerMasks[ name ] = LSET( PCB_LAYER_ID( it->m_number ) );
1036  }
1037 
1038  copperLayerCount = cu.size();
1039  }
1040 
1041  // process non-copper layers
1042  while( token != T_RIGHT )
1043  {
1044  LAYER_ID_MAP::const_iterator it = m_layerIndices.find( UTF8( layer.m_name ) );
1045 
1046  if( it == m_layerIndices.end() )
1047  {
1048  auto new_layer_it = v3_layer_names.find( layer.m_name.ToStdString() );
1049 
1050  if( new_layer_it != v3_layer_names.end() )
1051  it = m_layerIndices.find( new_layer_it->second );
1052 
1053  if( it == m_layerIndices.end() )
1054  {
1055  wxString error = wxString::Format(
1056  _( "Layer \"%s\" in file \"%s\" at line %d, is not in fixed layer hash" ),
1057  GetChars( layer.m_name ),
1058  GetChars( CurSource() ),
1059  CurLineNumber(),
1060  CurOffset()
1061  );
1062 
1063  THROW_IO_ERROR( error );
1064  }
1065 
1066  // If we are here, then we have found a translated layer name. Put it in the maps so that
1067  // items on this layer get the appropriate layer ID number
1068  m_layerIndices[ UTF8( layer.m_name ) ] = it->second;
1069  m_layerMasks[ UTF8( layer.m_name ) ] = it->second;
1070  layer.m_name = it->first;
1071  }
1072 
1073  layer.m_number = it->second;
1074  enabledLayers.set( layer.m_number );
1075 
1076  if( layer.m_visible )
1077  visibleLayers.set( layer.m_number );
1078 
1079  m_board->SetLayerDescr( it->second, layer );
1080 
1081  token = NextTok();
1082 
1083  if( token != T_LEFT )
1084  break;
1085 
1086  parseLayer( &layer );
1087  }
1088 
1089  // We need at least 2 copper layers and there must be an even number of them.
1090  if( copperLayerCount < 2 || (copperLayerCount % 2) != 0 )
1091  {
1092  wxString err = wxString::Format(
1093  _( "%d is not a valid layer count" ), copperLayerCount );
1094 
1095  THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
1096  }
1097 
1098  m_board->SetCopperLayerCount( copperLayerCount );
1099  m_board->SetEnabledLayers( enabledLayers );
1100 
1101  // call SetEnabledLayers before SetVisibleLayers()
1102  m_board->SetVisibleLayers( visibleLayers );
1103 }
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:112
LAYER_T m_type
The type of the layer.
Definition: class_board.h:114
void createOldLayerMapping(std::unordered_map< std::string, std::string > &aMap)
Creates a mapping from the (short-lived) bug where layer names were translated TODO: Remove this once...
Definition: pcb_parser.cpp:930
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:116
#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:889
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:100
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:86
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's index
Definition: pcb_parser.h:71
int m_number
Definition: class_board.h:118
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

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.

◆ parseMODULE()

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 1921 of file pcb_parser.cpp.

1922 {
1923  try
1924  {
1925  return parseMODULE_unchecked( aInitialComments );
1926  }
1927  catch( const PARSE_ERROR& parse_error )
1928  {
1929  if( m_tooRecent )
1930  throw FUTURE_FORMAT_ERROR( parse_error, GetRequiredVersion() );
1931  else
1932  throw;
1933  }
1934 }
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:184
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,...
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

Referenced by CLIPBOARD_PARSER::parseMODULE().

◆ parseMODULE_unchecked()

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 1937 of file pcb_parser.cpp.

1938 {
1939  wxCHECK_MSG( CurTok() == T_module, NULL,
1940  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as MODULE." ) );
1941 
1942  wxString name;
1943  wxPoint pt;
1944  T token;
1945  LIB_ID fpid;
1946 
1947  std::unique_ptr<MODULE> module( new MODULE( m_board ) );
1948 
1949  module->SetInitialComments( aInitialComments );
1950 
1951  token = NextTok();
1952 
1953  if( !IsSymbol( token ) && token != T_NUMBER )
1954  Expecting( "symbol|number" );
1955 
1956  name = FromUTF8();
1957 
1958  if( !name.IsEmpty() && fpid.Parse( name, LIB_ID::ID_PCB, true ) >= 0 )
1959  {
1960  wxString error;
1961  error.Printf( _( "Invalid footprint ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),
1962  GetChars( CurSource() ), CurLineNumber(), CurOffset() );
1963  THROW_IO_ERROR( error );
1964  }
1965 
1966  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1967  {
1968  if( token == T_LEFT )
1969  token = NextTok();
1970 
1971  switch( token )
1972  {
1973  case T_version:
1974  {
1975  // Theoretically a module nested in a PCB could declare its own version, though
1976  // as of writing this comment we don't do that. Just in case, take the greater
1977  // version.
1978  int this_version = parseInt( FromUTF8().mb_str( wxConvUTF8 ) );
1979  NeedRIGHT();
1980  m_requiredVersion = std::max( m_requiredVersion, this_version );
1982  break;
1983  }
1984 
1985  case T_locked:
1986  module->SetLocked( true );
1987  break;
1988 
1989  case T_placed:
1990  module->SetIsPlaced( true );
1991  break;
1992 
1993  case T_layer:
1994  {
1995  // Footprints can be only on the front side or the back side.
1996  // but because we can find some stupid layer in file, ensure a
1997  // acceptable layer is set for the footprint
1999  module->SetLayer( layer == B_Cu ? B_Cu : F_Cu );
2000  }
2001  NeedRIGHT();
2002  break;
2003 
2004  case T_tedit:
2005  module->SetLastEditTime( parseHex() );
2006  NeedRIGHT();
2007  break;
2008 
2009  case T_tstamp:
2010  module->SetTimeStamp( parseHex() );
2011  NeedRIGHT();
2012  break;
2013 
2014  case T_at:
2015  pt.x = parseBoardUnits( "X coordinate" );
2016  pt.y = parseBoardUnits( "Y coordinate" );
2017  module->SetPosition( pt );
2018  token = NextTok();
2019 
2020  if( token == T_NUMBER )
2021  {
2022  module->SetOrientation( parseDouble() * 10.0 );
2023  NeedRIGHT();
2024  }
2025  else if( token != T_RIGHT )
2026  {
2027  Expecting( T_RIGHT );
2028  }
2029 
2030  break;
2031 
2032  case T_descr:
2033  NeedSYMBOLorNUMBER(); // some symbols can be 0508, so a number is also a symbol here
2034  module->SetDescription( FromUTF8() );
2035  NeedRIGHT();
2036  break;
2037 
2038  case T_tags:
2039  NeedSYMBOLorNUMBER(); // some symbols can be 0508, so a number is also a symbol here
2040  module->SetKeywords( FromUTF8() );
2041  NeedRIGHT();
2042  break;
2043 
2044  case T_path:
2045  NeedSYMBOLorNUMBER(); // Paths can be numerical so a number is also a symbol here
2046  module->SetPath( FromUTF8() );
2047  NeedRIGHT();
2048  break;
2049 
2050  case T_autoplace_cost90:
2051  module->SetPlacementCost90( parseInt( "auto place cost at 90 degrees" ) );
2052  NeedRIGHT();
2053  break;
2054 
2055  case T_autoplace_cost180:
2056  module->SetPlacementCost180( parseInt( "auto place cost at 180 degrees" ) );
2057  NeedRIGHT();
2058  break;
2059 
2060  case T_solder_mask_margin:
2061  module->SetLocalSolderMaskMargin( parseBoardUnits( "local solder mask margin value" ) );
2062  NeedRIGHT();
2063  break;
2064 
2065  case T_solder_paste_margin:
2066  module->SetLocalSolderPasteMargin(
2067  parseBoardUnits( "local solder paste margin value" ) );
2068  NeedRIGHT();
2069  break;
2070 
2071  case T_solder_paste_ratio:
2072  module->SetLocalSolderPasteMarginRatio(
2073  parseDouble( "local solder paste margin ratio value" ) );
2074  NeedRIGHT();
2075  break;
2076 
2077  case T_clearance:
2078  module->SetLocalClearance( parseBoardUnits( "local clearance value" ) );
2079  NeedRIGHT();
2080  break;
2081 
2082  case T_zone_connect:
2083  module->SetZoneConnection( (ZoneConnection) parseInt( "zone connection value" ) );
2084  NeedRIGHT();
2085  break;
2086 
2087  case T_thermal_width:
2088  module->SetThermalWidth( parseBoardUnits( "thermal width value" ) );
2089  NeedRIGHT();
2090  break;
2091 
2092  case T_thermal_gap:
2093  module->SetThermalGap( parseBoardUnits( "thermal gap value" ) );
2094  NeedRIGHT();
2095  break;
2096 
2097  case T_attr:
2098  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2099  {
2100  switch( token )
2101  {
2102  case T_smd:
2103  module->SetAttributes( module->GetAttributes() | MOD_CMS );
2104  break;
2105 
2106  case T_virtual:
2107  module->SetAttributes( module->GetAttributes() | MOD_VIRTUAL );
2108  break;
2109 
2110  default:
2111  Expecting( "smd and/or virtual" );
2112  }
2113  }
2114  break;
2115 
2116  case T_fp_text:
2117  {
2118  TEXTE_MODULE* text = parseTEXTE_MODULE();
2119  text->SetParent( module.get() );
2120  double orientation = text->GetTextAngle();
2121  orientation -= module->GetOrientation();
2122  text->SetTextAngle( orientation );
2123  text->SetDrawCoord();
2124 
2125  switch( text->GetType() )
2126  {
2128  module->Reference() = *text;
2129  delete text;
2130  break;
2131 
2133  module->Value() = *text;
2134  delete text;
2135  break;
2136 
2137  default:
2138  module->GraphicalItemsList().PushBack( text );
2139  }
2140  }
2141  break;
2142 
2143  case T_fp_arc:
2144  case T_fp_circle:
2145  case T_fp_curve:
2146  case T_fp_line:
2147  case T_fp_poly:
2148  {
2149  EDGE_MODULE* em = parseEDGE_MODULE();
2150  em->SetParent( module.get() );
2151  em->SetDrawCoord();
2152  module->GraphicalItemsList().PushBack( em );
2153  }
2154  break;
2155 
2156  case T_pad:
2157  {
2158  D_PAD* pad = parseD_PAD( module.get() );
2159  pt = pad->GetPos0();
2160 
2161  RotatePoint( &pt, module->GetOrientation() );
2162  pad->SetPosition( pt + module->GetPosition() );
2163  module->Add( pad, ADD_APPEND );
2164  }
2165  break;
2166 
2167  case T_model:
2168  module->Add3DModel( parse3DModel() );
2169  break;
2170 
2171  default:
2172  Expecting( "locked, placed, tedit, tstamp, at, descr, tags, path, "
2173  "autoplace_cost90, autoplace_cost180, solder_mask_margin, "
2174  "solder_paste_margin, solder_paste_ratio, clearance, "
2175  "zone_connect, thermal_width, thermal_gap, attr, fp_text, "
2176  "fp_arc, fp_circle, fp_curve, fp_line, fp_poly, pad, or model" );
2177  }
2178  }
2179 
2180  module->SetFPID( fpid );
2181  module->CalculateBoundingBox();
2182 
2183  return module.release();
2184 }
const wxPoint & GetPos0() const
Definition: class_pad.h:265
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.
double GetTextAngle() const
Definition: eda_text.h:181
void SetPosition(const wxPoint &aPos) override
Definition: class_pad.h:221
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:238
PCB_LAYER_ID
A quick note on layer IDs:
void SetParent(EDA_ITEM *aParent)
Definition: base_struct.h:219
TEXT_TYPE GetType() const
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:100
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,...
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:126
void SetTextAngle(double aAngle)
TEXTE_MODULE * parseTEXTE_MODULE()
D_PAD * parseD_PAD(MODULE *aParent=NULL)
long parseHex()
Definition: pcb_parser.h:287
int parseInt()
Definition: pcb_parser.h:276
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:352

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.

◆ parseNETCLASS()

void PCB_PARSER::parseNETCLASS ( )
private

Definition at line 1434 of file pcb_parser.cpp.

1435 {
1436  wxCHECK_RET( CurTok() == T_net_class,
1437  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as net class." ) );
1438 
1439  T token;
1440 
1441  NETCLASSPTR nc = std::make_shared<NETCLASS>( wxEmptyString );
1442 
1443  // Read netclass name (can be a name or just a number like track width)
1444  NeedSYMBOLorNUMBER();
1445  nc->SetName( FromUTF8() );
1446  NeedSYMBOL();
1447  nc->SetDescription( FromUTF8() );
1448 
1449  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1450  {
1451  if( token != T_LEFT )
1452  Expecting( T_LEFT );
1453 
1454  token = NextTok();
1455 
1456  switch( token )
1457  {
1458  case T_clearance:
1459  nc->SetClearance( parseBoardUnits( T_clearance ) );
1460  break;
1461 
1462  case T_trace_width:
1463  nc->SetTrackWidth( parseBoardUnits( T_trace_width ) );
1464  break;
1465 
1466  case T_via_dia:
1467  nc->SetViaDiameter( parseBoardUnits( T_via_dia ) );
1468  break;
1469 
1470  case T_via_drill:
1471  nc->SetViaDrill( parseBoardUnits( T_via_drill ) );
1472  break;
1473 
1474  case T_uvia_dia:
1475  nc->SetuViaDiameter( parseBoardUnits( T_uvia_dia ) );
1476  break;
1477 
1478  case T_uvia_drill:
1479  nc->SetuViaDrill( parseBoardUnits( T_uvia_drill ) );
1480  break;
1481 
1482  case T_diff_pair_width:
1483  nc->SetDiffPairWidth( parseBoardUnits( T_diff_pair_width ) );
1484  break;
1485 
1486  case T_diff_pair_gap:
1487  nc->SetDiffPairGap( parseBoardUnits( T_diff_pair_gap ) );
1488  break;
1489 
1490  case T_add_net:
1491  NeedSYMBOLorNUMBER();
1492  nc->Add( FromUTF8() );
1493  break;
1494 
1495  default:
1496  Expecting( "clearance, trace_width, via_dia, via_drill, uvia_dia, uvia_drill, diff_pair_width, diff_pair_gap or add_net" );
1497  }
1498 
1499  NeedRIGHT();
1500  }
1501 
1502  if( !m_board->GetDesignSettings().m_NetClasses.Add( nc ) )
1503  {
1504  // Must have been a name conflict, this is a bad board file.
1505  // User may have done a hand edit to the file.
1506 
1507  // unique_ptr will delete nc on this code path
1508 
1509  wxString error;
1510  error.Printf( _( "Duplicate NETCLASS name \"%s\" in file \"%s\" at line %d, offset %d" ),
1511  nc->GetName().GetData(), CurSource().GetData(), CurLineNumber(), CurOffset() );
1512  THROW_IO_ERROR( error );
1513  }
1514 }
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:534
int parseBoardUnits()
Definition: pcb_parser.h:238
#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

References THROW_IO_ERROR.

◆ parseNETINFO_ITEM()

void PCB_PARSER::parseNETINFO_ITEM ( )
private

Definition at line 1408 of file pcb_parser.cpp.

1409 {
1410  wxCHECK_RET( CurTok() == T_net,
1411  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as net." ) );
1412 
1413  int netCode = parseInt( "net number" );
1414 
1415  NeedSYMBOLorNUMBER();
1416  wxString name = FromUTF8();
1417 
1418  NeedRIGHT();
1419 
1420  // net 0 should be already in list, so store this net
1421  // if it is not the net 0, or if the net 0 does not exists.
1422  // (TODO: a better test.)
1424  {
1425  NETINFO_ITEM* net = new NETINFO_ITEM( m_board, name, netCode );
1426  m_board->Add( net );
1427 
1428  // Store the new code mapping
1429  pushValueIntoMap( netCode, net->GetNet() );
1430  }
1431 }
NETINFO_ITEM * FindNet(int aNetcode) const
Function FindNet searches for a net with the given netcode.
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_INSERT) override
Adds an item to the container.
Class NETINFO_ITEM handles the data for a net.
Definition: netinfo.h:65
const char * name
Definition: DXF_plotter.cpp:61
int GetNet() const
Function GetNet.
Definition: netinfo.h:227
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:115
int parseInt()
Definition: pcb_parser.h:276
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
Definition: netinfo.h:465

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

◆ parsePAGE_INFO()

void PCB_PARSER::parsePAGE_INFO ( )
private

Definition at line 750 of file pcb_parser.cpp.

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

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

◆ parsePCB_TARGET()

PCB_TARGET * PCB_PARSER::parsePCB_TARGET ( )
private

Definition at line 3475 of file pcb_parser.cpp.

3476 {
3477  wxCHECK_MSG( CurTok() == T_target, NULL,
3478  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as PCB_TARGET." ) );
3479 
3480  wxPoint pt;
3481  T token;
3482 
3483  std::unique_ptr< PCB_TARGET > target( new PCB_TARGET( NULL ) );
3484 
3485  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3486  {
3487  if( token == T_LEFT )
3488  token = NextTok();
3489 
3490  switch( token )
3491  {
3492  case T_x:
3493  target->SetShape( 1 );
3494  break;
3495 
3496  case T_plus:
3497  target->SetShape( 0 );
3498  break;
3499 
3500  case T_at:
3501  pt.x = parseBoardUnits( "target x position" );
3502  pt.y = parseBoardUnits( "target y position" );
3503  target->SetPosition( pt );
3504  NeedRIGHT();
3505  break;
3506 
3507  case T_size:
3508  target->SetSize( parseBoardUnits( "target size" ) );
3509  NeedRIGHT();
3510  break;
3511 
3512  case T_width:
3513  target->SetWidth( parseBoardUnits( "target thickness" ) );
3514  NeedRIGHT();
3515  break;
3516 
3517  case T_layer:
3518  target->SetLayer( parseBoardItemLayer() );
3519  NeedRIGHT();
3520  break;
3521 
3522  case T_tstamp:
3523  target->SetTimeStamp( parseHex() );
3524  NeedRIGHT();
3525  break;
3526 
3527  default:
3528  Expecting( "x, plus, at, size, width, layer or tstamp" );
3529  }
3530  }
3531 
3532  return target.release();
3533 }
int parseBoardUnits()
Definition: pcb_parser.h:238
PCB_LAYER_ID parseBoardItemLayer()
Function parseBoardItemLayer parses the layer definition of a BOARD_ITEM object.
long parseHex()
Definition: pcb_parser.h:287

References parseHex().

◆ parseSetup()

void PCB_PARSER::parseSetup ( )
private

Definition at line 1164 of file pcb_parser.cpp.

1165 {
1166  wxCHECK_RET( CurTok() == T_setup,
1167  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as setup." ) );
1168 
1169  T token;
1170  NETCLASSPTR defaultNetClass = m_board->GetDesignSettings().GetDefault();
1171  // TODO Orson: is it really necessary to first operate on a copy and then apply it?
1172  // would not it be better to use reference here and apply all the changes instantly?
1173  BOARD_DESIGN_SETTINGS designSettings = m_board->GetDesignSettings();
1174  ZONE_SETTINGS zoneSettings = m_board->GetZoneSettings();
1175 
1176  // Missing soldermask min width value means that the user has set the value to 0 and
1177  // not the default value (0.25mm)
1178  designSettings.m_SolderMaskMinWidth = 0;
1179 
1180  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1181  {
1182  if( token != T_LEFT )
1183  Expecting( T_LEFT );
1184 
1185  token = NextTok();
1186 
1187  switch( token )
1188  {
1189  case T_last_trace_width: // not used now
1190  /* lastTraceWidth =*/ parseBoardUnits( T_last_trace_width );
1191  NeedRIGHT();
1192  break;
1193 
1194  case T_user_trace_width:
1195  designSettings.m_TrackWidthList.push_back( parseBoardUnits( T_user_trace_width ) );
1196  NeedRIGHT();
1197  break;
1198 
1199  case T_trace_clearance:
1200  defaultNetClass->SetClearance( parseBoardUnits( T_trace_clearance ) );
1201  NeedRIGHT();
1202  break;
1203 
1204  case T_zone_clearance:
1205  zoneSettings.m_ZoneClearance = parseBoardUnits( T_zone_clearance );
1206  NeedRIGHT();
1207  break;
1208 
1209  case T_zone_45_only:
1210  zoneSettings.m_Zone_45_Only = parseBool();
1211  NeedRIGHT();
1212  break;
1213 
1214  case T_trace_min:
1215  designSettings.m_TrackMinWidth = parseBoardUnits( T_trace_min );
1216  NeedRIGHT();
1217  break;
1218 
1219  case T_via_size:
1220  defaultNetClass->SetViaDiameter( parseBoardUnits( T_via_size ) );
1221  NeedRIGHT();
1222  break;
1223 
1224  case T_via_drill:
1225  defaultNetClass->SetViaDrill( parseBoardUnits( T_via_drill ) );
1226  NeedRIGHT();
1227  break;
1228 
1229  case T_via_min_size:
1230  designSettings.m_ViasMinSize = parseBoardUnits( T_via_min_size );
1231  NeedRIGHT();
1232  break;
1233 
1234  case T_via_min_drill:
1235  designSettings.m_ViasMinDrill = parseBoardUnits( T_via_min_drill );
1236  NeedRIGHT();
1237  break;
1238 
1239  case T_user_via:
1240  {
1241  int viaSize = parseBoardUnits( "user via size" );
1242  int viaDrill = parseBoardUnits( "user via drill" );
1243  designSettings.m_ViasDimensionsList.push_back( VIA_DIMENSION( viaSize, viaDrill ) );
1244  NeedRIGHT();
1245  }
1246  break;
1247 
1248  case T_uvia_size:
1249  defaultNetClass->SetuViaDiameter( parseBoardUnits( T_uvia_size ) );
1250  NeedRIGHT();
1251  break;
1252 
1253  case T_uvia_drill:
1254  defaultNetClass->SetuViaDrill( parseBoardUnits( T_uvia_drill ) );
1255  NeedRIGHT();
1256  break;
1257 
1258  case T_uvias_allowed:
1259  designSettings.m_MicroViasAllowed = parseBool();
1260  NeedRIGHT();
1261  break;
1262 
1263  case T_blind_buried_vias_allowed:
1264  designSettings.m_BlindBuriedViaAllowed = parseBool();
1265  NeedRIGHT();
1266  break;
1267 
1268  case T_uvia_min_size:
1269  designSettings.m_MicroViasMinSize = parseBoardUnits( T_uvia_min_size );
1270  NeedRIGHT();
1271  break;
1272 
1273  case T_uvia_min_drill:
1274  designSettings.m_MicroViasMinDrill = parseBoardUnits( T_uvia_min_drill );
1275  NeedRIGHT();
1276  break;
1277 
1278  // 6.0 TODO: change these names, or leave them?
1279  // 6.0 TODO: add LAYER_CLASS_OTHERS read/write
1280  // 6.0 TODO: add m_TextItalic read/write
1281  // 6.0 TODO: add m_TextUpright read/write
1282 
1283  case T_segment_width:
1284  designSettings.m_LineThickness[ LAYER_CLASS_COPPER ] = parseBoardUnits( T_segment_width );
1285  NeedRIGHT();
1286  break;
1287 
1288  case T_edge_width:
1289  designSettings.m_LineThickness[ LAYER_CLASS_EDGES ] = parseBoardUnits( T_edge_width );
1290  NeedRIGHT();
1291  break;
1292 
1293  case T_mod_edge_width:
1294  designSettings.m_LineThickness[ LAYER_CLASS_SILK ] = parseBoardUnits( T_mod_edge_width );
1295  NeedRIGHT();
1296  break;
1297 
1298  case T_pcb_text_width:
1299  designSettings.m_TextThickness[ LAYER_CLASS_COPPER ] = parseBoardUnits( T_pcb_text_width );
1300  NeedRIGHT();
1301  break;
1302 
1303  case T_mod_text_width:
1304  designSettings.m_TextThickness[ LAYER_CLASS_SILK ] = parseBoardUnits( T_mod_text_width );
1305  NeedRIGHT();
1306  break;
1307 
1308  case T_pcb_text_size:
1309  designSettings.m_TextSize[ LAYER_CLASS_COPPER ].x = parseBoardUnits( "pcb text width" );
1310  designSettings.m_TextSize[ LAYER_CLASS_COPPER ].y = parseBoardUnits( "pcb text height" );
1311  NeedRIGHT();
1312  break;
1313 
1314  case T_mod_text_size:
1315  designSettings.m_TextSize[ LAYER_CLASS_SILK ].x = parseBoardUnits( "module text width" );
1316  designSettings.m_TextSize[ LAYER_CLASS_SILK ].y = parseBoardUnits( "module text height" );
1317  NeedRIGHT();
1318  break;
1319 
1320  case T_pad_size:
1321  {
1322  wxSize sz;
1323  sz.SetWidth( parseBoardUnits( "master pad width" ) );
1324  sz.SetHeight( parseBoardUnits( "master pad height" ) );
1325  designSettings.m_Pad_Master.SetSize( sz );
1326  NeedRIGHT();
1327  }
1328  break;
1329 
1330  case T_pad_drill:
1331  {
1332  int drillSize = parseBoardUnits( T_pad_drill );
1333  designSettings.m_Pad_Master.SetDrillSize( wxSize( drillSize, drillSize ) );
1334  NeedRIGHT();
1335  }
1336  break;
1337 
1338  case T_pad_to_mask_clearance:
1339  designSettings.m_SolderMaskMargin = parseBoardUnits( T_pad_to_mask_clearance );
1340  NeedRIGHT();
1341  break;
1342 
1343  case T_solder_mask_min_width:
1344  designSettings.m_SolderMaskMinWidth = parseBoardUnits( T_solder_mask_min_width );
1345  NeedRIGHT();
1346  break;
1347 
1348  case T_pad_to_paste_clearance:
1349  designSettings.m_SolderPasteMargin = parseBoardUnits( T_pad_to_paste_clearance );
1350  NeedRIGHT();
1351  break;
1352 
1353  case T_pad_to_paste_clearance_ratio:
1354  designSettings.m_SolderPasteMarginRatio = parseDouble( T_pad_to_paste_clearance_ratio );
1355  NeedRIGHT();
1356  break;
1357 
1358  case T_aux_axis_origin:
1359  {
1360  int x = parseBoardUnits( "auxiliary origin X" );
1361  int y = parseBoardUnits( "auxiliary origin Y" );
1362  // m_board->SetAuxOrigin( wxPoint( x, y ) ); gets overwritten via SetDesignSettings below
1363  designSettings.m_AuxOrigin = wxPoint( x, y );
1364  NeedRIGHT();
1365  }
1366  break;
1367 
1368  case T_grid_origin:
1369  {
1370  int x = parseBoardUnits( "grid origin X" );
1371  int y = parseBoardUnits( "grid origin Y" );
1372  // m_board->SetGridOrigin( wxPoint( x, y ) ); gets overwritten SetDesignSettings below
1373  designSettings.m_GridOrigin = wxPoint( x, y );
1374  NeedRIGHT();
1375  }
1376  break;
1377 
1378  case T_visible_elements:
1379  designSettings.SetVisibleElements( parseHex() | MIN_VISIBILITY_MASK );
1380  NeedRIGHT();
1381  break;
1382 
1383  case T_pcbplotparams:
1384  {
1385  PCB_PLOT_PARAMS plotParams;
1386  PCB_PLOT_PARAMS_PARSER parser( reader );
1387  // parser must share the same current line as our current PCB parser
1388  // synchronize it.
1389  parser.SyncLineReaderWith( *this );
1390 
1391  plotParams.Parse( &parser );
1392  SyncLineReaderWith( parser );
1393 
1394  m_board->SetPlotOptions( plotParams );
1395  }
1396  break;
1397 
1398  default:
1399  Unexpected( CurText() );
1400  }
1401  }
1402 
1403  m_board->SetDesignSettings( designSettings );
1404  m_board->SetZoneSettings( zoneSettings );
1405 }
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:559
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
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:534
void SetDrillSize(const wxSize &aSize)
Definition: class_pad.h:276
int parseBoardUnits()
Definition: pcb_parser.h:238
wxSize m_TextSize[LAYER_CLASS_COUNT]
bool parseBool()
Definition: pcb_parser.cpp:156
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
void SetSize(const wxSize &aSize)
Definition: class_pad.h:270
int m_ZoneClearance
Clearance value.
Definition: zone_settings.h:64
void SetDesignSettings(const BOARD_DESIGN_SETTINGS &aDesignSettings)
Function SetDesignSettings.
Definition: class_board.h:544
bool m_BlindBuriedViaAllowed
true to allow blind/buried vias
void SetPlotOptions(const PCB_PLOT_PARAMS &aOptions)
Definition: class_board.h:553
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:49
NETCLASSPTR GetDefault() const
Function GetDefault.
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.
const ZONE_SETTINGS & GetZoneSettings() const
Definition: class_board.h:558
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:126
bool m_MicroViasAllowed
true to allow micro vias
int m_MicroViasMinDrill
micro vias (not vias) min drill diameter
long parseHex()
Definition: pcb_parser.h:287
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.

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

◆ parseTEXTE_MODULE()

TEXTE_MODULE * PCB_PARSER::parseTEXTE_MODULE ( )
private

Definition at line 2187 of file pcb_parser.cpp.

2188 {
2189  wxCHECK_MSG( CurTok() == T_fp_text, NULL,
2190  wxString::Format( wxT( "Cannot parse %s as TEXTE_MODULE at line %d, offset %d." ),
2191  GetChars( GetTokenString( CurTok() ) ),
2192  CurLineNumber(), CurOffset() ) );
2193 
2194  T token = NextTok();
2195 
2196  std::unique_ptr<TEXTE_MODULE> text( new TEXTE_MODULE( NULL ) );
2197 
2198  switch( token )
2199  {
2200  case T_reference:
2201  text->SetType( TEXTE_MODULE::TEXT_is_REFERENCE );
2202  break;
2203 
2204  case T_value:
2205  text->SetType( TEXTE_MODULE::TEXT_is_VALUE );
2206  break;
2207 
2208  case T_user:
2209  break; // Default type is user text.
2210 
2211  default:
2212  THROW_IO_ERROR( wxString::Format( _( "Cannot handle footprint text type %s" ),
2213  GetChars( FromUTF8() ) ) );
2214  }
2215 
2216  NeedSYMBOLorNUMBER();
2217 
2218  text->SetText( FromUTF8() );
2219  NeedLEFT();
2220  token = NextTok();
2221 
2222  if( token != T_at )
2223  Expecting( T_at );
2224 
2225  wxPoint pt;
2226 
2227  pt.x = parseBoardUnits( "X coordinate" );
2228  pt.y = parseBoardUnits( "Y coordinate" );
2229  text->SetPos0( pt );
2230 
2231  NextTok();
2232 
2233  if( CurTok() == T_NUMBER )
2234  {
2235  text->SetTextAngle( parseDouble() * 10.0 );
2236  NextTok();
2237  }
2238 
2239  if( CurTok() == T_unlocked )
2240  {
2241  text->SetKeepUpright( false );
2242  NextTok();
2243  }
2244 
2245  if( CurTok() != T_RIGHT )
2246  {
2247  Unexpected( CurText() );
2248  }
2249 
2250  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2251  {
2252  if( token == T_LEFT )
2253  token = NextTok();
2254 
2255  switch( token )
2256  {
2257  case T_layer:
2258  text->SetLayer( parseBoardItemLayer() );
2259  NeedRIGHT();
2260  break;
2261 
2262  case T_hide:
2263  text->SetVisible( false );
2264  break;
2265 
2266  case T_effects:
2267  parseEDA_TEXT( (EDA_TEXT*) text.get() );
2268  break;
2269 
2270  default:
2271  Expecting( "hide or effects" );
2272  }
2273  }
2274 
2275  return text.release();
2276 }
void parseEDA_TEXT(EDA_TEXT *aText)
Function parseEDA_TEXT parses the common settings for any object derived from EDA_TEXT.
Definition: pcb_parser.cpp:240
int parseBoardUnits()
Definition: pcb_parser.h:238
Class EDA_TEXT is a mix-in class (via multiple inheritance) that handles texts such as labels,...
Definition: eda_text.h:128
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:100
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:126

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

◆ parseTEXTE_PCB()

TEXTE_PCB * PCB_PARSER::parseTEXTE_PCB ( )
private

Definition at line 1690 of file pcb_parser.cpp.

1691 {
1692  wxCHECK_MSG( CurTok() == T_gr_text, NULL,
1693  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as TEXTE_PCB." ) );
1694 
1695  T token;
1696 
1697  std::unique_ptr<TEXTE_PCB> text( new TEXTE_PCB( m_board ) );
1698  NeedSYMBOLorNUMBER();
1699 
1700  text->SetText( FromUTF8() );
1701  NeedLEFT();
1702  token = NextTok();
1703 
1704  if( token != T_at )
1705  Expecting( T_at );
1706 
1707  wxPoint pt;
1708 
1709  pt.x = parseBoardUnits( "X coordinate" );
1710  pt.y = parseBoardUnits( "Y coordinate" );
1711  text->SetTextPos( pt );
1712 
1713  // If there is no orientation defined, then it is the default value of 0 degrees.
1714  token = NextTok();
1715 
1716  if( token == T_NUMBER )
1717  {
1718  text->SetTextAngle( parseDouble() * 10.0 );
1719  NeedRIGHT();
1720  }
1721  else if( token != T_RIGHT )
1722  {
1723  Unexpected( CurText() );
1724  }
1725 
1726  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1727  {
1728  if( token != T_LEFT )
1729  Expecting( T_LEFT );
1730 
1731  token = NextTok();
1732 
1733  switch( token )
1734  {
1735  case T_layer:
1736  text->SetLayer( parseBoardItemLayer() );
1737  NeedRIGHT();
1738  break;
1739 
1740  case T_tstamp:
1741  text->SetTimeStamp( parseHex() );
1742  NeedRIGHT();
1743  break;
1744 
1745  case T_effects:
1746  parseEDA_TEXT( (EDA_TEXT*) text.get() );
1747  break;
1748 
1749  default:
1750  Expecting( "layer, tstamp or effects" );
1751  }
1752  }
1753 
1754  return text.release();
1755 }
void parseEDA_TEXT(EDA_TEXT *aText)
Function parseEDA_TEXT parses the common settings for any object derived from EDA_TEXT.
Definition: pcb_parser.cpp:240
int parseBoardUnits()
Definition: pcb_parser.h:238
Class EDA_TEXT is a mix-in class (via multiple inheritance) that handles texts such as labels,...
Definition: eda_text.h:128
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:126
long parseHex()
Definition: pcb_parser.h:287

References parseDouble(), and parseHex().

◆ parseTITLE_BLOCK()

void PCB_PARSER::parseTITLE_BLOCK ( )
private

Definition at line 806 of file pcb_parser.cpp.

807 {
808  wxCHECK_RET( CurTok() == T_title_block,
809  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
810  wxT( " as TITLE_BLOCK." ) );
811 
812  T token;
813  TITLE_BLOCK titleBlock;
814 
815  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
816  {
817  if( token != T_LEFT )
818  Expecting( T_LEFT );
819 
820  token = NextTok();
821 
822  switch( token )
823  {
824  case T_title:
825  NextTok();
826  titleBlock.SetTitle( FromUTF8() );
827  break;
828 
829  case T_date:
830  NextTok();
831  titleBlock.SetDate( FromUTF8() );
832  break;
833 
834  case T_rev:
835  NextTok();
836  titleBlock.SetRevision( FromUTF8() );
837  break;
838 
839  case T_company:
840  NextTok();
841  titleBlock.SetCompany( FromUTF8() );
842  break;
843 
844  case T_comment:
845  {
846  int commentNumber = parseInt( "comment" );
847 
848  switch( commentNumber )
849  {
850  case 1:
851  NextTok();
852  titleBlock.SetComment1( FromUTF8() );
853  break;
854 
855  case 2:
856  NextTok();
857  titleBlock.SetComment2( FromUTF8() );
858  break;
859 
860  case 3:
861  NextTok();
862  titleBlock.SetComment3( FromUTF8() );
863  break;
864 
865  case 4:
866  NextTok();
867  titleBlock.SetComment4( FromUTF8() );
868  break;
869 
870  default:
871  wxString err;
872  err.Printf( wxT( "%d is not a valid title block comment number" ), commentNumber );
873  THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
874  }
875  }
876  break;
877 
878  default:
879  Expecting( "title, date, rev, company, or comment" );
880  }
881 
882  NeedRIGHT();
883  }
884 
885  m_board->SetTitleBlock( titleBlock );
886 }
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:556
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,...
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:276

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.

◆ parseTRACK()

TRACK * PCB_PARSER::parseTRACK ( )
private

Definition at line 2896 of file pcb_parser.cpp.

2897 {
2898  wxCHECK_MSG( CurTok() == T_segment, NULL,
2899  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as TRACK." ) );
2900 
2901  wxPoint pt;
2902  T token;
2903 
2904  std::unique_ptr< TRACK > track( new TRACK( m_board ) );
2905 
2906  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2907  {
2908  if( token != T_LEFT )
2909  Expecting( T_LEFT );
2910 
2911  token = NextTok();
2912 
2913  switch( token )
2914  {
2915  case T_start:
2916  pt.x = parseBoardUnits( "start x" );
2917  pt.y = parseBoardUnits( "start y" );
2918  track->SetStart( pt );
2919  break;
2920 
2921  case T_end:
2922  pt.x = parseBoardUnits( "end x" );
2923  pt.y = parseBoardUnits( "end y" );
2924  track->SetEnd( pt );
2925  break;
2926 
2927  case T_width:
2928  track->SetWidth( parseBoardUnits( "width" ) );
2929  break;
2930 
2931  case T_layer:
2932  track->SetLayer( parseBoardItemLayer() );
2933  break;
2934 
2935  case T_net:
2936  if( ! track->SetNetCode( getNetCode( parseInt( "net number" ) ), /* aNoAssert */ true ) )
2938  wxString::Format( _( "Invalid net ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),
2939  GetChars( CurSource() ), CurLineNumber(), CurOffset() )
2940  );
2941  break;
2942 
2943  case T_tstamp:
2944  track->SetTimeStamp( parseHex() );
2945  break;
2946 
2947  case T_status:
2948  track->SetStatus( static_cast<STATUS_FLAGS>( parseHex() ) );
2949  break;
2950 
2951  default:
2952  Expecting( "start, end, width, layer, net, tstamp, or status" );
2953  }
2954 
2955  NeedRIGHT();
2956  }
2957 
2958  return track.release();
2959 }
int parseBoardUnits()
Definition: pcb_parser.h:238
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:100
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:82
BOARD * m_board
Definition: pcb_parser.h:70
long parseHex()
Definition: pcb_parser.h:287
int parseInt()
Definition: pcb_parser.h:276

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

◆ parseVersion()

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 171 of file pcb_parser.cpp.

172 {
173  if( NextTok() != T_version )
174  Expecting( GetTokenText( T_version ) );
175 
176  int pcb_version = parseInt( FromUTF8().mb_str( wxConvUTF8 ) );
177 
178  NeedRIGHT();
179 
180  return pcb_version;
181 }
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:276

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

◆ parseVIA()

VIA * PCB_PARSER::parseVIA ( )
private

Definition at line 2962 of file pcb_parser.cpp.

2963 {
2964  wxCHECK_MSG( CurTok() == T_via, NULL,
2965  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as VIA." ) );
2966 
2967  wxPoint pt;
2968  T token;
2969 
2970  std::unique_ptr< VIA > via( new VIA( m_board ) );
2971 
2972  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2973  {
2974  if( token == T_LEFT )
2975  token = NextTok();
2976 
2977  switch( token )
2978  {
2979  case T_blind:
2980  via->SetViaType( VIA_BLIND_BURIED );
2981  break;
2982 
2983  case T_micro:
2984  via->SetViaType( VIA_MICROVIA );
2985  break;
2986 
2987  case T_at:
2988  pt.x = parseBoardUnits( "start x" );
2989  pt.y = parseBoardUnits( "start y" );
2990  via->SetStart( pt );
2991  via->SetEnd( pt );
2992  NeedRIGHT();
2993  break;
2994 
2995  case T_size:
2996  via->SetWidth( parseBoardUnits( "via width" ) );
2997  NeedRIGHT();
2998  break;
2999 
3000  case T_drill:
3001  via->SetDrill( parseBoardUnits( "drill diameter" ) );
3002  NeedRIGHT();
3003  break;
3004 
3005  case T_layers:
3006  {
3007  PCB_LAYER_ID layer1, layer2;
3008  NextTok();
3009  layer1 = lookUpLayer<PCB_LAYER_ID>( m_layerIndices );
3010  NextTok();
3011  layer2 = lookUpLayer<PCB_LAYER_ID>( m_layerIndices );
3012  via->SetLayerPair( layer1, layer2 );
3013  NeedRIGHT();
3014  }
3015  break;
3016 
3017  case T_net:
3018  if(! via->SetNetCode( getNetCode( parseInt( "net number" ) ), /* aNoAssert */ true))
3020  wxString::Format( _( "Invalid net ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),
3021  GetChars( CurSource() ), CurLineNumber(), CurOffset() )
3022  );
3023  NeedRIGHT();
3024  break;
3025 
3026  case T_tstamp:
3027  via->SetTimeStamp( parseHex() );
3028  NeedRIGHT();
3029  break;
3030 
3031  case T_status:
3032  via->SetStatus( static_cast<STATUS_FLAGS>( parseHex() ) );
3033  NeedRIGHT();
3034  break;
3035 
3036  default:
3037  Expecting( "blind, micro, at, size, drill, layers, net, tstamp, or status" );
3038  }
3039  }
3040 
3041  return via.release();
3042 }
int parseBoardUnits()
Definition: pcb_parser.h:238
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:100
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:82
BOARD * m_board
Definition: pcb_parser.h:70
LAYER_ID_MAP m_layerIndices
map layer name to it's index
Definition: pcb_parser.h:71
long parseHex()
Definition: pcb_parser.h:287
int parseInt()
Definition: pcb_parser.h:276

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

◆ parseXY() [1/2]

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 208 of file pcb_parser.cpp.

209 {
210  if( CurTok() != T_LEFT )
211  NeedLEFT();
212 
213  wxPoint pt;
214  T token = NextTok();
215 
216  if( token != T_xy )
217  Expecting( T_xy );
218 
219  pt.x = parseBoardUnits( "X coordinate" );
220  pt.y = parseBoardUnits( "Y coordinate" );
221 
222  NeedRIGHT();
223 
224  return pt;
225 }
int parseBoardUnits()
Definition: pcb_parser.h:238

◆ parseXY() [2/2]

void PCB_PARSER::parseXY ( int *  aX,
int *  aY 
)
private

Definition at line 228 of file pcb_parser.cpp.

229 {
230  wxPoint pt = parseXY();
231 
232  if( aX )
233  *aX = pt.x;
234 
235  if( aY )
236  *aY = pt.y;
237 }
wxPoint parseXY()
Function parseXY parses a coordinate pair (xy X Y) in board units (mm).
Definition: pcb_parser.cpp:208

◆ parseZONE_CONTAINER()

ZONE_CONTAINER * PCB_PARSER::parseZONE_CONTAINER ( )
private

Definition at line 3045 of file pcb_parser.cpp.

3046 {
3047  wxCHECK_MSG( CurTok() == T_zone, NULL,
3048  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
3049  wxT( " as ZONE_CONTAINER." ) );
3050 
3052 
3053  int hatchPitch = ZONE_CONTAINER::GetDefaultHatchPitch();
3054  wxPoint pt;
3055  T token;
3056  int tmp;
3057  wxString netnameFromfile; // the zone net name find in file
3058 
3059  // bigger scope since each filled_polygon is concatenated in here
3060  SHAPE_POLY_SET pts;
3061 
3062  std::unique_ptr< ZONE_CONTAINER > zone( new ZONE_CONTAINER( m_board ) );
3063 
3064  zone->SetPriority( 0 );
3065 
3066  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3067  {
3068  if( token == T_LEFT )
3069  token = NextTok();
3070 
3071  switch( token )
3072  {
3073  case T_net:
3074  // Init the net code only, not the netname, to be sure
3075  // the zone net name is the name read in file.
3076  // (When mismatch, the user will be prompted in DRC, to fix the actual name)
3077  tmp = getNetCode( parseInt( "net number" ) );
3078 
3079  if( tmp < 0 )
3080  tmp = 0;
3081 
3082  if( ! zone->SetNetCode( tmp, /* aNoAssert */ true ) )
3084  wxString::Format( _( "Invalid net ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),
3085  GetChars( CurSource() ), CurLineNumber(), CurOffset() )
3086  );
3087 
3088  NeedRIGHT();
3089  break;
3090 
3091  case T_net_name:
3092  NeedSYMBOLorNUMBER();
3093  netnameFromfile = FromUTF8();
3094  NeedRIGHT();
3095  break;
3096 
3097  case T_layer: // keyword for zones that are on only one layer
3098  zone->SetLayer( parseBoardItemLayer() );
3099  NeedRIGHT();
3100  break;
3101 
3102  case T_layers: // keyword for zones that can live on a set of layer
3103  // currently: keepout zones
3104  zone->SetLayerSet( parseBoardItemLayersAsMask() );
3105  break;
3106 
3107  case T_tstamp:
3108  zone->SetTimeStamp( parseHex() );
3109  NeedRIGHT();
3110  break;
3111 
3112  case T_hatch:
3113  token = NextTok();
3114 
3115  if( token != T_none && token != T_edge && token != T_full )
3116  Expecting( "none, edge, or full" );
3117 
3118  switch( token )
3119  {
3120  default:
3121  case T_none: hatchStyle = ZONE_CONTAINER::NO_HATCH; break;
3122  case T_edge: hatchStyle = ZONE_CONTAINER::DIAGONAL_EDGE; break;
3123  case T_full: hatchStyle = ZONE_CONTAINER::DIAGONAL_FULL;
3124  }
3125 
3126  hatchPitch = parseBoardUnits( "hatch pitch" );
3127  NeedRIGHT();
3128  break;
3129 
3130  case T_priority:
3131  zone->SetPriority( parseInt( "zone priority" ) );
3132  NeedRIGHT();
3133  break;
3134 
3135  case T_connect_pads:
3136  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3137  {
3138  if( token == T_LEFT )
3139  token = NextTok();
3140 
3141  switch( token )
3142  {
3143  case T_yes:
3144  zone->SetPadConnection( PAD_ZONE_CONN_FULL );
3145  break;
3146 
3147  case T_no:
3148  zone->SetPadConnection( PAD_ZONE_CONN_NONE );
3149  break;
3150 
3151  case T_thru_hole_only:
3152  zone->SetPadConnection( PAD_ZONE_CONN_THT_THERMAL );
3153  break;
3154 
3155  case T_clearance:
3156  zone->SetZoneClearance( parseBoardUnits( "zone clearance" ) );
3157  NeedRIGHT();
3158  break;
3159 
3160  default:
3161  Expecting( "yes, no, or clearance" );
3162  }
3163  }
3164 
3165  break;
3166 
3167  case T_min_thickness:
3168  zone->SetMinThickness( parseBoardUnits( T_min_thickness ) );
3169  NeedRIGHT();
3170  break;
3171 
3172  case T_fill:
3173  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3174  {
3175  if( token == T_LEFT )
3176  token = NextTok();
3177 
3178  switch( token )
3179  {
3180  case T_yes:
3181  zone->SetIsFilled( true );
3182  break;
3183 
3184  case T_mode:
3185  token = NextTok();
3186 
3187  if( token != T_segment && token != T_hatch && token != T_polygon )
3188  Expecting( "segment, hatch or polygon" );
3189 
3190  if( token == T_segment ) // deprecated
3191  {
3192  // SEGMENT fill mode no longer supported. Make sure user is OK with converting them.
3194  {
3195  KIDIALOG dlg( nullptr,
3196  _( "The legacy segment fill mode is no longer supported.\n"
3197  "Convert zones to polygon fills?"),
3198  _( "Legacy Zone Warning" ),
3199  wxYES_NO | wxICON_WARNING );
3200 
3201  dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
3202 
3203  if( dlg.ShowModal() == wxID_NO )
3204  THROW_IO_ERROR( wxT( "CANCEL" ) );
3205 
3206  m_showLegacyZoneWarning = false;
3207  }
3208 
3209  zone->SetFillMode( ZFM_POLYGONS );
3210  m_board->SetModified();
3211  }
3212  else if( token == T_hatch )
3213  zone->SetFillMode( ZFM_HATCH_PATTERN );
3214  else
3215  zone->SetFillMode( ZFM_POLYGONS );
3216  NeedRIGHT();
3217  break;
3218 
3219  case T_hatch_thickness:
3220  zone->SetHatchFillTypeThickness( parseBoardUnits( T_hatch_thickness ) );
3221  NeedRIGHT();
3222  break;
3223 
3224  case T_hatch_gap:
3225  zone->SetHatchFillTypeGap( parseBoardUnits( T_hatch_gap ) );
3226  NeedRIGHT();
3227  break;
3228 
3229  case T_hatch_orientation:
3230  zone->SetHatchFillTypeOrientation( parseDouble( T_hatch_orientation ) );
3231  NeedRIGHT();
3232  break;
3233 
3234  case T_hatch_smoothing_level:
3235  zone->SetHatchFillTypeSmoothingLevel( parseDouble( T_hatch_smoothing_level ) );
3236  NeedRIGHT();
3237  break;
3238 
3239  case T_hatch_smoothing_value:
3240  zone->SetHatchFillTypeSmoothingValue( parseDouble( T_hatch_smoothing_value ) );
3241  NeedRIGHT();
3242  break;
3243 
3244  case T_arc_segments:
3245  zone->SetArcSegmentCount( parseInt( "arc segment count" ) );
3246  NeedRIGHT();
3247  break;
3248 
3249  case T_thermal_gap:
3250  zone->SetThermalReliefGap( parseBoardUnits( T_thermal_gap ) );
3251  NeedRIGHT();
3252  break;
3253 
3254  case T_thermal_bridge_width:
3255  zone->SetThermalReliefCopperBridge( parseBoardUnits( T_thermal_bridge_width ) );
3256  NeedRIGHT();
3257  break;
3258 
3259  case T_smoothing:
3260  switch( NextTok() )
3261  {
3262  case T_none:
3263  zone->SetCornerSmoothingType( ZONE_SETTINGS::SMOOTHING_NONE );
3264  break;
3265 
3266  case T_chamfer:
3267  if( !zone->GetIsKeepout() ) // smoothing has meaning only for filled zones
3268  zone->SetCornerSmoothingType( ZONE_SETTINGS::SMOOTHING_CHAMFER );
3269  break;
3270 
3271  case T_fillet:
3272  if( !zone->GetIsKeepout() ) // smoothing has meaning only for filled zones
3273  zone->SetCornerSmoothingType( ZONE_SETTINGS::SMOOTHING_FILLET );
3274  break;
3275 
3276  default:
3277  Expecting( "none, chamfer, or fillet" );
3278  }
3279  NeedRIGHT();
3280  break;
3281 
3282  case T_radius:
3283  tmp = parseBoardUnits( "corner radius" );
3284  if( !zone->GetIsKeepout() ) // smoothing has meaning only for filled zones
3285  zone->SetCornerRadius( tmp );
3286  NeedRIGHT();
3287  break;
3288 
3289  default:
3290  Expecting( "mode, arc_segments, thermal_gap, thermal_bridge_width, "
3291  "hatch_thickness, hatch_gap, hatch_orientation, "
3292  "hatch_smoothing_level, hatch_smoothing_value, smoothing, or radius" );
3293  }
3294  }
3295  break;
3296 
3297  case T_keepout:
3298  zone->SetIsKeepout( true );
3299 
3300  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3301  {
3302  if( token == T_LEFT )
3303  token = NextTok();
3304 
3305  switch( token )
3306  {
3307  case T_tracks:
3308  token = NextTok();
3309 
3310  if( token != T_allowed && token != T_not_allowed )
3311  Expecting( "allowed or not_allowed" );
3312  zone->SetDoNotAllowTracks( token == T_not_allowed );
3313  break;
3314 
3315  case T_vias:
3316  token = NextTok();
3317 
3318  if( token != T_allowed && token != T_not_allowed )
3319  Expecting( "allowed or not_allowed" );
3320  zone->SetDoNotAllowVias( token == T_not_allowed );
3321  break;
3322 
3323  case T_copperpour:
3324  token = NextTok();
3325 
3326  if( token != T_allowed && token != T_not_allowed )
3327  Expecting( "allowed or not_allowed" );
3328  zone->SetDoNotAllowCopperPour( token == T_not_allowed );
3329  break;
3330 
3331  default:
3332  Expecting( "tracks, vias or copperpour" );
3333  }
3334 
3335  NeedRIGHT();
3336  }
3337 
3338  break;
3339 
3340  case T_polygon:
3341  {
3342  std::vector< wxPoint > corners;
3343 
3344  NeedLEFT();
3345  token = NextTok();
3346 
3347  if( token != T_pts )
3348  Expecting( T_pts );
3349 
3350  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3351  {
3352  corners.push_back( parseXY() );
3353  }
3354 
3355  NeedRIGHT();
3356 
3357  // Remark: The first polygon is the main outline.
3358  // Others are holes inside the main outline.
3359  zone->AddPolygon( corners );
3360  }
3361  break;
3362 
3363  case T_filled_polygon:
3364  {
3365  // "(filled_polygon (pts"
3366  NeedLEFT();
3367  token = NextTok();
3368 
3369  if( token != T_pts )
3370  Expecting( T_pts );
3371 
3372  pts.NewOutline();
3373 
3374  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3375  {
3376  pts.Append( parseXY() );
3377  }
3378 
3379  NeedRIGHT();
3380  }
3381  break;
3382 
3383  case T_fill_segments:
3384  {
3385  ZONE_SEGMENT_FILL segs;
3386 
3387  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3388  {
3389  if( token != T_LEFT )
3390  Expecting( T_LEFT );
3391 
3392  token = NextTok();
3393 
3394  if( token != T_pts )
3395  Expecting( T_pts );
3396 
3397  SEG segment( parseXY(), parseXY() );
3398  NeedRIGHT();
3399  segs.push_back( segment );
3400  }
3401 
3402  zone->SetFillSegments( segs );
3403  }
3404  break;
3405 
3406  default:
3407  Expecting( "net, layer/layers, tstamp, hatch, priority, connect_pads, min_thickness, "
3408  "fill, polygon, filled_polygon, or fill_segments" );
3409  }
3410  }
3411 
3412  if( zone->GetNumCorners() > 2 )
3413  {
3414  if( !zone->IsOnCopperLayer() )
3415  {
3416  //zone->SetFillMode( ZFM_POLYGONS );
3417  zone->SetNetCode( NETINFO_LIST::UNCONNECTED );
3418  }
3419 
3420  // Set hatch here, after outlines corners are read
3421  zone->SetHatch( hatchStyle, hatchPitch, true );
3422  }
3423 
3424  if( !pts.IsEmpty() )
3425  zone->SetFilledPolysList( pts );
3426 
3427  // Ensure keepout and non copper zones do not have a net
3428  // (which have no sense for these zones)
3429  // the netcode 0 is used for these zones
3430  bool zone_has_net = zone->IsOnCopperLayer() && !zone->GetIsKeepout();
3431 
3432  if( !zone_has_net )
3433  zone->SetNetCode( NETINFO_LIST::UNCONNECTED );
3434 
3435  // Ensure the zone net name is valid, and matches the net code, for copper zones
3436  if( zone_has_net && ( zone->GetNet()->GetNetname() != netnameFromfile ) )
3437  {
3438  // Can happens which old boards, with nonexistent nets ...
3439  // or after being edited by hand
3440  // We try to fix the mismatch.
3441  NETINFO_ITEM* net = m_board->FindNet( netnameFromfile );
3442 
3443  if( net ) // An existing net has the same net name. use it for the zone
3444  zone->SetNetCode( net->GetNet() );
3445  else // Not existing net: add a new net to keep trace of the zone netname
3446  {
3447  int newnetcode = m_board->GetNetCount();
3448  net = new NETINFO_ITEM( m_board, netnameFromfile, newnetcode );
3449  m_board->Add( net );
3450 
3451  // Store the new code mapping
3452  pushValueIntoMap( newnetcode, net->GetNet() );
3453  // and update the zone netcode
3454  zone->SetNetCode( net->GetNet() );
3455 
3456  // FIXME: a call to any GUI item is not allowed in io plugins:
3457  // Change this code to generate a warning message outside this plugin
3458  // Prompt the user
3459  wxString msg;
3460  msg.Printf( _( "There is a zone that belongs to a not existing net\n"
3461  "\"%s\"\n"
3462  "you should verify and edit it (run DRC test)." ),
3463  GetChars( netnameFromfile ) );
3464  DisplayError( NULL, msg );
3465  }
3466  }
3467 
3468  // Clear flags used in zone edition:
3469  zone->SetNeedRefill( false );
3470 
3471  return zone.release();
3472 }
NETINFO_ITEM * FindNet(int aNetcode) const
Function FindNet searches for a net with the given netcode.
void SetModified()
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.
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition: confirm.h:44
bool IsEmpty() const
Returns true if the set is empty (no polygons at all)
wxPoint parseXY()
Function parseXY parses a coordinate pair (xy X Y) in board units (mm).
Definition: pcb_parser.cpp:208
static int GetDefaultHatchPitch()
Function GetDefaultHatchPitchMils.
int parseBoardUnits()
Definition: pcb_parser.h:238
Pads are not covered.
Definition: zones.h:52
unsigned GetNetCount() const
Function GetNetCount.
Definition: class_board.h:777
Class SHAPE_POLY_SET.
void SetNetCode(int aNetCode)
Definition: netinfo.h:229
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_INSERT) override
Adds an item to the container.
PCB_LAYER_ID parseBoardItemLayer()
Function parseBoardItemLayer parses the layer definition of a BOARD_ITEM object.
#define THROW_IO_ERROR(msg)
HATCH_STYLE
Zone hatch styles.
Definition: class_zone.h:66
bool m_showLegacyZoneWarning
Definition: pcb_parser.h:78
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:65
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:100
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 GetNet() const
Function GetNet.
Definition: netinfo.h:227
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:82
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:115
double parseDouble()
Function parseDouble parses the current token as an ASCII numeric string with possible leading whites...
Definition: pcb_parser.cpp:126
long parseHex()
Definition: pcb_parser.h:287
int parseInt()
Definition: pcb_parser.h:276
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:244
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
Definition: netinfo.h:465
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)

References SHAPE_POLY_SET::Append(), ZONE_CONTAINER::DIAGONAL_EDGE, ZONE_CONTAINER::DIAGONAL_FULL, DisplayError(), KIDIALOG::DoNotShowCheckbox(), 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, parseDouble(), parseHex(), parseInt(), NETINFO_ITEM::SetNetCode(), KIDIALOG::ShowModal(), ZONE_SETTINGS::SMOOTHING_CHAMFER, ZONE_SETTINGS::SMOOTHING_FILLET, ZONE_SETTINGS::SMOOTHING_NONE, THROW_IO_ERROR, NETINFO_LIST::UNCONNECTED, ZFM_HATCH_PATTERN, and ZFM_POLYGONS.

◆ pushValueIntoMap()

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 115 of file pcb_parser.cpp.

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

◆ SetBoard()

void PCB_PARSER::SetBoard ( BOARD aBoard)
inline

Definition at line 325 of file pcb_parser.h.

326  {
327  init();
328  m_board = aBoard;
329  }
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:57

References init(), and m_board.

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

◆ SetLineReader()

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 318 of file pcb_parser.h.

319  {
320  LINE_READER* ret = PopReader();
321  PushReader( aReader );
322  return ret;
323  }
Class LINE_READER is an abstract class from which implementation specific LINE_READERs may be derived...
Definition: richio.h:81

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

Member Data Documentation

◆ m_board

BOARD* PCB_PARSER::m_board
private

Definition at line 70 of file pcb_parser.h.

Referenced by SetBoard().

◆ m_layerIndices

LAYER_ID_MAP PCB_PARSER::m_layerIndices
private

map layer name to it's index

Definition at line 71 of file pcb_parser.h.

◆ m_layerMasks

LSET_MAP PCB_PARSER::m_layerMasks
private

map layer names to their masks

Definition at line 72 of file pcb_parser.h.

◆ m_netCodes

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

net codes mapping for boards being loaded

Definition at line 74 of file pcb_parser.h.

Referenced by getNetCode().

◆ m_requiredVersion

int PCB_PARSER::m_requiredVersion
private

set to the KiCad format version this board requires

Definition at line 76 of file pcb_parser.h.

◆ m_showLegacyZoneWarning

bool PCB_PARSER::m_showLegacyZoneWarning
private

Definition at line 78 of file pcb_parser.h.

◆ m_tooRecent

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

◆ m_undefinedLayers

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: