KiCad PCB EDA Suite
PCB_PARSER Class Reference

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 skipCurrent ()
 Function skipCurrent Skip the current token level, i.e search for the RIGHT parenthesis which closes the current description. More...
 
void parseHeader ()
 
void parseGeneralSection ()
 
void parsePAGE_INFO ()
 
void parseTITLE_BLOCK ()
 
void parseLayers ()
 
void parseLayer (LAYER *aLayer)
 
void parseBoardStackup ()
 
void parseSetup ()
 
void parseDefaults (BOARD_DESIGN_SETTINGS &aSettings)
 
void parseDefaultTextDims (BOARD_DESIGN_SETTINGS &aSettings, int aLayer)
 
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)
 
ARCparseARC ()
 
TRACKparseTRACK ()
 
VIAparseVIA ()
 
ZONE_CONTAINERparseZONE_CONTAINER (BOARD_ITEM_CONTAINER *aParent)
 
PCB_TARGETparsePCB_TARGET ()
 
MARKER_PCBparseMARKER (BOARD_ITEM_CONTAINER *aParent)
 
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

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

Definition at line 69 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 71 of file pcb_parser.h.

◆ LSET_MAP

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

Definition at line 72 of file pcb_parser.h.

Constructor & Destructor Documentation

◆ PCB_PARSER()

PCB_PARSER::PCB_PARSER ( LINE_READER aReader = NULL)
inline

Definition at line 320 of file pcb_parser.h.

320  :
321  PCB_LEXER( aReader ),
322  m_board( 0 )
323  {
324  init();
325  }
BOARD * m_board
Definition: pcb_parser.h:74
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 1178 of file pcb_parser.cpp.

1179 {
1180  // N.B. This mapping only includes Italian, Polish and French as they were the only languages that
1181  // mapped the layer names as of cc2022b1ac739aa673d2a0b7a2047638aa7a47b3 (kicad-i18n) when the
1182  // bug was fixed in KiCad source.
1183 
1184  // Italian
1185  aMap["Adesivo.Retro"] = "B.Adhes";
1186  aMap["Adesivo.Fronte"] = "F.Adhes";
1187  aMap["Pasta.Retro"] = "B.Paste";
1188  aMap["Pasta.Fronte"] = "F.Paste";
1189  aMap["Serigrafia.Retro"] = "B.SilkS";
1190  aMap["Serigrafia.Fronte"] = "F.SilkS";
1191  aMap["Maschera.Retro"] = "B.Mask";
1192  aMap["Maschera.Fronte"] = "F.Mask";
1193  aMap["Grafica"] = "Dwgs.User";
1194  aMap["Commenti"] = "Cmts.User";
1195  aMap["Eco1"] = "Eco1.User";
1196  aMap["Eco2"] = "Eco2.User";
1197  aMap["Contorno.scheda"] = "Edge.Cuts";
1198 
1199  // Polish
1200  aMap["Kleju_Dolna"] = "B.Adhes";
1201  aMap["Kleju_Gorna"] = "F.Adhes";
1202  aMap["Pasty_Dolna"] = "B.Paste";
1203  aMap["Pasty_Gorna"] = "F.Paste";
1204  aMap["Opisowa_Dolna"] = "B.SilkS";
1205  aMap["Opisowa_Gorna"] = "F.SilkS";
1206  aMap["Maski_Dolna"] = "B.Mask";
1207  aMap["Maski_Gorna"] = "F.Mask";
1208  aMap["Rysunkowa"] = "Dwgs.User";
1209  aMap["Komentarzy"] = "Cmts.User";
1210  aMap["ECO1"] = "Eco1.User";
1211  aMap["ECO2"] = "Eco2.User";
1212  aMap["Krawedziowa"] = "Edge.Cuts";
1213 
1214  // French
1215  aMap["Dessous.Adhes"] = "B.Adhes";
1216  aMap["Dessus.Adhes"] = "F.Adhes";
1217  aMap["Dessous.Pate"] = "B.Paste";
1218  aMap["Dessus.Pate"] = "F.Paste";
1219  aMap["Dessous.SilkS"] = "B.SilkS";
1220  aMap["Dessus.SilkS"] = "F.SilkS";
1221  aMap["Dessous.Masque"] = "B.Mask";
1222  aMap["Dessus.Masque"] = "F.Mask";
1223  aMap["Dessin.User"] = "Dwgs.User";
1224  aMap["Contours.Ci"] = "Edge.Cuts";
1225 }

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

87  {
88  if( ( aNetCode >= 0 ) && ( aNetCode < (int) m_netCodes.size() ) )
89  return m_netCodes[aNetCode];
90 
91  return aNetCode;
92  }
std::vector< int > m_netCodes
net codes mapping for boards being loaded
Definition: pcb_parser.h:78

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

208 {
209  int year, month, day;
210 
211  year = m_requiredVersion / 10000;
212  month = ( m_requiredVersion / 100 ) - ( year * 100 );
213  day = m_requiredVersion - ( year * 10000 ) - ( month * 100 );
214 
215  // wx throws an assertion, not a catchable exception, when the date is invalid.
216  // User input shouldn't give wx asserts, so check manually and throw a proper
217  // error instead
218  if( day <= 0 || month <= 0 || month > 12 ||
219  day > wxDateTime::GetNumberOfDays( (wxDateTime::Month)( month - 1 ), year ) )
220  {
221  wxString err;
222  err.Printf( _( "Cannot interpret date code %d" ), m_requiredVersion );
223  THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
224  }
225 
226  wxDateTime date( day, (wxDateTime::Month)( month - 1 ), year, 0, 0, 0, 0 );
227  return date.FormatDate();
228 }
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
int m_requiredVersion
set to the KiCad format version this board requires
Definition: pcb_parser.h:80
#define _(s)
Definition: 3d_actions.cpp:33

References _, 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[ "*In.Cu" ] = LSET::InternalCuMask();
78  m_layerMasks[ "F&B.Cu" ] = LSET( 2, F_Cu, B_Cu );
79  m_layerMasks[ "*.Adhes" ] = LSET( 2, B_Adhes, F_Adhes );
80  m_layerMasks[ "*.Paste" ] = LSET( 2, B_Paste, F_Paste );
81  m_layerMasks[ "*.Mask" ] = LSET( 2, B_Mask, F_Mask );
82  m_layerMasks[ "*.SilkS" ] = LSET( 2, B_SilkS, F_SilkS );
83  m_layerMasks[ "*.Fab" ] = LSET( 2, B_Fab, F_Fab );
84  m_layerMasks[ "*.CrtYd" ] = LSET( 2, B_CrtYd, F_CrtYd );
85 
86  // This is for the first pretty & *.kicad_pcb formats, which had
87  // Inner1_Cu - Inner14_Cu with the numbering sequence
88  // reversed from the subsequent format's In1_Cu - In30_Cu numbering scheme.
89  // The newer format brought in an additional 16 Cu layers and flipped the cu stack but
90  // kept the gap between one of the outside layers and the last cu internal.
91 
92  for( int i=1; i<=14; ++i )
93  {
94  std::string key = StrPrintf( "Inner%d.Cu", i );
95 
96  m_layerMasks[ key ] = LSET( PCB_LAYER_ID( In15_Cu - i ) );
97  }
98 
99 #if defined(DEBUG) && 0
100  printf( "m_layerMasks:\n" );
101  for( LSET_MAP::const_iterator it = m_layerMasks.begin(); it != m_layerMasks.end(); ++it )
102  {
103  printf( " [%s] == 0x%s\n", it->first.c_str(), it->second.FmtHex().c_str() );
104  }
105 
106  printf( "m_layerIndices:\n" );
107  for( LAYER_ID_MAP::const_iterator it = m_layerIndices.begin(); it != m_layerIndices.end(); ++it )
108  {
109  printf( " [%s] == %d\n", it->first.c_str(), it->second );
110  }
111 #endif
112 
113 }
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:686
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:79
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:48
PCB_LAYER_ID
A quick note on layer IDs:
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:78
static LSET InternalCuMask()
Function InternalCuMask() returns a complete set of internal copper layers, which is all Cu layers ex...
Definition: lset.cpp:646
bool m_showLegacyZoneWarning
Definition: pcb_parser.h:82
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:80
LAYER_ID_MAP m_layerIndices
map layer name to it's index
Definition: pcb_parser.h:75
LSET_MAP m_layerMasks
map layer names to their masks
Definition: pcb_parser.h:76

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, In15_Cu, LSET::InternalCuMask(), 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 360 of file pcb_parser.h.

361  {
362  return m_tooRecent;
363  }
bool m_tooRecent
true if version parses as later than supported
Definition: pcb_parser.h:79

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

1356 {
1357  // avoid constructing another std::string, use lexer's directly
1358  typename M::const_iterator it = aMap.find( curText );
1359 
1360  if( it == aMap.end() )
1361  {
1362 #if 0 && defined(DEBUG)
1363  // dump the whole darn table, there's something wrong with it.
1364  for( it = aMap.begin(); it != aMap.end(); ++it )
1365  {
1366  wxLogDebug( &aMap == (void*)&m_layerIndices ? wxT( "lm[%s] = %d" ) :
1367  wxT( "lm[%s] = %08X" ), it->first.c_str(), it->second );
1368  }
1369 #endif
1370 
1371  m_undefinedLayers.insert( curText );
1372  return Rescue;
1373  }
1374 
1375  return it->second;
1376 }
LAYER_ID_MAP m_layerIndices
map layer name to it's index
Definition: pcb_parser.h:75
std::set< wxString > m_undefinedLayers
set of layers not defined in layers section
Definition: pcb_parser.h:77

References Rescue.

◆ Parse()

BOARD_ITEM * PCB_PARSER::Parse ( )

Definition at line 467 of file pcb_parser.cpp.

468 {
469  T token;
470  BOARD_ITEM* item;
471  LOCALE_IO toggle;
472 
473  // MODULEs can be prefixed with an initial block of single line comments and these
474  // are kept for Format() so they round trip in s-expression form. BOARDs might
475  // eventually do the same, but currently do not.
476  std::unique_ptr<wxArrayString> initial_comments( ReadCommentLines() );
477 
478  token = CurTok();
479 
480  if( token != T_LEFT )
481  Expecting( T_LEFT );
482 
483  switch( NextTok() )
484  {
485  case T_kicad_pcb:
486  if( m_board == NULL )
487  m_board = new BOARD();
488 
489  item = (BOARD_ITEM*) parseBOARD();
490  break;
491 
492  case T_module:
493  item = (BOARD_ITEM*) parseMODULE( initial_comments.release() );
494  break;
495 
496  default:
497  wxString err;
498  err.Printf( _( "Unknown token \"%s\"" ), GetChars( FromUTF8() ) );
499  THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
500  }
501 
502  return item;
503 }
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: common.h:202
BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class,...
BOARD * parseBOARD()
Definition: pcb_parser.cpp:506
#define NULL
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
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:101
BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:163
#define _(s)
Definition: 3d_actions.cpp:33
BOARD * m_board
Definition: pcb_parser.h:74
MODULE * parseMODULE(wxArrayString *aInitialComments=0)
Function parseMODULE.

References _, GetChars(), NULL, and THROW_PARSE_ERROR.

Referenced by GITHUB_PLUGIN::FootprintLoad(), CLIPBOARD_IO::Load(), PCB_IO::Load(), FP_CACHE::Load(), parse(), PCB_IO::Parse(), KI_TEST::ReadBoardItemFromFile(), and KI_TEST::ReadBoardItemFromStream().

◆ parse3DModel()

MODULE_3D_SETTINGS * PCB_PARSER::parse3DModel ( )
private

Definition at line 375 of file pcb_parser.cpp.

376 {
377  wxCHECK_MSG( CurTok() == T_model, NULL,
378  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as MODULE_3D_SETTINGS." ) );
379 
380  T token;
381 
383  NeedSYMBOLorNUMBER();
384  n3D->m_Filename = FromUTF8();
385 
386  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
387  {
388  if( token != T_LEFT )
389  Expecting( T_LEFT );
390 
391  token = NextTok();
392 
393  switch( token )
394  {
395  case T_at:
396  NeedLEFT();
397  token = NextTok();
398 
399  if( token != T_xyz )
400  Expecting( T_xyz );
401 
402  /* Note:
403  * Prior to KiCad v5, model offset was designated by "at",
404  * and the units were in inches.
405  * Now we use mm, but support reading of legacy files
406  */
407 
408  n3D->m_Offset.x = parseDouble( "x value" ) * 25.4f;
409  n3D->m_Offset.y = parseDouble( "y value" ) * 25.4f;
410  n3D->m_Offset.z = parseDouble( "z value" ) * 25.4f;
411  NeedRIGHT();
412  break;
413 
414  case T_offset:
415  NeedLEFT();
416  token = NextTok();
417 
418  if( token != T_xyz )
419  Expecting( T_xyz );
420 
421  /*
422  * 3D model offset is in mm
423  */
424  n3D->m_Offset.x = parseDouble( "x value" );
425  n3D->m_Offset.y = parseDouble( "y value" );
426  n3D->m_Offset.z = parseDouble( "z value" );
427  NeedRIGHT();
428  break;
429 
430  case T_scale:
431  NeedLEFT();
432  token = NextTok();
433 
434  if( token != T_xyz )
435  Expecting( T_xyz );
436 
437  n3D->m_Scale.x = parseDouble( "x value" );
438  n3D->m_Scale.y = parseDouble( "y value" );
439  n3D->m_Scale.z = parseDouble( "z value" );
440  NeedRIGHT();
441  break;
442 
443  case T_rotate:
444  NeedLEFT();
445  token = NextTok();
446 
447  if( token != T_xyz )
448  Expecting( T_xyz );
449 
450  n3D->m_Rotation.x = parseDouble( "x value" );
451  n3D->m_Rotation.y = parseDouble( "y value" );
452  n3D->m_Rotation.z = parseDouble( "z value" );
453  NeedRIGHT();
454  break;
455 
456  default:
457  Expecting( "at, offset, scale, or rotate" );
458  }
459 
460  NeedRIGHT();
461  }
462 
463  return n3D;
464 }
VECTOR3D m_Offset
3D model offset (mm)
Definition: class_module.h:99
#define NULL
wxString m_Filename
The 3D shape filename in 3D library.
Definition: class_module.h:100
VECTOR3D m_Rotation
3D model rotation (degrees)
Definition: class_module.h:98
VECTOR3D m_Scale
3D model scaling factor (dimensionless)
Definition: class_module.h:97
double parseDouble()
Function parseDouble parses the current token as an ASCII numeric string with possible leading whites...
Definition: pcb_parser.cpp:149

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

◆ parseARC()

ARC * PCB_PARSER::parseARC ( )
private

Definition at line 3381 of file pcb_parser.cpp.

3382 {
3383  wxCHECK_MSG( CurTok() == T_arc, NULL,
3384  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as ARC." ) );
3385 
3386  wxPoint pt;
3387  T token;
3388 
3389  std::unique_ptr<ARC> arc( new ARC( m_board ) );
3390 
3391  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3392  {
3393  if( token != T_LEFT )
3394  Expecting( T_LEFT );
3395 
3396  token = NextTok();
3397 
3398  switch( token )
3399  {
3400  case T_start:
3401  pt.x = parseBoardUnits( "start x" );
3402  pt.y = parseBoardUnits( "start y" );
3403  arc->SetStart( pt );
3404  break;
3405 
3406  case T_mid:
3407  pt.x = parseBoardUnits( "mid x" );
3408  pt.y = parseBoardUnits( "mid y" );
3409  arc->SetMid( pt );
3410  break;
3411 
3412  case T_end:
3413  pt.x = parseBoardUnits( "end x" );
3414  pt.y = parseBoardUnits( "end y" );
3415  arc->SetEnd( pt );
3416  break;
3417 
3418  case T_width:
3419  arc->SetWidth( parseBoardUnits( "width" ) );
3420  break;
3421 
3422  case T_layer:
3423  arc->SetLayer( parseBoardItemLayer() );
3424  break;
3425 
3426  case T_net:
3427  if( !arc->SetNetCode( getNetCode( parseInt( "net number" ) ), /* aNoAssert */ true ) )
3429  _( "Invalid net ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),
3430  GetChars( CurSource() ), CurLineNumber(), CurOffset() ) );
3431  break;
3432 
3433  case T_tstamp:
3434  NextTok();
3435  const_cast<KIID&>( arc->m_Uuid ) = KIID( CurStr() );
3436  break;
3437 
3438  case T_status:
3439  arc->SetStatus( static_cast<STATUS_FLAGS>( parseHex() ) );
3440  break;
3441 
3442  default:
3443  Expecting( "start, mid, end, width, layer, net, tstamp, or status" );
3444  }
3445 
3446  NeedRIGHT();
3447  }
3448 
3449  return arc.release();
3450 }
int parseBoardUnits()
Definition: pcb_parser.h:255
Definition: common.h:65
#define NULL
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:101
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
#define _(s)
Definition: 3d_actions.cpp:33
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:86
BOARD * m_board
Definition: pcb_parser.h:74
long parseHex()
Definition: pcb_parser.h:304
int parseInt()
Definition: pcb_parser.h:293

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

◆ parseBOARD()

BOARD * PCB_PARSER::parseBOARD ( )
private

Definition at line 506 of file pcb_parser.cpp.

507 {
508  try
509  {
510  return parseBOARD_unchecked();
511  }
512  catch( const PARSE_ERROR& parse_error )
513  {
514  if( m_tooRecent )
515  throw FUTURE_FORMAT_ERROR( parse_error, GetRequiredVersion() );
516  else
517  throw;
518  }
519 }
bool m_tooRecent
true if version parses as later than supported
Definition: pcb_parser.h:79
wxString GetRequiredVersion()
Return a string representing the version of kicad required to open this file.
Definition: pcb_parser.cpp:207
BOARD * parseBOARD_unchecked()
Function parseBOARD_unchecked Parse a module, but do not replace PARSE_ERROR with FUTURE_FORMAT_ERROR...
Definition: pcb_parser.cpp:522
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 522 of file pcb_parser.cpp.

523 {
524  T token;
525 
526  parseHeader();
527 
528  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
529  {
530  if( token != T_LEFT )
531  Expecting( T_LEFT );
532 
533  token = NextTok();
534 
535  switch( token )
536  {
537  case T_general:
539  break;
540 
541  case T_page:
542  parsePAGE_INFO();
543  break;
544 
545  case T_title_block:
547  break;
548 
549  case T_layers:
550  parseLayers();
551  break;
552 
553  case T_setup:
554  parseSetup();
555  break;
556 
557  case T_net:
559  break;
560 
561  case T_net_class:
562  parseNETCLASS();
563  break;
564 
565  case T_gr_arc:
566  case T_gr_circle:
567  case T_gr_curve:
568  case T_gr_line:
569  case T_gr_poly:
571  break;
572 
573  case T_gr_text:
575  break;
576 
577  case T_dimension:
579  break;
580 
581  case T_module:
583  break;
584 
585  case T_segment:
587  break;
588 
589  case T_arc:
591  break;
592 
593  case T_via:
595  break;
596 
597  case T_zone:
599  break;
600 
601  case T_target:
603  break;
604 
605  default:
606  wxString err;
607  err.Printf( _( "Unknown token \"%s\"" ), GetChars( FromUTF8() ) );
608  THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
609  }
610  }
611 
612  if( m_undefinedLayers.size() > 0 )
613  {
614  bool deleteItems;
615  std::vector<BOARD_ITEM*> deleteList;
616  wxString msg = wxString::Format( _( "Items found on undefined layers. Do you wish to\n"
617  "rescue them to the Cmts.User layer?" ) );
618  wxString details = wxString::Format( _( "Undefined layers:" ) );
619 
620  for( const wxString& undefinedLayer : m_undefinedLayers )
621  details += wxT( "\n " ) + undefinedLayer;
622 
623  wxRichMessageDialog dlg( nullptr, msg, _( "Warning" ),
624  wxYES_NO | wxCANCEL | wxCENTRE | wxICON_WARNING | wxSTAY_ON_TOP );
625  dlg.ShowDetailedText( details );
626  dlg.SetYesNoCancelLabels( _( "Rescue" ), _( "Delete" ), _( "Cancel" ) );
627 
628  switch( dlg.ShowModal() )
629  {
630  case wxID_YES: deleteItems = false; break;
631  case wxID_NO: deleteItems = true; break;
632  case wxID_CANCEL:
633  default: THROW_IO_ERROR( wxT( "CANCEL" ) );
634  }
635 
636  auto visitItem = [&]( BOARD_ITEM* item )
637  {
638  if( item->GetLayer() == Rescue )
639  {
640  if( deleteItems )
641  deleteList.push_back( item );
642  else
643  item->SetLayer( Cmts_User );
644  }
645  };
646 
647  for( auto segm : m_board->Tracks() )
648  {
649  if( segm->Type() == PCB_VIA_T )
650  {
651  VIA* via = (VIA*) segm;
652  PCB_LAYER_ID top_layer, bottom_layer;
653 
654  if( via->GetViaType() == VIATYPE::THROUGH )
655  continue;
656 
657  via->LayerPair( &top_layer, &bottom_layer );
658 
659  if( top_layer == Rescue || bottom_layer == Rescue )
660  {
661  if( deleteItems )
662  deleteList.push_back( via );
663  else
664  {
665  if( top_layer == Rescue )
666  top_layer = F_Cu;
667 
668  if( bottom_layer == Rescue )
669  bottom_layer = B_Cu;
670 
671  via->SetLayerPair( top_layer, bottom_layer );
672  }
673  }
674  }
675  else
676  visitItem( segm );
677  }
678 
679  for( BOARD_ITEM* zone : m_board->Zones() )
680  visitItem( zone );
681 
682  for( BOARD_ITEM* drawing : m_board->Drawings() )
683  visitItem( drawing );
684 
685  for( BOARD_ITEM* item : deleteList )
686  m_board->Delete( item );
687 
688  m_undefinedLayers.clear();
689  }
690 
691  return m_board;
692 }
void parseHeader()
Definition: pcb_parser.cpp:695
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.
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()
ARC * parseARC()
DIMENSION * parseDIMENSION()
void parseTITLE_BLOCK()
Definition: pcb_parser.cpp:833
void parseLayers()
void parsePAGE_INFO()
Definition: pcb_parser.cpp:777
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Adds an item to the container.
PCB_LAYER_ID
A quick note on layer IDs:
PCB_TARGET * parsePCB_TARGET()
ZONE_CONTAINER * parseZONE_CONTAINER(BOARD_ITEM_CONTAINER *aParent)
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()
ZONE_CONTAINERS & Zones()
Definition: class_board.h:243
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:101
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
#define _(s)
Definition: 3d_actions.cpp:33
BOARD * m_board
Definition: pcb_parser.h:74
void parseGeneralSection()
Definition: pcb_parser.cpp:731
VIATYPE GetViaType() const
Definition: class_track.h:416
virtual void Delete(BOARD_ITEM *aItem)
Removes an item from the container and deletes it.
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:97
MODULE * parseMODULE(wxArrayString *aInitialComments=0)
Function parseMODULE.
DRAWINGS & Drawings()
Definition: class_board.h:238
TRACKS & Tracks()
Definition: class_board.h:220
void parseSetup()
std::set< wxString > m_undefinedLayers
set of layers not defined in layers section
Definition: pcb_parser.h:77

References _, APPEND, B_Cu, Cmts_User, F_Cu, Format(), GetChars(), VIA::GetViaType(), INSERT, VIA::LayerPair(), PCB_VIA_T, Rescue, VIA::SetLayerPair(), THROUGH, THROW_IO_ERROR, and THROW_PARSE_ERROR.

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

1380 {
1381  wxCHECK_MSG( CurTok() == T_layer, UNDEFINED_LAYER,
1382  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as layer." ) );
1383 
1384  NextTok();
1385 
1386  PCB_LAYER_ID layerIndex = lookUpLayer<PCB_LAYER_ID>( m_layerIndices );
1387 
1388  // Handle closing ) in object parser.
1389 
1390  return layerIndex;
1391 }
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:75

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

1395 {
1396  wxCHECK_MSG( CurTok() == T_layers, LSET(),
1397  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
1398  wxT( " as item layer mask." ) );
1399 
1400  LSET layerMask;
1401 
1402  for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
1403  {
1404  LSET mask = lookUpLayer<LSET>( m_layerMasks );
1405  layerMask |= mask;
1406  }
1407 
1408  return layerMask;
1409 }
LSET is a set of PCB_LAYER_IDs.
LSET_MAP m_layerMasks
map layer names to their masks
Definition: pcb_parser.h:76

◆ parseBoardStackup()

void PCB_PARSER::parseBoardStackup ( )
private

Definition at line 982 of file pcb_parser.cpp.

983 {
984  T token;
985  wxString name;
986  int dielectric_idx = 1; // the index of dielectric layers
988 
989  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
990  {
991  if( CurTok() != T_LEFT )
992  Expecting( T_LEFT );
993 
994  token = NextTok();
995 
996  if( token != T_layer )
997  {
998  switch( token )
999  {
1000  case T_copper_finish:
1001  NeedSYMBOL();
1002  stackup.m_FinishType = FromUTF8();
1003  NeedRIGHT();
1004  break;
1005 
1006  case T_edge_plating:
1007  token = NextTok();
1008  stackup.m_EdgePlating = token == T_yes;
1009  NeedRIGHT();
1010  break;
1011 
1012  case T_dielectric_constraints:
1013  token = NextTok();
1014  stackup.m_HasDielectricConstrains = token == T_yes;
1015  NeedRIGHT();
1016  break;
1017 
1018  case T_edge_connector:
1019  token = NextTok();
1021 
1022  if( token == T_yes )
1024  else if( token == T_bevelled )
1026 
1027  NeedRIGHT();
1028  break;
1029 
1030  case T_castellated_pads:
1031  token = NextTok();
1032  stackup.m_CastellatedPads = token == T_yes;
1033  NeedRIGHT();
1034  break;
1035 
1036  default:
1037  // Currently, skip this item if not defined, because the stackup def
1038  // is a moving target
1039  //Expecting( "copper_finish, edge_plating, dielectric_constrains, edge_connector, castellated_pads" );
1040  skipCurrent();
1041  break;
1042  }
1043 
1044  continue;
1045  }
1046 
1047  NeedSYMBOL();
1048  name = FromUTF8();
1049 
1050  // init the layer id. For dielectric, layer id = UNDEFINED_LAYER
1051  PCB_LAYER_ID layerId = m_board->GetLayerID( name );
1052 
1053  // Init the type
1055 
1056  if( layerId == F_SilkS || layerId == B_SilkS )
1057  type = BS_ITEM_TYPE_SILKSCREEN;
1058  else if( layerId == F_Mask || layerId == B_Mask )
1059  type = BS_ITEM_TYPE_SOLDERMASK;
1060  else if( layerId == F_Paste || layerId == B_Paste )
1061  type = BS_ITEM_TYPE_SOLDERPASTE;
1062  else if( layerId == UNDEFINED_LAYER )
1063  type = BS_ITEM_TYPE_DIELECTRIC;
1064  else if( layerId >= F_Cu && layerId <= B_Cu )
1065  type = BS_ITEM_TYPE_COPPER;
1066 
1067  BOARD_STACKUP_ITEM* item = nullptr;
1068 
1069  if( type != BS_ITEM_TYPE_UNDEFINED )
1070  {
1071  item = new BOARD_STACKUP_ITEM( type );
1072  item->SetBrdLayerId( layerId );
1073 
1074  if( type == BS_ITEM_TYPE_DIELECTRIC )
1075  item->SetDielectricLayerId( dielectric_idx++ );
1076 
1077  stackup.Add( item );
1078  }
1079  else
1080  Expecting( "layer_name" );
1081 
1082  bool has_next_sublayer = true;
1083  int sublayer_idx = 0; // the index of dielectric sub layers
1084  // sublayer 0 is always existing (main sublayer)
1085 
1086  while( has_next_sublayer )
1087  {
1088  has_next_sublayer = false;
1089 
1090  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1091  {
1092  if( token == T_addsublayer )
1093  {
1094  has_next_sublayer = true;
1095  break;
1096  }
1097 
1098  if( token == T_LEFT )
1099  {
1100  token = NextTok();
1101 
1102  switch( token )
1103  {
1104  case T_type:
1105  NeedSYMBOL();
1106  item->SetTypeName( FromUTF8() );
1107  NeedRIGHT();
1108  break;
1109 
1110  case T_thickness:
1111  item->SetThickness( parseBoardUnits( T_thickness ), sublayer_idx );
1112  token = NextTok();
1113 
1114  if( token == T_LEFT )
1115  break;
1116 
1117  if( token == T_locked )
1118  {
1119  // Dielectric thickness can be locked (for impedance controled layers)
1120  if( type == BS_ITEM_TYPE_DIELECTRIC )
1121  item->SetThicknessLocked( true, sublayer_idx );
1122 
1123  NeedRIGHT();
1124  }
1125  break;
1126 
1127  case T_material:
1128  NeedSYMBOL();
1129  item->SetMaterial( FromUTF8(), sublayer_idx );
1130  NeedRIGHT();
1131  break;
1132 
1133  case T_epsilon_r:
1134  NextTok();
1135  item->SetEpsilonR( parseDouble(), sublayer_idx );
1136  NeedRIGHT();
1137  break;
1138 
1139  case T_loss_tangent:
1140  NextTok();
1141  item->SetLossTangent( parseDouble(), sublayer_idx );
1142  NeedRIGHT();
1143  break;
1144 
1145  case T_color:
1146  NeedSYMBOL();
1147  item->SetColor( FromUTF8() );
1148  NeedRIGHT();
1149  break;
1150 
1151  default:
1152  // Currently, skip this item if not defined, because the stackup def
1153  // is a moving target
1154  //Expecting( "type, thickness, material, epsilon_r, loss_tangent, color" );
1155  skipCurrent();
1156  }
1157  }
1158  }
1159 
1160  if( has_next_sublayer ) // Prepare reading the next sublayer description
1161  {
1162  sublayer_idx++;
1163  item->AddDielectricPrms( sublayer_idx );
1164  }
1165  }
1166  }
1167 
1168  if( token != T_RIGHT )
1169  {
1170  Expecting( ")" );
1171  }
1172 
1173  // Success:
1175 }
const PCB_LAYER_ID GetLayerID(const wxString &aLayerName) const
Function GetLayerID returns the ID of a layer given by aLayerName.
void SetBrdLayerId(PCB_LAYER_ID aBrdLayerId)
void SetTypeName(const wxString &aName)
this class manage the layers needed to make a physical board they are solder mask,...
wxString m_FinishType
The name of external copper finish.
bool m_EdgePlating
True if the edge board is plated.
BS_EDGE_CONNECTOR_CONSTRAINTS m_EdgeConnectorConstraints
If the board has edge connector cards, some constrains can be specifed in job file: BS_EDGE_CONNECTOR...
bool m_CastellatedPads
True if castellated pads exist.
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:512
int parseBoardUnits()
Definition: pcb_parser.h:255
void skipCurrent()
Function skipCurrent Skip the current token level, i.e search for the RIGHT parenthesis which closes ...
Definition: pcb_parser.cpp:116
bool m_HasDielectricConstrains
True if some layers have impedance controlled tracks or have specific constrains for micro-wave appli...
BOARD_STACKUP & GetStackupDescriptor()
PCB_LAYER_ID
A quick note on layer IDs:
void SetDielectricLayerId(int aLayerId)
void SetMaterial(const wxString &aName, int aDielectricSubLayer=0)
this class manage one layer needed to make a physical board it can be a solder mask,...
void SetEpsilonR(double aEpsilon, int aDielectricSubLayer=0)
void AddDielectricPrms(int aDielectricPrmsIdx)
true if this stackup item must be taken in account, false to ignore it.
void SetThickness(int aThickness, int aDielectricSubLayer=0)
void SetThicknessLocked(bool aLocked, int aDielectricSubLayer=0)
const char * name
Definition: DXF_plotter.cpp:60
BOARD * m_board
Definition: pcb_parser.h:74
BOARD_STACKUP_ITEM_TYPE
double parseDouble()
Function parseDouble parses the current token as an ASCII numeric string with possible leading whites...
Definition: pcb_parser.cpp:149
void SetColor(const wxString &aColorName)
bool m_HasStackup
Set to true if the board has a stackup management.
void Add(BOARD_STACKUP_ITEM *aItem)
Add a new item in stackup layer.
void SetLossTangent(double aTg, int aDielectricSubLayer=0)

References BOARD_STACKUP::Add(), BOARD_STACKUP_ITEM::AddDielectricPrms(), B_Cu, B_Mask, B_Paste, B_SilkS, BS_EDGE_CONNECTOR_BEVELLED, BS_EDGE_CONNECTOR_IN_USE, BS_EDGE_CONNECTOR_NONE, BS_ITEM_TYPE_COPPER, BS_ITEM_TYPE_DIELECTRIC, BS_ITEM_TYPE_SILKSCREEN, BS_ITEM_TYPE_SOLDERMASK, BS_ITEM_TYPE_SOLDERPASTE, BS_ITEM_TYPE_UNDEFINED, F_Cu, F_Mask, F_Paste, F_SilkS, BOARD_STACKUP::m_CastellatedPads, BOARD_STACKUP::m_EdgeConnectorConstraints, BOARD_STACKUP::m_EdgePlating, BOARD_STACKUP::m_FinishType, BOARD_STACKUP::m_HasDielectricConstrains, name, parseDouble(), BOARD_STACKUP_ITEM::SetBrdLayerId(), BOARD_STACKUP_ITEM::SetColor(), BOARD_STACKUP_ITEM::SetDielectricLayerId(), BOARD_STACKUP_ITEM::SetEpsilonR(), BOARD_STACKUP_ITEM::SetLossTangent(), BOARD_STACKUP_ITEM::SetMaterial(), BOARD_STACKUP_ITEM::SetThickness(), BOARD_STACKUP_ITEM::SetThicknessLocked(), BOARD_STACKUP_ITEM::SetTypeName(), and UNDEFINED_LAYER.

◆ parseBoardUnits() [1/3]

int PCB_PARSER::parseBoardUnits ( )
inlineprivate

Definition at line 255 of file pcb_parser.h.

256  {
257  // There should be no major rounding issues here, since the values in
258  // the file are in mm and get converted to nano-meters.
259  // See test program tools/test-nm-biu-to-ascii-mm-round-tripping.cpp
260  // to confirm or experiment. Use a similar strategy in both places, here
261  // and in the test program. Make that program with:
262  // $ make test-nm-biu-to-ascii-mm-round-tripping
263  auto retval = parseDouble() * IU_PER_MM;
264 
265  // N.B. we currently represent board units as integers. Any values that are
266  // larger or smaller than those board units represent undefined behavior for
267  // the system. We limit values to the largest that is visible on the screen
268  // This is the diagonal distance of the full screen ~1.5m
269  double int_limit = std::numeric_limits<int>::max() * 0.7071; // 0.7071 = roughly 1/sqrt(2)
270  return KiROUND( Clamp<double>( -int_limit, retval, int_limit ) );
271  }
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:61
double parseDouble()
Function parseDouble parses the current token as an ASCII numeric string with possible leading whites...
Definition: pcb_parser.cpp:149

References KiROUND(), and parseDouble().

Referenced by parseBoardUnits().

◆ parseBoardUnits() [2/3]

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

Definition at line 273 of file pcb_parser.h.

274  {
275  auto retval = parseDouble( aExpected ) * IU_PER_MM;
276 
277  // N.B. we currently represent board units as integers. Any values that are
278  // larger or smaller than those board units represent undefined behavior for
279  // the system. We limit values to the largest that is visible on the screen
280  double int_limit = std::numeric_limits<int>::max() * 0.7071;
281 
282  // Use here KiROUND, not KIROUND (see comments about them)
283  // when having a function as argument, because it will be called twice
284  // with KIROUND
285  return KiROUND( Clamp<double>( -int_limit, retval, int_limit ) );
286  }
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:61
double parseDouble()
Function parseDouble parses the current token as an ASCII numeric string with possible leading whites...
Definition: pcb_parser.cpp:149

References KiROUND(), and parseDouble().

◆ parseBoardUnits() [3/3]

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

Definition at line 288 of file pcb_parser.h.

289  {
290  return parseBoardUnits( GetTokenText( aToken ) );
291  }
int parseBoardUnits()
Definition: pcb_parser.h:255
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 179 of file pcb_parser.cpp.

180 {
181  T token = NextTok();
182 
183  if( token == T_yes )
184  return true;
185  else if( token == T_no )
186  return false;
187  else
188  Expecting( "yes or no" );
189 
190  return false;
191 }

◆ parseD_PAD()

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

Definition at line 2864 of file pcb_parser.cpp.

2865 {
2866  wxCHECK_MSG( CurTok() == T_pad, NULL,
2867  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as D_PAD." ) );
2868 
2869  wxSize sz;
2870  wxPoint pt;
2871 
2872  std::unique_ptr< D_PAD > pad( new D_PAD( aParent ) );
2873 
2874  NeedSYMBOLorNUMBER();
2875  pad->SetName( FromUTF8() );
2876 
2877  T token = NextTok();
2878 
2879  switch( token )
2880  {
2881  case T_thru_hole:
2882  pad->SetAttribute( PAD_ATTRIB_STANDARD );
2883  break;
2884 
2885  case T_smd:
2886  pad->SetAttribute( PAD_ATTRIB_SMD );
2887 
2888  // Default D_PAD object is thru hole with drill.
2889  // SMD pads have no hole
2890  pad->SetDrillSize( wxSize( 0, 0 ) );
2891  break;
2892 
2893  case T_connect:
2894  pad->SetAttribute( PAD_ATTRIB_CONN );
2895 
2896  // Default D_PAD object is thru hole with drill.
2897  // CONN pads have no hole
2898  pad->SetDrillSize( wxSize( 0, 0 ) );
2899  break;
2900 
2901  case T_np_thru_hole:
2902  pad->SetAttribute( PAD_ATTRIB_HOLE_NOT_PLATED );
2903  break;
2904 
2905  default:
2906  Expecting( "thru_hole, smd, connect, or np_thru_hole" );
2907  }
2908 
2909  token = NextTok();
2910 
2911  switch( token )
2912  {
2913  case T_circle:
2914  pad->SetShape( PAD_SHAPE_CIRCLE );
2915  break;
2916 
2917  case T_rect:
2918  pad->SetShape( PAD_SHAPE_RECT );
2919  break;
2920 
2921  case T_oval:
2922  pad->SetShape( PAD_SHAPE_OVAL );
2923  break;
2924 
2925  case T_trapezoid:
2926  pad->SetShape( PAD_SHAPE_TRAPEZOID );
2927  break;
2928 
2929  case T_roundrect:
2930  // Note: the shape can be PAD_SHAPE_ROUNDRECT or PAD_SHAPE_CHAMFERED_RECT
2931  // (if champfer parameters are found later in pad descr.)
2932  pad->SetShape( PAD_SHAPE_ROUNDRECT );
2933  break;
2934 
2935  case T_custom:
2936  pad->SetShape( PAD_SHAPE_CUSTOM );
2937  break;
2938 
2939  default:
2940  Expecting( "circle, rectangle, roundrect, oval, trapezoid or custom" );
2941  }
2942 
2943  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2944  {
2945  if( token != T_LEFT )
2946  Expecting( T_LEFT );
2947 
2948  token = NextTok();
2949 
2950  switch( token )
2951  {
2952  case T_size:
2953  sz.SetWidth( parseBoardUnits( "width value" ) );
2954  sz.SetHeight( parseBoardUnits( "height value" ) );
2955  pad->SetSize( sz );
2956  NeedRIGHT();
2957  break;
2958 
2959  case T_at:
2960  pt.x = parseBoardUnits( "X coordinate" );
2961  pt.y = parseBoardUnits( "Y coordinate" );
2962  pad->SetPos0( pt );
2963  token = NextTok();
2964 
2965  if( token == T_NUMBER )
2966  {
2967  pad->SetOrientation( parseDouble() * 10.0 );
2968  NeedRIGHT();
2969  }
2970  else if( token != T_RIGHT )
2971  {
2972  Expecting( ") or angle value" );
2973  }
2974 
2975  break;
2976 
2977  case T_rect_delta:
2978  {
2979  wxSize delta;
2980  delta.SetWidth( parseBoardUnits( "rectangle delta width" ) );
2981  delta.SetHeight( parseBoardUnits( "rectangle delta height" ) );
2982  pad->SetDelta( delta );
2983  NeedRIGHT();
2984  }
2985  break;
2986 
2987  case T_drill:
2988  {
2989  bool haveWidth = false;
2990  wxSize drillSize = pad->GetDrillSize();
2991 
2992  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2993  {
2994  if( token == T_LEFT )
2995  token = NextTok();
2996 
2997  switch( token )
2998  {
2999  case T_oval:
3000  pad->SetDrillShape( PAD_DRILL_SHAPE_OBLONG );
3001  break;
3002 
3003  case T_NUMBER:
3004  {
3005  if( !haveWidth )
3006  {
3007  drillSize.SetWidth( parseBoardUnits() );
3008 
3009  // If height is not defined the width and height are the same.
3010  drillSize.SetHeight( drillSize.GetWidth() );
3011  haveWidth = true;
3012  }
3013  else
3014  {
3015  drillSize.SetHeight( parseBoardUnits() );
3016  }
3017 
3018  }
3019  break;
3020 
3021  case T_offset:
3022  pt.x = parseBoardUnits( "drill offset x" );
3023  pt.y = parseBoardUnits( "drill offset y" );
3024  pad->SetOffset( pt );
3025  NeedRIGHT();
3026  break;
3027 
3028  default:
3029  Expecting( "oval, size, or offset" );
3030  }
3031  }
3032 
3033  // This fixes a bug caused by setting the default D_PAD drill size to a value
3034  // other than 0 used to fix a bunch of debug assertions even though it is defined
3035  // as a through hole pad. Wouldn't a though hole pad with no drill be a surface
3036  // mount pad (or a conn pad which is a smd pad with no solder paste)?
3037  if( ( pad->GetAttribute() != PAD_ATTRIB_SMD ) && ( pad->GetAttribute() != PAD_ATTRIB_CONN ) )
3038  pad->SetDrillSize( drillSize );
3039  else
3040  pad->SetDrillSize( wxSize( 0, 0 ) );
3041 
3042  }
3043  break;
3044 
3045  case T_layers:
3046  {
3047  LSET layerMask = parseBoardItemLayersAsMask();
3048  pad->SetLayerSet( layerMask );
3049  }
3050  break;
3051 
3052  case T_net:
3053  if( ! pad->SetNetCode( getNetCode( parseInt( "net number" ) ), /* aNoAssert */ true ) )
3054  {
3055  wxLogError( wxString::Format( _( "Invalid net ID in\n"
3056  "file: '%s'\n"
3057  "line: %d\n"
3058  "offset: %d" ),
3059  CurSource(),
3060  CurLineNumber(),
3061  CurOffset() ) );
3062  }
3063 
3064  NeedSYMBOLorNUMBER();
3065 
3066  // Test validity of the netname in file for netcodes expected having a net name
3067  if( m_board && pad->GetNetCode() > 0 &&
3068  FromUTF8() != m_board->FindNet( pad->GetNetCode() )->GetNetname() )
3069  {
3070  pad->SetNetCode( NETINFO_LIST::ORPHANED, /* aNoAssert */ true );
3071  wxLogError( wxString::Format( _( "Net name doesn't match net ID in\n"
3072  "file: '%s'\n"
3073  "line: %d\n"
3074  "offset: %d" ),
3075  CurSource(),
3076  CurLineNumber(),
3077  CurOffset() ) );
3078  }
3079 
3080  NeedRIGHT();
3081  break;
3082 
3083  case T_pinfunction:
3084  NeedSYMBOLorNUMBER();
3085  pad->SetPinFunction( FromUTF8() );
3086  NeedRIGHT();
3087  break;
3088 
3089  case T_die_length:
3090  pad->SetPadToDieLength( parseBoardUnits( T_die_length ) );
3091  NeedRIGHT();
3092  break;
3093 
3094  case T_solder_mask_margin:
3095  pad->SetLocalSolderMaskMargin( parseBoardUnits( T_solder_mask_margin ) );
3096  NeedRIGHT();
3097  break;
3098 
3099  case T_solder_paste_margin:
3100  pad->SetLocalSolderPasteMargin( parseBoardUnits( T_solder_paste_margin ) );
3101  NeedRIGHT();
3102  break;
3103 
3104  case T_solder_paste_margin_ratio:
3105  pad->SetLocalSolderPasteMarginRatio(
3106  parseDouble( "pad local solder paste margin ratio value" ) );
3107  NeedRIGHT();
3108  break;
3109 
3110  case T_clearance:
3111  pad->SetLocalClearance( parseBoardUnits( "local clearance value" ) );
3112  NeedRIGHT();
3113  break;
3114 
3115  case T_zone_connect:
3116  pad->SetZoneConnection( (ZONE_CONNECTION) parseInt( "zone connection value" ) );
3117  NeedRIGHT();
3118  break;
3119 
3120  case T_thermal_width:
3121  pad->SetThermalWidth( parseBoardUnits( T_thermal_width ) );
3122  NeedRIGHT();
3123  break;
3124 
3125  case T_thermal_gap:
3126  pad->SetThermalGap( parseBoardUnits( T_thermal_gap ) );
3127  NeedRIGHT();
3128  break;
3129 
3130  case T_roundrect_rratio:
3131  pad->SetRoundRectRadiusRatio( parseDouble( "roundrect radius ratio" ) );
3132  NeedRIGHT();
3133  break;
3134 
3135  case T_chamfer_ratio:
3136  pad->SetChamferRectRatio( parseDouble( "chamfer ratio" ) );
3137 
3138  if( pad->GetChamferRectRatio() > 0 )
3139  pad->SetShape( PAD_SHAPE_CHAMFERED_RECT );
3140 
3141  NeedRIGHT();
3142  break;
3143 
3144  case T_chamfer:
3145  {
3146  int chamfers = 0;
3147  bool end_list = false;
3148 
3149  while( !end_list )
3150  {
3151  token = NextTok();
3152  switch( token )
3153  {
3154  case T_top_left:
3155  chamfers |= RECT_CHAMFER_TOP_LEFT;
3156  break;
3157 
3158  case T_top_right:
3159  chamfers |= RECT_CHAMFER_TOP_RIGHT;
3160  break;
3161 
3162  case T_bottom_left:
3163  chamfers |= RECT_CHAMFER_BOTTOM_LEFT;
3164  break;
3165 
3166  case T_bottom_right:
3167  chamfers |= RECT_CHAMFER_BOTTOM_RIGHT;
3168  break;
3169 
3170  case T_RIGHT:
3171  pad->SetChamferPositions( chamfers );
3172  end_list = true;
3173  break;
3174 
3175  default:
3176  Expecting( "chamfer_top_left chamfer_top_right chamfer_bottom_left or chamfer_bottom_right" );
3177  }
3178  }
3179 
3180  if( pad->GetChamferPositions() != RECT_NO_CHAMFER )
3181  pad->SetShape( PAD_SHAPE_CHAMFERED_RECT );
3182  }
3183  break;
3184 
3185  case T_property:
3186  {
3187  while( token != T_RIGHT )
3188  {
3189  token = NextTok();
3190 
3191  switch( token )
3192  {
3193  case T_pad_prop_bga:
3194  pad->SetProperty( PAD_PROP_BGA );
3195  break;
3196 
3197  case T_pad_prop_fiducial_glob:
3198  pad->SetProperty( PAD_PROP_FIDUCIAL_GLBL );
3199  break;
3200 
3201  case T_pad_prop_fiducial_loc:
3202  pad->SetProperty( PAD_PROP_FIDUCIAL_LOCAL );
3203  break;
3204 
3205  case T_pad_prop_testpoint:
3206  pad->SetProperty( PAD_PROP_TESTPOINT );
3207  break;
3208 
3209  case T_pad_prop_castellated:
3210  pad->SetProperty( PAD_PROP_CASTELLATED );
3211  break;
3212 
3213  case T_pad_prop_heatsink:
3214  pad->SetProperty( PAD_PROP_HEATSINK );
3215  break;
3216 
3217  case T_RIGHT:
3218  break;
3219 
3220  default:
3221 #if 0 // Currently: skip unknown property
3222  Expecting( "pad_prop_bga pad_prop_fiducial_glob pad_prop_fiducial_loc"
3223  " pad_prop_heatsink or pad_prop_castellated" );
3224 #endif
3225  break;
3226  }
3227  }
3228  }
3229  break;
3230 
3231  case T_options:
3232  parseD_PAD_option( pad.get() );
3233  break;
3234 
3235  case T_primitives:
3236  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3237  {
3238  if( token == T_LEFT )
3239  token = NextTok();
3240 
3241  // Currently, I am using parseDRAWSEGMENT() to read basic shapes parameters,
3242  // because they are the same as a DRAWSEGMENT.
3243  // However it could be better to write a specific parser, to avoid possible issues
3244  // if the DRAWSEGMENT parser is modified.
3245  DRAWSEGMENT* dummysegm = NULL;
3246 
3247  switch( token )
3248  {
3249  case T_gr_arc:
3250  dummysegm = parseDRAWSEGMENT();
3251  pad->AddPrimitiveArc( dummysegm->GetCenter(), dummysegm->GetArcStart(),
3252  dummysegm->GetAngle(), dummysegm->GetWidth(), false );
3253  break;
3254 
3255  case T_gr_line:
3256  dummysegm = parseDRAWSEGMENT();
3257  pad->AddPrimitiveSegment( dummysegm->GetStart(), dummysegm->GetEnd(),
3258  dummysegm->GetWidth(), false );
3259  break;
3260 
3261  case T_gr_circle:
3262  dummysegm = parseDRAWSEGMENT( true ); // Circles with 0 thickness are allowed
3263  // ( filled circles )
3264  pad->AddPrimitiveCircle( dummysegm->GetCenter(), dummysegm->GetRadius(),
3265  dummysegm->GetWidth(), false );
3266  break;
3267 
3268  case T_gr_poly:
3269  dummysegm = parseDRAWSEGMENT();
3270  pad->AddPrimitivePoly(
3271  dummysegm->BuildPolyPointsList(), dummysegm->GetWidth(), false );
3272  break;
3273 
3274  case T_gr_curve:
3275  dummysegm = parseDRAWSEGMENT();
3276  pad->AddPrimitiveCurve( dummysegm->GetStart(), dummysegm->GetEnd(),
3277  dummysegm->GetBezControl1(), dummysegm->GetBezControl2(),
3278  dummysegm->GetWidth(), false );
3279  break;
3280 
3281  default:
3282  Expecting( "gr_line, gr_arc, gr_circle, gr_curve or gr_poly" );
3283  break;
3284  }
3285 
3286  delete dummysegm;
3287  }
3288  break;
3289 
3290  case T_tstamp:
3291  NextTok();
3292  const_cast<KIID&>( pad->m_Uuid ) = KIID( CurStr() );
3293  NeedRIGHT();
3294  break;
3295 
3296  default:
3297  Expecting( "at, drill, layers, net, die_length, solder_mask_margin, roundrect_rratio,\n"
3298  "solder_paste_margin, solder_paste_margin_ratio, clearance, tstamp,\n"
3299  "zone_connect, fp_poly, primitives, thermal_width, or thermal_gap" );
3300  }
3301  }
3302 
3303  // Be sure the custom shape polygon is built:
3304  if( pad->GetShape() == PAD_SHAPE_CUSTOM )
3305  pad->MergePrimitivesAsPolygon();
3306 
3307  return pad.release();
3308 }
NETINFO_ITEM * FindNet(int aNetcode) const
Function FindNet searches for a net with the given netcode.
ZONE_CONNECTION
How pads are covered by copper in zone.
Definition: zones.h:41
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()
a fiducial (usually a smd) for the full board
Definition: pad_shapes.h:80
Smd pad, appears on the solder paste layer (default)
Definition: pad_shapes.h:62
Smd pad, used in BGA footprints.
Definition: pad_shapes.h:79
bool parseD_PAD_option(D_PAD *aPad)
a pad used as heat sink, usually in SMD footprints
Definition: pad_shapes.h:83
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.
int parseBoardUnits()
Definition: pcb_parser.h:255
a pad with a castellated through hole
Definition: pad_shapes.h:84
Definition: common.h:65
LSET is a set of PCB_LAYER_IDs.
#define NULL
const wxPoint & GetArcStart() const
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
static const int ORPHANED
Constant that forces initialization of a netinfo item to the NETINFO_ITEM ORPHANED (typically -1) whe...
Definition: netinfo.h:466
double GetAngle() const
a fiducial (usually a smd) local to the parent footprint
Definition: pad_shapes.h:81
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
#define _(s)
Definition: 3d_actions.cpp:33
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:86
BOARD * m_board
Definition: pcb_parser.h:74
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:149
const wxPoint & GetBezControl1() const
const wxPoint & GetStart() const
Function GetStart returns the starting point of the graphic.
int parseInt()
Definition: pcb_parser.h:293
a test point pad
Definition: pad_shapes.h:82

References _, DRAWSEGMENT::BuildPolyPointsList(), Format(), DRAWSEGMENT::GetAngle(), DRAWSEGMENT::GetArcStart(), DRAWSEGMENT::GetBezControl1(), DRAWSEGMENT::GetBezControl2(), DRAWSEGMENT::GetCenter(), DRAWSEGMENT::GetEnd(), DRAWSEGMENT::GetRadius(), DRAWSEGMENT::GetStart(), DRAWSEGMENT::GetWidth(), NULL, NETINFO_LIST::ORPHANED, PAD_ATTRIB_CONN, PAD_ATTRIB_HOLE_NOT_PLATED, PAD_ATTRIB_SMD, PAD_ATTRIB_STANDARD, PAD_DRILL_SHAPE_OBLONG, PAD_PROP_BGA, PAD_PROP_CASTELLATED, PAD_PROP_FIDUCIAL_GLBL, PAD_PROP_FIDUCIAL_LOCAL, PAD_PROP_HEATSINK, PAD_PROP_TESTPOINT, 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, wxPoint::x, and wxPoint::y.

◆ parseD_PAD_option()

bool PCB_PARSER::parseD_PAD_option ( D_PAD aPad)
private

Definition at line 3311 of file pcb_parser.cpp.

3312 {
3313  // Parse only the (option ...) inside a pad description
3314  for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
3315  {
3316  if( token != T_LEFT )
3317  Expecting( T_LEFT );
3318 
3319  token = NextTok();
3320 
3321  switch( token )
3322  {
3323  case T_anchor:
3324  token = NextTok();
3325  // Custom shaped pads have a "anchor pad", which is the reference
3326  // for connection calculations.
3327  // Because this is an anchor, only the 2 very basic shapes are managed:
3328  // circle and rect. The default is circle
3329  switch( token )
3330  {
3331  case T_circle: // default
3332  break;
3333 
3334  case T_rect:
3336  break;
3337 
3338  default:
3339  // Currently, because pad options is a moving target
3340  // just skip unknown keywords
3341  break;
3342  }
3343  NeedRIGHT();
3344  break;
3345 
3346  case T_clearance:
3347  token = NextTok();
3348  // Custom shaped pads have a clearance area that is the pad shape
3349  // (like usual pads) or the convew hull of the pad shape.
3350  switch( token )
3351  {
3352  case T_outline:
3354  break;
3355 
3356  case T_convexhull:
3358  break;
3359 
3360  default:
3361  // Currently, because pad options is a moving target
3362  // just skip unknown keywords
3363  break;
3364  }
3365  NeedRIGHT();
3366  break;
3367 
3368  default:
3369  // Currently, because pad options is a moving target
3370  // just skip unknown keywords
3371  while( (token = NextTok() ) != T_RIGHT )
3372  {}
3373  break;
3374  }
3375  }
3376 
3377  return true;
3378 }
void SetAnchorPadShape(PAD_SHAPE_T aShape)
Function SetAnchorPadShape Set the shape of the anchor pad for custm shped pads.
Definition: class_pad.h:274
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:263

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

◆ parseDefaults()

void PCB_PARSER::parseDefaults ( BOARD_DESIGN_SETTINGS aSettings)
private

Definition at line 1677 of file pcb_parser.cpp.

1678 {
1679  T token;
1680 
1681  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1682  {
1683  if( token != T_LEFT )
1684  Expecting( T_LEFT );
1685 
1686  token = NextTok();
1687 
1688  switch( token )
1689  {
1690  case T_edge_clearance:
1691  designSettings.m_CopperEdgeClearance = parseBoardUnits( T_edge_clearance );
1692  NeedRIGHT();
1693  break;
1694 
1695  case T_copper_line_width:
1696  designSettings.m_LineThickness[ LAYER_CLASS_COPPER ] = parseBoardUnits( token );
1697  NeedRIGHT();
1698  break;
1699 
1700  case T_copper_text_dims:
1701  parseDefaultTextDims( designSettings, LAYER_CLASS_COPPER );
1702  break;
1703 
1704  case T_courtyard_line_width:
1705  designSettings.m_LineThickness[ LAYER_CLASS_COURTYARD ] = parseBoardUnits( token );
1706  NeedRIGHT();
1707  break;
1708 
1709  case T_edge_cuts_line_width:
1710  designSettings.m_LineThickness[ LAYER_CLASS_EDGES ] = parseBoardUnits( token );
1711  NeedRIGHT();
1712  break;
1713 
1714  case T_silk_line_width:
1715  designSettings.m_LineThickness[ LAYER_CLASS_SILK ] = parseBoardUnits( token );
1716  NeedRIGHT();
1717  break;
1718 
1719  case T_silk_text_dims:
1720  parseDefaultTextDims( designSettings, LAYER_CLASS_SILK );
1721  break;
1722 
1723  case T_other_layers_line_width:
1724  designSettings.m_LineThickness[ LAYER_CLASS_OTHERS ] = parseBoardUnits( token );
1725  NeedRIGHT();
1726  break;
1727 
1728  case T_other_layers_text_dims:
1729  parseDefaultTextDims( designSettings, LAYER_CLASS_OTHERS );
1730  break;
1731 
1732  case T_dimension_units:
1733  designSettings.m_DimensionUnits = parseInt( "dimension units" );
1734  NeedRIGHT();
1735  break;
1736 
1737  case T_dimension_precision:
1738  designSettings.m_DimensionPrecision = parseInt( "dimension precision" );
1739  NeedRIGHT();
1740  break;
1741 
1742  default:
1743  Unexpected( CurText() );
1744  }
1745  }
1746 }
int parseBoardUnits()
Definition: pcb_parser.h:255
void parseDefaultTextDims(BOARD_DESIGN_SETTINGS &aSettings, int aLayer)
int parseInt()
Definition: pcb_parser.h:293

References LAYER_CLASS_COPPER, LAYER_CLASS_COURTYARD, LAYER_CLASS_EDGES, LAYER_CLASS_OTHERS, LAYER_CLASS_SILK, BOARD_DESIGN_SETTINGS::m_CopperEdgeClearance, BOARD_DESIGN_SETTINGS::m_DimensionPrecision, BOARD_DESIGN_SETTINGS::m_DimensionUnits, BOARD_DESIGN_SETTINGS::m_LineThickness, and parseInt().

◆ parseDefaultTextDims()

void PCB_PARSER::parseDefaultTextDims ( BOARD_DESIGN_SETTINGS aSettings,
int  aLayer 
)
private

Definition at line 1749 of file pcb_parser.cpp.

1750 {
1751  T token;
1752 
1753  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1754  {
1755  if( token == T_LEFT )
1756  token = NextTok();
1757 
1758  switch( token )
1759  {
1760  case T_size:
1761  aSettings.m_TextSize[ aLayer ].x = parseBoardUnits( "default text size X" );
1762  aSettings.m_TextSize[ aLayer ].y = parseBoardUnits( "default text size Y" );
1763  NeedRIGHT();
1764  break;
1765 
1766  case T_thickness:
1767  aSettings.m_TextThickness[ aLayer ] = parseBoardUnits( "default text width" );
1768  NeedRIGHT();
1769  break;
1770 
1771  case T_italic:
1772  aSettings.m_TextItalic[ aLayer ] = true;
1773  break;
1774 
1775  case T_keep_upright:
1776  aSettings.m_TextUpright[ aLayer ] = true;
1777  break;
1778 
1779  default:
1780  Expecting( "size, thickness, italic or keep_upright" );
1781  }
1782  }
1783 }
int parseBoardUnits()
Definition: pcb_parser.h:255
wxSize m_TextSize[LAYER_CLASS_COUNT]
int m_TextThickness[LAYER_CLASS_COUNT]
bool m_TextItalic[LAYER_CLASS_COUNT]
bool m_TextUpright[LAYER_CLASS_COUNT]

References BOARD_DESIGN_SETTINGS::m_TextItalic, BOARD_DESIGN_SETTINGS::m_TextSize, BOARD_DESIGN_SETTINGS::m_TextThickness, and BOARD_DESIGN_SETTINGS::m_TextUpright.

◆ parseDIMENSION()

DIMENSION * PCB_PARSER::parseDIMENSION ( )
private

Definition at line 2138 of file pcb_parser.cpp.

2139 {
2140  wxCHECK_MSG( CurTok() == T_dimension, NULL,
2141  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as DIMENSION." ) );
2142 
2143  T token;
2144 
2145  std::unique_ptr<DIMENSION> dimension( new DIMENSION( NULL ) );
2146 
2147  dimension->SetValue( parseBoardUnits( "dimension value" ) );
2148  NeedLEFT();
2149  token = NextTok();
2150 
2151  if( token != T_width )
2152  Expecting( T_width );
2153 
2154  dimension->SetWidth( parseBoardUnits( "dimension width value" ) );
2155  NeedRIGHT();
2156 
2157  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2158  {
2159  if( token != T_LEFT )
2160  Expecting( T_LEFT );
2161 
2162  token = NextTok();
2163 
2164  switch( token )
2165  {
2166  case T_layer:
2167  dimension->SetLayer( parseBoardItemLayer() );
2168  NeedRIGHT();
2169  break;
2170 
2171  case T_tstamp:
2172  NextTok();
2173  const_cast<KIID&>( dimension->m_Uuid ) = KIID( CurStr() );
2174  NeedRIGHT();
2175  break;
2176 
2177  case T_gr_text:
2178  {
2179  TEXTE_PCB* text = parseTEXTE_PCB();
2180  dimension->Text() = *text;
2181 
2182  // The text is part of the dimension and shares its uuid
2183  const_cast<KIID&>( dimension->Text().m_Uuid ) = dimension->m_Uuid;
2184 
2185  // Fetch other dimension properties out of the text item
2186  dimension->SetPosition( text->GetTextPos() );
2187 
2188  EDA_UNITS units = EDA_UNITS::INCHES;
2189  bool useMils = false;
2190  FetchUnitsFromString( text->GetText(), units, useMils );
2191  dimension->SetUnits( units, useMils );
2192 
2193  delete text;
2194  break;
2195  }
2196 
2197  case T_feature1:
2198  NeedLEFT();
2199  token = NextTok();
2200 
2201  if( token != T_pts )
2202  Expecting( T_pts );
2203 
2204  parseXY( &dimension->m_featureLineDO.x, &dimension->m_featureLineDO.y );
2205  parseXY( &dimension->m_featureLineDF.x, &dimension->m_featureLineDF.y );
2206  dimension->UpdateHeight();
2207  NeedRIGHT();
2208  NeedRIGHT();
2209  break;
2210 
2211  case T_feature2:
2212  NeedLEFT();
2213  token = NextTok();
2214 
2215  if( token != T_pts )
2216  Expecting( T_pts );
2217 
2218  parseXY( &dimension->m_featureLineGO.x, &dimension->m_featureLineGO.y );
2219  parseXY( &dimension->m_featureLineGF.x, &dimension->m_featureLineGF.y );
2220  dimension->UpdateHeight();
2221  NeedRIGHT();
2222  NeedRIGHT();
2223  break;
2224 
2225 
2226  case T_crossbar:
2227  NeedLEFT();
2228  token = NextTok();
2229 
2230  if( token != T_pts )
2231  Expecting( T_pts );
2232 
2233  parseXY( &dimension->m_crossBarO.x, &dimension->m_crossBarO.y );
2234  parseXY( &dimension->m_crossBarF.x, &dimension->m_crossBarF.y );
2235  dimension->UpdateHeight();
2236  NeedRIGHT();
2237  NeedRIGHT();
2238  break;
2239 
2240  case T_arrow1a:
2241  NeedLEFT();
2242  token = NextTok();
2243 
2244  if( token != T_pts )
2245  Expecting( T_pts );
2246 
2247  parseXY( &dimension->m_crossBarF.x, &dimension->m_crossBarF.y );
2248  parseXY( &dimension->m_arrowD1F.x, &dimension->m_arrowD1F.y );
2249  NeedRIGHT();
2250  NeedRIGHT();
2251  break;
2252 
2253  case T_arrow1b:
2254  NeedLEFT();
2255  token = NextTok();
2256 
2257  if( token != T_pts )
2258  Expecting( T_pts );
2259 
2260  parseXY( &dimension->m_crossBarF.x, &dimension->m_crossBarF.y );
2261  parseXY( &dimension->m_arrowD2F.x, &dimension->m_arrowD2F.y );
2262  NeedRIGHT();
2263  NeedRIGHT();
2264  break;
2265 
2266  case T_arrow2a:
2267  NeedLEFT();
2268  token = NextTok();
2269 
2270  if( token != T_pts )
2271  Expecting( T_pts );
2272 
2273  parseXY( &dimension->m_crossBarO.x, &dimension->m_crossBarO.y );
2274  parseXY( &dimension->m_arrowG1F.x, &dimension->m_arrowG1F.y );
2275  NeedRIGHT();
2276  NeedRIGHT();
2277  break;
2278 
2279  case T_arrow2b:
2280  NeedLEFT();
2281  token = NextTok();
2282 
2283  if( token != T_pts )
2284  Expecting( T_pts );
2285 
2286  parseXY( &dimension->m_crossBarO.x, &dimension->m_crossBarO.y );
2287  parseXY( &dimension->m_arrowG2F.x, &dimension->m_arrowG2F.y );
2288  NeedRIGHT();
2289  NeedRIGHT();
2290  break;
2291 
2292  default:
2293  Expecting( "layer, tstamp, gr_text, feature1, feature2 crossbar, arrow1a, "
2294  "arrow1b, arrow2a, or arrow2b" );
2295  }
2296  }
2297 
2298  return dimension.release();
2299 }
EDA_UNITS
Definition: common.h:184
wxPoint parseXY()
Function parseXY parses a coordinate pair (xy X Y) in board units (mm).
Definition: pcb_parser.cpp:231
int parseBoardUnits()
Definition: pcb_parser.h:255
Definition: common.h:65
#define NULL
PCB_LAYER_ID parseBoardItemLayer()
Function parseBoardItemLayer parses the layer definition of a BOARD_ITEM object.
TEXTE_PCB * parseTEXTE_PCB()
const KIID m_Uuid
Definition: base_struct.h:169
void FetchUnitsFromString(const wxString &aTextValue, EDA_UNITS &aUnits, bool &aUseMils)
Function FetchUnitsFromString writes any unit info found in the string to aUnits and aUseMils.
Definition: base_units.cpp:405
const wxPoint & GetTextPos() const
Definition: eda_text.h:232
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:123
DIMENSION.

References FetchUnitsFromString(), EDA_TEXT::GetText(), EDA_TEXT::GetTextPos(), INCHES, EDA_ITEM::m_Uuid, and NULL.

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

150 {
151  char* tmp;
152 
153  errno = 0;
154 
155  double fval = strtod( CurText(), &tmp );
156 
157  if( errno )
158  {
159  wxString error;
160  error.Printf( _( "Invalid floating point number in\nfile: \"%s\"\nline: %d\noffset: %d" ),
161  GetChars( CurSource() ), CurLineNumber(), CurOffset() );
162 
163  THROW_IO_ERROR( error );
164  }
165 
166  if( CurText() == tmp )
167  {
168  wxString error;
169  error.Printf( _( "Missing floating point number in\nfile: \"%s\"\nline: %d\noffset: %d" ),
170  GetChars( CurSource() ), CurLineNumber(), CurOffset() );
171 
172  THROW_IO_ERROR( error );
173  }
174 
175  return fval;
176 }
#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:101
#define _(s)
Definition: 3d_actions.cpp:33

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

245  {
246  NeedNUMBER( aExpected );
247  return parseDouble();
248  }
double parseDouble()
Function parseDouble parses the current token as an ASCII numeric string with possible leading whites...
Definition: pcb_parser.cpp:149

References parseDouble().

◆ parseDouble() [3/3]

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

Definition at line 250 of file pcb_parser.h.

251  {
252  return parseDouble( GetTokenText( aToken ) );
253  }
double parseDouble()
Function parseDouble parses the current token as an ASCII numeric string with possible leading whites...
Definition: pcb_parser.cpp:149
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 1895 of file pcb_parser.cpp.

1896 {
1897  wxCHECK_MSG( CurTok() == T_gr_arc || CurTok() == T_gr_circle || CurTok() == T_gr_curve ||
1898  CurTok() == T_gr_line || CurTok() == T_gr_poly, NULL,
1899  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as DRAWSEGMENT." ) );
1900 
1901  T token;
1902  wxPoint pt;
1903  std::unique_ptr< DRAWSEGMENT > segment( new DRAWSEGMENT( NULL ) );
1904 
1905  switch( CurTok() )
1906  {
1907  case T_gr_arc:
1908  segment->SetShape( S_ARC );
1909  NeedLEFT();
1910  token = NextTok();
1911 
1912  // the start keyword actually gives the arc center
1913  // Allows also T_center for future change
1914  if( token != T_start && token != T_center )
1915  Expecting( T_start );
1916 
1917  pt.x = parseBoardUnits( "X coordinate" );
1918  pt.y = parseBoardUnits( "Y coordinate" );
1919  segment->SetCenter( pt );
1920  NeedRIGHT();
1921  NeedLEFT();
1922  token = NextTok();
1923 
1924  if( token != T_end ) // the end keyword actually gives the starting point of the arc
1925  Expecting( T_end );
1926 
1927  pt.x = parseBoardUnits( "X coordinate" );
1928  pt.y = parseBoardUnits( "Y coordinate" );
1929  segment->SetArcStart( pt );
1930  NeedRIGHT();
1931  break;
1932 
1933  case T_gr_circle:
1934  segment->SetShape( S_CIRCLE );
1935  NeedLEFT();
1936  token = NextTok();
1937 
1938  if( token != T_center )
1939  Expecting( T_center );
1940 
1941  pt.x = parseBoardUnits( "X coordinate" );
1942  pt.y = parseBoardUnits( "Y coordinate" );
1943  segment->SetCenter( pt );
1944  NeedRIGHT();
1945  NeedLEFT();
1946 
1947  token = NextTok();
1948 
1949  if( token != T_end )
1950  Expecting( T_end );
1951 
1952  pt.x = parseBoardUnits( "X coordinate" );
1953  pt.y = parseBoardUnits( "Y coordinate" );
1954  segment->SetEnd( pt );
1955  NeedRIGHT();
1956  break;
1957 
1958  case T_gr_curve:
1959  segment->SetShape( S_CURVE );
1960  NeedLEFT();
1961  token = NextTok();
1962 
1963  if( token != T_pts )
1964  Expecting( T_pts );
1965 
1966  segment->SetStart( parseXY() );
1967  segment->SetBezControl1( parseXY() );
1968  segment->SetBezControl2( parseXY() );
1969  segment->SetEnd( parseXY() );
1970  NeedRIGHT();
1971  break;
1972 
1973  case T_gr_line:
1974  // Default DRAWSEGMENT type is S_SEGMENT.
1975  NeedLEFT();
1976  token = NextTok();
1977 
1978  if( token != T_start )
1979  Expecting( T_start );
1980 
1981  pt.x = parseBoardUnits( "X coordinate" );
1982  pt.y = parseBoardUnits( "Y coordinate" );
1983  segment->SetStart( pt );
1984  NeedRIGHT();
1985  NeedLEFT();
1986  token = NextTok();
1987 
1988  if( token != T_end )
1989  Expecting( T_end );
1990 
1991  pt.x = parseBoardUnits( "X coordinate" );
1992  pt.y = parseBoardUnits( "Y coordinate" );
1993  segment->SetEnd( pt );
1994  NeedRIGHT();
1995  break;
1996 
1997  case T_gr_poly:
1998  {
1999  segment->SetShape( S_POLYGON );
2000  segment->SetWidth( 0 ); // this is the default value. will be (perhaps) modified later
2001  NeedLEFT();
2002  token = NextTok();
2003 
2004  if( token != T_pts )
2005  Expecting( T_pts );
2006 
2007  std::vector< wxPoint > pts;
2008 
2009  while( (token = NextTok()) != T_RIGHT )
2010  pts.push_back( parseXY() );
2011 
2012  segment->SetPolyPoints( pts );
2013  }
2014  break;
2015 
2016  default:
2017  Expecting( "gr_arc, gr_circle, gr_curve, gr_line, or gr_poly" );
2018  }
2019 
2020  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2021  {
2022  if( token != T_LEFT )
2023  Expecting( T_LEFT );
2024 
2025  token = NextTok();
2026 
2027  switch( token )
2028  {
2029  case T_angle:
2030  segment->SetAngle( parseDouble( "segment angle" ) * 10.0 );
2031  break;
2032 
2033  case T_layer:
2034  segment->SetLayer( parseBoardItemLayer() );
2035  break;
2036 
2037  case T_width:
2038  segment->SetWidth( parseBoardUnits( T_width ) );
2039  break;
2040 
2041  case T_tstamp:
2042  NextTok();
2043  const_cast<KIID&>( segment->m_Uuid ) = KIID( CurStr() );
2044  break;
2045 
2046  case T_status:
2047  segment->SetStatus( static_cast<STATUS_FLAGS>( parseHex() ) );
2048  break;
2049 
2050  default:
2051  Expecting( "layer, width, tstamp, or status" );
2052  }
2053 
2054  NeedRIGHT();
2055  }
2056 
2057  // Only filled polygons may have a zero-line width
2058  // This is not permitted in KiCad but some external tools generate invalid
2059  // files.
2060  // However in custom pad shapes, zero-line width is allowed for filled circles
2061  if( segment->GetShape() != S_POLYGON && segment->GetWidth() == 0 &&
2062  !( segment->GetShape() == S_CIRCLE && aAllowCirclesZeroWidth ) )
2063  segment->SetWidth( Millimeter2iu( DEFAULT_LINE_WIDTH ) );
2064 
2065  return segment.release();
2066 }
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:231
#define DEFAULT_LINE_WIDTH
int parseBoardUnits()
Definition: pcb_parser.h:255
Definition: common.h:65
#define NULL
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:149
long parseHex()
Definition: pcb_parser.h:304

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

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

264 {
265  wxCHECK_RET( CurTok() == T_effects,
266  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as EDA_TEXT." ) );
267 
268  T token;
269 
270  // Prior to v5.0 text size was omitted from file format if equal to 60mils
271  // Now, it is always explicitly written to file
272  bool foundTextSize = false;
273 
274  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
275  {
276  if( token == T_LEFT )
277  token = NextTok();
278 
279  switch( token )
280  {
281  case T_font:
282  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
283  {
284  if( token == T_LEFT )
285  continue;
286 
287  switch( token )
288  {
289  case T_size:
290  {
291  wxSize sz;
292  sz.SetHeight( parseBoardUnits( "text height" ) );
293  sz.SetWidth( parseBoardUnits( "text width" ) );
294  aText->SetTextSize( sz );
295  NeedRIGHT();
296 
297  foundTextSize = true;
298  }
299  break;
300 
301  case T_thickness:
302  aText->SetThickness( parseBoardUnits( "text thickness" ) );
303  NeedRIGHT();
304  break;
305 
306  case T_bold:
307  aText->SetBold( true );
308  break;
309 
310  case T_italic:
311  aText->SetItalic( true );
312  break;
313 
314  default:
315  Expecting( "size, bold, or italic" );
316  }
317  }
318  break;
319 
320  case T_justify:
321  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
322  {
323  if( token == T_LEFT )
324  continue;
325 
326  switch( token )
327  {
328  case T_left:
330  break;
331 
332  case T_right:
334  break;
335 
336  case T_top:
338  break;
339 
340  case T_bottom:
342  break;
343 
344  case T_mirror:
345  aText->SetMirrored( true );
346  break;
347 
348  default:
349  Expecting( "left, right, top, bottom, or mirror" );
350  }
351 
352  }
353  break;
354 
355  case T_hide:
356  aText->SetVisible( false );
357  break;
358 
359  default:
360  Expecting( "font, justify, or hide" );
361  }
362  }
363 
364  // Text size was not specified in file, force legacy default units
365  // 60mils is 1.524mm
366  if( !foundTextSize )
367  {
368  const double defaultTextSize = 1.524 * IU_PER_MM;
369 
370  aText->SetTextSize( wxSize( defaultTextSize, defaultTextSize ) );
371  }
372 }
void SetMirrored(bool isMirrored)
Definition: eda_text.h:172
void SetItalic(bool isItalic)
Definition: eda_text.h:163
void SetVisible(bool aVisible)
Definition: eda_text.h:169
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:222
int parseBoardUnits()
Definition: pcb_parser.h:255
void SetVertJustify(EDA_TEXT_VJUSTIFY_T aType)
Definition: eda_text.h:187
void SetHorizJustify(EDA_TEXT_HJUSTIFY_T aType)
Definition: eda_text.h:186
void SetBold(bool aBold)
Definition: eda_text.h:166
void SetThickness(int aNewThickness)
Set the pen width.
Definition: eda_text.h:143

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

2689 {
2690  wxCHECK_MSG( CurTok() == T_fp_arc || CurTok() == T_fp_circle || CurTok() == T_fp_curve ||
2691  CurTok() == T_fp_line || CurTok() == T_fp_poly, NULL,
2692  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as EDGE_MODULE." ) );
2693 
2694  wxPoint pt;
2695  T token;
2696 
2697  std::unique_ptr< EDGE_MODULE > segment( new EDGE_MODULE( NULL ) );
2698 
2699  switch( CurTok() )
2700  {
2701  case T_fp_arc:
2702  segment->SetShape( S_ARC );
2703  NeedLEFT();
2704  token = NextTok();
2705 
2706  // the start keyword actually gives the arc center
2707  // Allows also T_center for future change
2708  if( token != T_start && token != T_center )
2709  Expecting( T_start );
2710 
2711  pt.x = parseBoardUnits( "X coordinate" );
2712  pt.y = parseBoardUnits( "Y coordinate" );
2713  segment->SetStart0( pt );
2714  NeedRIGHT();
2715  NeedLEFT();
2716  token = NextTok();
2717 
2718  if( token != T_end ) // end keyword actually gives the starting point of the arc
2719  Expecting( T_end );
2720 
2721  pt.x = parseBoardUnits( "X coordinate" );
2722  pt.y = parseBoardUnits( "Y coordinate" );
2723  segment->SetEnd0( pt );
2724  NeedRIGHT();
2725  NeedLEFT();
2726  token = NextTok();
2727 
2728  if( token != T_angle )
2729  Expecting( T_angle );
2730 
2731  segment->SetAngle( parseDouble( "segment angle" ) * 10.0 );
2732  NeedRIGHT();
2733  break;
2734 
2735  case T_fp_circle:
2736  segment->SetShape( S_CIRCLE );
2737  NeedLEFT();
2738  token = NextTok();
2739 
2740  if( token != T_center )
2741  Expecting( T_center );
2742 
2743  pt.x = parseBoardUnits( "X coordinate" );
2744  pt.y = parseBoardUnits( "Y coordinate" );
2745  segment->SetStart0( pt );
2746  NeedRIGHT();
2747  NeedLEFT();
2748  token = NextTok();
2749 
2750  if( token != T_end )
2751  Expecting( T_end );
2752 
2753  pt.x = parseBoardUnits( "X coordinate" );
2754  pt.y = parseBoardUnits( "Y coordinate" );
2755  segment->SetEnd0( pt );
2756  NeedRIGHT();
2757  break;
2758 
2759  case T_fp_curve:
2760  segment->SetShape( S_CURVE );
2761  NeedLEFT();
2762  token = NextTok();
2763 
2764  if( token != T_pts )
2765  Expecting( T_pts );
2766 
2767  segment->SetStart0( parseXY() );
2768  segment->SetBezier0_C1( parseXY() );
2769  segment->SetBezier0_C2( parseXY() );
2770  segment->SetEnd0( parseXY() );
2771  NeedRIGHT();
2772  break;
2773 
2774  case T_fp_line:
2775  // Default DRAWSEGMENT type is S_SEGMENT.
2776  NeedLEFT();
2777  token = NextTok();
2778 
2779  if( token != T_start )
2780  Expecting( T_start );
2781 
2782  pt.x = parseBoardUnits( "X coordinate" );
2783  pt.y = parseBoardUnits( "Y coordinate" );
2784  segment->SetStart0( pt );
2785 
2786  NeedRIGHT();
2787  NeedLEFT();
2788  token = NextTok();
2789 
2790  if( token != T_end )
2791  Expecting( T_end );
2792 
2793  pt.x = parseBoardUnits( "X coordinate" );
2794  pt.y = parseBoardUnits( "Y coordinate" );
2795  segment->SetEnd0( pt );
2796  NeedRIGHT();
2797  break;
2798 
2799  case T_fp_poly:
2800  {
2801  segment->SetShape( S_POLYGON );
2802  NeedLEFT();
2803  token = NextTok();
2804 
2805  if( token != T_pts )
2806  Expecting( T_pts );
2807 
2808  std::vector< wxPoint > pts;
2809 
2810  while( (token = NextTok()) != T_RIGHT )
2811  pts.push_back( parseXY() );
2812 
2813  segment->SetPolyPoints( pts );
2814  }
2815  break;
2816 
2817  default:
2818  Expecting( "fp_arc, fp_circle, fp_curve, fp_line, or fp_poly" );
2819  }
2820 
2821  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2822  {
2823  if( token != T_LEFT )
2824  Expecting( T_LEFT );
2825 
2826  token = NextTok();
2827 
2828  switch( token )
2829  {
2830  case T_layer:
2831  segment->SetLayer( parseBoardItemLayer() );
2832  break;
2833 
2834  case T_width:
2835  segment->SetWidth( parseBoardUnits( T_width ) );
2836  break;
2837 
2838  case T_tstamp:
2839  NextTok();
2840  const_cast<KIID&>( segment->m_Uuid ) = KIID( CurStr() );
2841  break;
2842 
2843  case T_status:
2844  segment->SetStatus( static_cast<STATUS_FLAGS>( parseHex() ) );
2845  break;
2846 
2847  default:
2848  Expecting( "layer or width" );
2849  }
2850 
2851  NeedRIGHT();
2852  }
2853 
2854  // Only filled polygons may have a zero-line width
2855  // This is not permitted in KiCad but some external tools generate invalid
2856  // files.
2857  if( segment->GetShape() != S_POLYGON && segment->GetWidth() == 0 )
2858  segment->SetWidth( Millimeter2iu( DEFAULT_LINE_WIDTH ) );
2859 
2860  return segment.release();
2861 }
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:231
#define DEFAULT_LINE_WIDTH
int parseBoardUnits()
Definition: pcb_parser.h:255
Definition: common.h:65
#define NULL
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:149
long parseHex()
Definition: pcb_parser.h:304

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

◆ parseGeneralSection()

void PCB_PARSER::parseGeneralSection ( )
private

Definition at line 731 of file pcb_parser.cpp.

732 {
733  wxCHECK_RET( CurTok() == T_general,
734  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
735  wxT( " as a general section." ) );
736 
737  T token;
738 
739  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
740  {
741  if( token != T_LEFT )
742  Expecting( T_LEFT );
743 
744  token = NextTok();
745 
746  switch( token )
747  {
748  case T_thickness:
750  NeedRIGHT();
751  break;
752 
753  case T_nets:
754  m_netCodes.resize( parseInt( "nets number" ) );
755  NeedRIGHT();
756  break;
757 
758  case T_no_connects:
759  // ignore
760  parseInt( "no connect count" );
761  NeedRIGHT();
762  break;
763 
764  default: // Skip everything but the board thickness.
765  //wxLogDebug( wxT( "Skipping general section token %s " ), GetChars( GetTokenString( token ) ) );
766 
767  while( ( token = NextTok() ) != T_RIGHT )
768  {
769  if( !IsSymbol( token ) && token != T_NUMBER )
770  Expecting( "symbol or number" );
771  }
772  }
773  }
774 }
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:512
void SetBoardThickness(int aThickness)
int parseBoardUnits()
Definition: pcb_parser.h:255
std::vector< int > m_netCodes
net codes mapping for boards being loaded
Definition: pcb_parser.h:78
BOARD * m_board
Definition: pcb_parser.h:74
int parseInt()
Definition: pcb_parser.h:293

References parseInt().

◆ parseHeader()

void PCB_PARSER::parseHeader ( )
private

Definition at line 695 of file pcb_parser.cpp.

696 {
697  wxCHECK_RET( CurTok() == T_kicad_pcb,
698  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a header." ) );
699 
700  NeedLEFT();
701 
702  T tok = NextTok();
703  if( tok == T_version )
704  {
705  m_requiredVersion = parseInt( FromUTF8().mb_str( wxConvUTF8 ) );
707  NeedRIGHT();
708 
709  // Skip the host name and host build version information.
710  NeedLEFT();
711  NeedSYMBOL();
712  NeedSYMBOL();
713  NeedSYMBOL();
714  NeedRIGHT();
715  }
716  else
717  {
720 
721  // Skip the host name and host build version information.
722  NeedSYMBOL();
723  NeedSYMBOL();
724  NeedRIGHT();
725  }
726 
728 }
void SetFileFormatVersionAtLoad(int aVersion)
Definition: class_board.h:272
#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:79
int m_requiredVersion
set to the KiCad format version this board requires
Definition: pcb_parser.h:80
BOARD * m_board
Definition: pcb_parser.h:74
int parseInt()
Definition: pcb_parser.h:293

References parseInt(), and SEXPR_BOARD_FILE_VERSION.

◆ parseHex()

long PCB_PARSER::parseHex ( )
inlineprivate

Definition at line 304 of file pcb_parser.h.

305  {
306  NextTok();
307  return strtol( CurText(), NULL, 16 );
308  }
#define NULL

References NULL.

◆ parseInt() [1/2]

int PCB_PARSER::parseInt ( )
inlineprivate

Definition at line 293 of file pcb_parser.h.

294  {
295  return (int)strtol( CurText(), NULL, 10 );
296  }
#define NULL

References NULL.

Referenced by parseInt().

◆ parseInt() [2/2]

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

Definition at line 298 of file pcb_parser.h.

299  {
300  NeedNUMBER( aExpected );
301  return parseInt();
302  }
int parseInt()
Definition: pcb_parser.h:293

References parseInt().

◆ parseLayer()

void PCB_PARSER::parseLayer ( LAYER aLayer)
private

Definition at line 941 of file pcb_parser.cpp.

942 {
943  T token;
944 
945  std::string name;
946  std::string type;
947  bool isVisible = true;
948 
949  aLayer->clear();
950 
951  if( CurTok() != T_LEFT )
952  Expecting( T_LEFT );
953 
954  // this layer_num is not used, we DO depend on LAYER_T however.
955  LAYER_NUM layer_num = parseInt( "layer index" );
956 
957  NeedSYMBOLorNUMBER();
958  name = CurText();
959 
960  NeedSYMBOL();
961  type = CurText();
962 
963  token = NextTok();
964 
965  if( token == T_hide )
966  {
967  isVisible = false;
968  NeedRIGHT();
969  }
970  else if( token != T_RIGHT )
971  {
972  Expecting( "hide or )" );
973  }
974 
975  aLayer->m_name = FROM_UTF8( name.c_str() );
976  aLayer->m_type = LAYER::ParseType( type.c_str() );
977  aLayer->m_number = layer_num;
978  aLayer->m_visible = isVisible;
979 }
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:62
wxString m_name
The name of the layer, there should be no spaces in this name.
Definition: class_board.h:108
LAYER_T m_type
The type of the layer.
Definition: class_board.h:109
bool m_visible
Definition: class_board.h:110
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:89
const char * name
Definition: DXF_plotter.cpp:60
int m_number
Definition: class_board.h:111
int parseInt()
Definition: pcb_parser.h:293

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

1229 {
1230  wxCHECK_RET( CurTok() == T_layers,
1231  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as layers." ) );
1232 
1233  T token;
1234  LSET visibleLayers;
1235  LSET enabledLayers;
1236  int copperLayerCount = 0;
1237  LAYER layer;
1238 
1239  std::unordered_map< std::string, std::string > v3_layer_names;
1240  std::vector<LAYER> cu;
1241 
1242  createOldLayerMapping( v3_layer_names );
1243 
1244  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1245  {
1246  parseLayer( &layer );
1247 
1248  if( layer.m_type == LT_UNDEFINED ) // it's a non-copper layer
1249  break;
1250 
1251  cu.push_back( layer ); // it's copper
1252  }
1253 
1254  // All Cu layers are parsed, but not the non-cu layers here.
1255 
1256  // The original *.kicad_pcb file format and the inverted
1257  // Cu stack format both have all the Cu layers first, so use this
1258  // trick to handle either. The layer number in the (layers ..)
1259  // s-expression element are ignored.
1260  if( cu.size() )
1261  {
1262  // Rework the layer numbers, which changed when the Cu stack
1263  // was flipped. So we instead use position in the list.
1264  cu[cu.size()-1].m_number = B_Cu;
1265 
1266  for( unsigned i=0; i < cu.size()-1; ++i )
1267  {
1268  cu[i].m_number = i;
1269  }
1270 
1271  for( std::vector<LAYER>::const_iterator it = cu.begin(); it<cu.end(); ++it )
1272  {
1273  enabledLayers.set( it->m_number );
1274 
1275  if( it->m_visible )
1276  visibleLayers.set( it->m_number );
1277 
1278  m_board->SetLayerDescr( PCB_LAYER_ID( it->m_number ), *it );
1279 
1280  UTF8 name = it->m_name;
1281 
1282  m_layerIndices[ name ] = PCB_LAYER_ID( it->m_number );
1283  m_layerMasks[ name ] = LSET( PCB_LAYER_ID( it->m_number ) );
1284  }
1285 
1286  copperLayerCount = cu.size();
1287  }
1288 
1289  // process non-copper layers
1290  while( token != T_RIGHT )
1291  {
1292  LAYER_ID_MAP::const_iterator it = m_layerIndices.find( UTF8( layer.m_name ) );
1293 
1294  if( it == m_layerIndices.end() )
1295  {
1296  auto new_layer_it = v3_layer_names.find( layer.m_name.ToStdString() );
1297 
1298  if( new_layer_it != v3_layer_names.end() )
1299  it = m_layerIndices.find( new_layer_it->second );
1300 
1301  if( it == m_layerIndices.end() )
1302  {
1303  wxString error = wxString::Format(
1304  _( "Layer \"%s\" in file \"%s\" at line %d, is not in fixed layer hash" ),
1305  GetChars( layer.m_name ),
1306  GetChars( CurSource() ),
1307  CurLineNumber(),
1308  CurOffset()
1309  );
1310 
1311  THROW_IO_ERROR( error );
1312  }
1313 
1314  // If we are here, then we have found a translated layer name. Put it in the maps so that
1315  // items on this layer get the appropriate layer ID number
1316  m_layerIndices[ UTF8( layer.m_name ) ] = it->second;
1317  m_layerMasks[ UTF8( layer.m_name ) ] = it->second;
1318  layer.m_name = it->first;
1319  }
1320 
1321  layer.m_number = it->second;
1322  enabledLayers.set( layer.m_number );
1323 
1324  if( layer.m_visible )
1325  visibleLayers.set( layer.m_number );
1326 
1327  m_board->SetLayerDescr( it->second, layer );
1328 
1329  token = NextTok();
1330 
1331  if( token != T_LEFT )
1332  break;
1333 
1334  parseLayer( &layer );
1335  }
1336 
1337  // We need at least 2 copper layers and there must be an even number of them.
1338  if( copperLayerCount < 2 || (copperLayerCount % 2) != 0 )
1339  {
1340  wxString err = wxString::Format(
1341  _( "%d is not a valid layer count" ), copperLayerCount );
1342 
1343  THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
1344  }
1345 
1346  m_board->SetCopperLayerCount( copperLayerCount );
1347  m_board->SetEnabledLayers( enabledLayers );
1348 
1349  // call SetEnabledLayers before SetVisibleLayers()
1350  m_board->SetVisibleLayers( visibleLayers );
1351 }
UTF8 is an 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to...
Definition: utf8.h:73
wxString m_name
The name of the layer, there should be no spaces in this name.
Definition: class_board.h:108
LAYER_T m_type
The type of the layer.
Definition: class_board.h:109
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...
void SetCopperLayerCount(int aCount)
PCB_LAYER_ID
A quick note on layer IDs:
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:110
#define THROW_IO_ERROR(msg)
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
void parseLayer(LAYER *aLayer)
Definition: pcb_parser.cpp:941
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:101
const char * name
Definition: DXF_plotter.cpp:60
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
LAYER holds information pertinent to a layer of a BOARD.
Definition: class_board.h:82
#define _(s)
Definition: 3d_actions.cpp:33
BOARD * m_board
Definition: pcb_parser.h:74
LAYER_ID_MAP m_layerIndices
map layer name to it's index
Definition: pcb_parser.h:75
int m_number
Definition: class_board.h:111
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:76

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

◆ parseMARKER()

MARKER_PCB* PCB_PARSER::parseMARKER ( BOARD_ITEM_CONTAINER aParent)
private

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

2303 {
2304  try
2305  {
2306  return parseMODULE_unchecked( aInitialComments );
2307  }
2308  catch( const PARSE_ERROR& parse_error )
2309  {
2310  if( m_tooRecent )
2311  throw FUTURE_FORMAT_ERROR( parse_error, GetRequiredVersion() );
2312  else
2313  throw;
2314  }
2315 }
bool m_tooRecent
true if version parses as later than supported
Definition: pcb_parser.h:79
wxString GetRequiredVersion()
Return a string representing the version of kicad required to open this file.
Definition: pcb_parser.cpp:207
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 2318 of file pcb_parser.cpp.

2319 {
2320  wxCHECK_MSG( CurTok() == T_module, NULL,
2321  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as MODULE." ) );
2322 
2323  wxString name;
2324  wxPoint pt;
2325  T token;
2326  LIB_ID fpid;
2327 
2328  std::unique_ptr<MODULE> module( new MODULE( m_board ) );
2329 
2330  module->SetInitialComments( aInitialComments );
2331 
2332  token = NextTok();
2333 
2334  if( !IsSymbol( token ) && token != T_NUMBER )
2335  Expecting( "symbol|number" );
2336 
2337  name = FromUTF8();
2338 
2339  if( !name.IsEmpty() && fpid.Parse( name, LIB_ID::ID_PCB, true ) >= 0 )
2340  {
2341  wxString error;
2342  error.Printf( _( "Invalid footprint ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),
2343  GetChars( CurSource() ), CurLineNumber(), CurOffset() );
2344  THROW_IO_ERROR( error );
2345  }
2346 
2347  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2348  {
2349  if( token == T_LEFT )
2350  token = NextTok();
2351 
2352  switch( token )
2353  {
2354  case T_version:
2355  {
2356  // Theoretically a module nested in a PCB could declare its own version, though
2357  // as of writing this comment we don't do that. Just in case, take the greater
2358  // version.
2359  int this_version = parseInt( FromUTF8().mb_str( wxConvUTF8 ) );
2360  NeedRIGHT();
2361  m_requiredVersion = std::max( m_requiredVersion, this_version );
2363  break;
2364  }
2365 
2366  case T_locked:
2367  module->SetLocked( true );
2368  break;
2369 
2370  case T_placed:
2371  module->SetIsPlaced( true );
2372  break;
2373 
2374  case T_layer:
2375  {
2376  // Footprints can be only on the front side or the back side.
2377  // but because we can find some stupid layer in file, ensure a
2378  // acceptable layer is set for the footprint
2380  module->SetLayer( layer == B_Cu ? B_Cu : F_Cu );
2381  }
2382  NeedRIGHT();
2383  break;
2384 
2385  case T_tedit:
2386  module->SetLastEditTime( parseHex() );
2387  NeedRIGHT();
2388  break;
2389 
2390  case T_tstamp:
2391  NextTok();
2392  const_cast<KIID&>( module->m_Uuid ) = KIID( CurStr() );
2393  NeedRIGHT();
2394  break;
2395 
2396  case T_at:
2397  pt.x = parseBoardUnits( "X coordinate" );
2398  pt.y = parseBoardUnits( "Y coordinate" );
2399  module->SetPosition( pt );
2400  token = NextTok();
2401 
2402  if( token == T_NUMBER )
2403  {
2404  module->SetOrientation( parseDouble() * 10.0 );
2405  NeedRIGHT();
2406  }
2407  else if( token != T_RIGHT )
2408  {
2409  Expecting( T_RIGHT );
2410  }
2411 
2412  break;
2413 
2414  case T_descr:
2415  NeedSYMBOLorNUMBER(); // some symbols can be 0508, so a number is also a symbol here
2416  module->SetDescription( FromUTF8() );
2417  NeedRIGHT();
2418  break;
2419 
2420  case T_tags:
2421  NeedSYMBOLorNUMBER(); // some symbols can be 0508, so a number is also a symbol here
2422  module->SetKeywords( FromUTF8() );
2423  NeedRIGHT();
2424  break;
2425 
2426  case T_path:
2427  NeedSYMBOLorNUMBER(); // Paths can be numerical so a number is also a symbol here
2428  module->SetPath( KIID_PATH( FromUTF8() ) );
2429  NeedRIGHT();
2430  break;
2431 
2432  case T_autoplace_cost90:
2433  module->SetPlacementCost90( parseInt( "auto place cost at 90 degrees" ) );
2434  NeedRIGHT();
2435  break;
2436 
2437  case T_autoplace_cost180:
2438  module->SetPlacementCost180( parseInt( "auto place cost at 180 degrees" ) );
2439  NeedRIGHT();
2440  break;
2441 
2442  case T_solder_mask_margin:
2443  module->SetLocalSolderMaskMargin( parseBoardUnits( "local solder mask margin value" ) );
2444  NeedRIGHT();
2445  break;
2446 
2447  case T_solder_paste_margin:
2448  module->SetLocalSolderPasteMargin(
2449  parseBoardUnits( "local solder paste margin value" ) );
2450  NeedRIGHT();
2451  break;
2452 
2453  case T_solder_paste_ratio:
2454  module->SetLocalSolderPasteMarginRatio(
2455  parseDouble( "local solder paste margin ratio value" ) );
2456  NeedRIGHT();
2457  break;
2458 
2459  case T_clearance:
2460  module->SetLocalClearance( parseBoardUnits( "local clearance value" ) );
2461  NeedRIGHT();
2462  break;
2463 
2464  case T_zone_connect:
2465  module->SetZoneConnection( (ZONE_CONNECTION) parseInt( "zone connection value" ) );
2466  NeedRIGHT();
2467  break;
2468 
2469  case T_thermal_width:
2470  module->SetThermalWidth( parseBoardUnits( "thermal width value" ) );
2471  NeedRIGHT();
2472  break;
2473 
2474  case T_thermal_gap:
2475  module->SetThermalGap( parseBoardUnits( "thermal gap value" ) );
2476  NeedRIGHT();
2477  break;
2478 
2479  case T_attr:
2480  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2481  {
2482  switch( token )
2483  {
2484  case T_smd:
2485  module->SetAttributes( module->GetAttributes() | MOD_CMS );
2486  break;
2487 
2488  case T_virtual:
2489  module->SetAttributes( module->GetAttributes() | MOD_VIRTUAL );
2490  break;
2491 
2492  default:
2493  Expecting( "smd and/or virtual" );
2494  }
2495  }
2496  break;
2497 
2498  case T_fp_text:
2499  {
2500  TEXTE_MODULE* text = parseTEXTE_MODULE();
2501  text->SetParent( module.get() );
2502  double orientation = text->GetTextAngle();
2503  orientation -= module->GetOrientation();
2504  text->SetTextAngle( orientation );
2505  text->SetDrawCoord();
2506 
2507  switch( text->GetType() )
2508  {
2510  module->Reference() = *text;
2511  delete text;
2512  break;
2513 
2515  module->Value() = *text;
2516  delete text;
2517  break;
2518 
2519  default:
2520  module->Add( text );
2521  }
2522  }
2523  break;
2524 
2525  case T_fp_arc:
2526  {
2527  EDGE_MODULE* em = parseEDGE_MODULE();
2528 
2529  // Drop 0 and NaN angles as these can corrupt/crash the schematic
2530  if( std::isnormal( em->GetAngle() ) )
2531  {
2532  em->SetParent( module.get() );
2533  em->SetDrawCoord();
2534  module->Add( em );
2535  }
2536  else
2537  delete em;
2538  }
2539 
2540  break;
2541 
2542  case T_fp_circle:
2543  case T_fp_curve:
2544  case T_fp_line:
2545  case T_fp_poly:
2546  {
2547  EDGE_MODULE* em = parseEDGE_MODULE();
2548  em->SetParent( module.get() );
2549  em->SetDrawCoord();
2550  module->Add( em );
2551  }
2552 
2553  break;
2554 
2555  case T_pad:
2556  {
2557  D_PAD* pad = parseD_PAD( module.get() );
2558  pt = pad->GetPos0();
2559 
2560  RotatePoint( &pt, module->GetOrientation() );
2561  pad->SetPosition( pt + module->GetPosition() );
2562  module->Add( pad, ADD_MODE::APPEND );
2563  }
2564 
2565  break;
2566 
2567  case T_model:
2568  module->Add3DModel( parse3DModel() );
2569  break;
2570 
2571  case T_zone:
2572  {
2573  ZONE_CONTAINER* zone = parseZONE_CONTAINER( module.get() );
2574  module->Add( zone, ADD_MODE::APPEND );
2575  }
2576  break;
2577 
2578  default:
2579  Expecting(
2580  "locked, placed, tedit, tstamp, at, descr, tags, path, "
2581  "autoplace_cost90, autoplace_cost180, solder_mask_margin, "
2582  "solder_paste_margin, solder_paste_ratio, clearance, "
2583  "zone_connect, thermal_width, thermal_gap, attr, fp_text, "
2584  "fp_arc, fp_circle, fp_curve, fp_line, fp_poly, pad, "
2585  "zone, or model" );
2586  }
2587  }
2588 
2589  module->SetFPID( fpid );
2590  module->CalculateBoundingBox();
2591 
2592  return module.release();
2593 }
ZONE_CONNECTION
How pads are covered by copper in zone.
Definition: zones.h:41
ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:60
const wxPoint & GetPos0() const
Definition: class_pad.h:294
Set for modules listed in the automatic insertion list (usually SMD footprints)
Definition: class_module.h:74
#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:158
void SetPosition(const wxPoint &aPos) override
Definition: class_pad.h:240
bool m_tooRecent
true if version parses as later than supported
Definition: pcb_parser.h:79
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:208
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:255
Definition: common.h:65
PCB_LAYER_ID
A quick note on layer IDs:
#define NULL
void SetParent(EDA_ITEM *aParent)
Definition: base_struct.h:218
TEXT_TYPE GetType() const
PCB_LAYER_ID parseBoardItemLayer()
Function parseBoardItemLayer parses the layer definition of a BOARD_ITEM object.
ZONE_CONTAINER * parseZONE_CONTAINER(BOARD_ITEM_CONTAINER *aParent)
#define THROW_IO_ERROR(msg)
double GetAngle() const
int m_requiredVersion
set to the KiCad format version this board requires
Definition: pcb_parser.h:80
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:101
EDGE_MODULE * parseEDGE_MODULE()
const char * name
Definition: DXF_plotter.cpp:60
#define _(s)
Definition: 3d_actions.cpp:33
BOARD * m_board
Definition: pcb_parser.h:74
Virtual component: when created by copper shapes on board (Like edge card connectors,...
Definition: class_module.h:76
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:149
void SetTextAngle(double aAngle)
TEXTE_MODULE * parseTEXTE_MODULE()
D_PAD * parseD_PAD(MODULE *aParent=NULL)
long parseHex()
Definition: pcb_parser.h:304
int parseInt()
Definition: pcb_parser.h:293
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:375

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

◆ parseNETCLASS()

void PCB_PARSER::parseNETCLASS ( )
private

Definition at line 1812 of file pcb_parser.cpp.

1813 {
1814  wxCHECK_RET( CurTok() == T_net_class,
1815  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as net class." ) );
1816 
1817  T token;
1818 
1819  NETCLASSPTR nc = std::make_shared<NETCLASS>( wxEmptyString );
1820 
1821  // Read netclass name (can be a name or just a number like track width)
1822  NeedSYMBOLorNUMBER();
1823  nc->SetName( FromUTF8() );
1824  NeedSYMBOL();
1825  nc->SetDescription( FromUTF8() );
1826 
1827  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1828  {
1829  if( token != T_LEFT )
1830  Expecting( T_LEFT );
1831 
1832  token = NextTok();
1833 
1834  switch( token )
1835  {
1836  case T_clearance:
1837  nc->SetClearance( parseBoardUnits( T_clearance ) );
1838  break;
1839 
1840  case T_trace_width:
1841  nc->SetTrackWidth( parseBoardUnits( T_trace_width ) );
1842  break;
1843 
1844  case T_via_dia:
1845  nc->SetViaDiameter( parseBoardUnits( T_via_dia ) );
1846  break;
1847 
1848  case T_via_drill:
1849  nc->SetViaDrill( parseBoardUnits( T_via_drill ) );
1850  break;
1851 
1852  case T_uvia_dia:
1853  nc->SetuViaDiameter( parseBoardUnits( T_uvia_dia ) );
1854  break;
1855 
1856  case T_uvia_drill:
1857  nc->SetuViaDrill( parseBoardUnits( T_uvia_drill ) );
1858  break;
1859 
1860  case T_diff_pair_width:
1861  nc->SetDiffPairWidth( parseBoardUnits( T_diff_pair_width ) );
1862  break;
1863 
1864  case T_diff_pair_gap:
1865  nc->SetDiffPairGap( parseBoardUnits( T_diff_pair_gap ) );
1866  break;
1867 
1868  case T_add_net:
1869  NeedSYMBOLorNUMBER();
1870  nc->Add( FromUTF8() );
1871  break;
1872 
1873  default:
1874  Expecting( "clearance, trace_width, via_dia, via_drill, uvia_dia, uvia_drill, diff_pair_width, diff_pair_gap or add_net" );
1875  }
1876 
1877  NeedRIGHT();
1878  }
1879 
1880  if( !m_board->GetDesignSettings().m_NetClasses.Add( nc ) )
1881  {
1882  // Must have been a name conflict, this is a bad board file.
1883  // User may have done a hand edit to the file.
1884 
1885  // unique_ptr will delete nc on this code path
1886 
1887  wxString error;
1888  error.Printf( _( "Duplicate NETCLASS name \"%s\" in file \"%s\" at line %d, offset %d" ),
1889  nc->GetName().GetData(), CurSource().GetData(), CurLineNumber(), CurOffset() );
1890  THROW_IO_ERROR( error );
1891  }
1892 }
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:512
int parseBoardUnits()
Definition: pcb_parser.h:255
#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
#define _(s)
Definition: 3d_actions.cpp:33
BOARD * m_board
Definition: pcb_parser.h:74

References _, and THROW_IO_ERROR.

◆ parseNETINFO_ITEM()

void PCB_PARSER::parseNETINFO_ITEM ( )
private

Definition at line 1786 of file pcb_parser.cpp.

1787 {
1788  wxCHECK_RET( CurTok() == T_net,
1789  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as net." ) );
1790 
1791  int netCode = parseInt( "net number" );
1792 
1793  NeedSYMBOLorNUMBER();
1794  wxString name = FromUTF8();
1795 
1796  NeedRIGHT();
1797 
1798  // net 0 should be already in list, so store this net
1799  // if it is not the net 0, or if the net 0 does not exists.
1800  // (TODO: a better test.)
1802  {
1803  NETINFO_ITEM* net = new NETINFO_ITEM( m_board, name, netCode );
1804  m_board->Add( net );
1805 
1806  // Store the new code mapping
1807  pushValueIntoMap( netCode, net->GetNet() );
1808  }
1809 }
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_MODE::INSERT) override
Adds an item to the container.
NETINFO_ITEM handles the data for a net.
Definition: netinfo.h:65
const char * name
Definition: DXF_plotter.cpp:60
int GetNet() const
Function GetNet.
Definition: netinfo.h:224
BOARD * m_board
Definition: pcb_parser.h:74
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:137
int parseInt()
Definition: pcb_parser.h:293
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
Definition: netinfo.h:462

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

◆ parsePAGE_INFO()

void PCB_PARSER::parsePAGE_INFO ( )
private

Definition at line 777 of file pcb_parser.cpp.

778 {
779  wxCHECK_RET( CurTok() == T_page,
780  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a PAGE_INFO." ) );
781 
782  T token;
783  PAGE_INFO pageInfo;
784 
785  NeedSYMBOL();
786 
787  wxString pageType = FromUTF8();
788 
789  if( !pageInfo.SetType( pageType ) )
790  {
791  wxString err;
792  err.Printf( _( "Page type \"%s\" is not valid " ), GetChars( FromUTF8() ) );
793  THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
794  }
795 
796  if( pageType == PAGE_INFO::Custom )
797  {
798  double width = parseDouble( "width" ); // width in mm
799 
800  // Perform some controls to avoid crashes if the size is edited by hands
801  if( width < 100.0 )
802  width = 100.0;
803  else if( width > 1200.0 )
804  width = 1200.0;
805 
806  double height = parseDouble( "height" ); // height in mm
807 
808  if( height < 100.0 )
809  height = 100.0;
810  else if( height > 1200.0 )
811  height = 1200.0;
812 
813  pageInfo.SetWidthMils( Mm2mils( width ) );
814  pageInfo.SetHeightMils( Mm2mils( height ) );
815  }
816 
817  token = NextTok();
818 
819  if( token == T_portrait )
820  {
821  pageInfo.SetPortrait( true );
822  NeedRIGHT();
823  }
824  else if( token != T_RIGHT )
825  {
826  Expecting( "portrait|)" );
827  }
828 
829  m_board->SetPageSettings( pageInfo );
830 }
int Mm2mils(double x)
Convert mm to mils.
Definition: base_units.h:52
void SetPageSettings(const PAGE_INFO &aPageSettings)
Definition: class_board.h:528
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
PAGE_INFO describes the page size and margins of a paper page on which to eventually print or plot.
Definition: page_info.h:54
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
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:101
#define _(s)
Definition: 3d_actions.cpp:33
BOARD * m_board
Definition: pcb_parser.h:74
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:149
void SetPortrait(bool aIsPortrait)
Function SetPortrait will rotate the paper page 90 degrees.
Definition: page_info.cpp:182

References _, PAGE_INFO::Custom, 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 4054 of file pcb_parser.cpp.

4055 {
4056  wxCHECK_MSG( CurTok() == T_target, NULL,
4057  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as PCB_TARGET." ) );
4058 
4059  wxPoint pt;
4060  T token;
4061 
4062  std::unique_ptr< PCB_TARGET > target( new PCB_TARGET( NULL ) );
4063 
4064  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4065  {
4066  if( token == T_LEFT )
4067  token = NextTok();
4068 
4069  switch( token )
4070  {
4071  case T_x:
4072  target->SetShape( 1 );
4073  break;
4074 
4075  case T_plus:
4076  target->SetShape( 0 );
4077  break;
4078 
4079  case T_at:
4080  pt.x = parseBoardUnits( "target x position" );
4081  pt.y = parseBoardUnits( "target y position" );
4082  target->SetPosition( pt );
4083  NeedRIGHT();
4084  break;
4085 
4086  case T_size:
4087  target->SetSize( parseBoardUnits( "target size" ) );
4088  NeedRIGHT();
4089  break;
4090 
4091  case T_width:
4092  target->SetWidth( parseBoardUnits( "target thickness" ) );
4093  NeedRIGHT();
4094  break;
4095 
4096  case T_layer:
4097  target->SetLayer( parseBoardItemLayer() );
4098  NeedRIGHT();
4099  break;
4100 
4101  case T_tstamp:
4102  NextTok();
4103  const_cast<KIID&>( target->m_Uuid ) = KIID( CurStr() );
4104  NeedRIGHT();
4105  break;
4106 
4107  default:
4108  Expecting( "x, plus, at, size, width, layer or tstamp" );
4109  }
4110  }
4111 
4112  return target.release();
4113 }
int parseBoardUnits()
Definition: pcb_parser.h:255
Definition: common.h:65
#define NULL
PCB_LAYER_ID parseBoardItemLayer()
Function parseBoardItemLayer parses the layer definition of a BOARD_ITEM object.

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

◆ parseSetup()

void PCB_PARSER::parseSetup ( )
private

Definition at line 1412 of file pcb_parser.cpp.

1413 {
1414  wxCHECK_RET( CurTok() == T_setup,
1415  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as setup." ) );
1416 
1417  T token;
1418  NETCLASSPTR defaultNetClass = m_board->GetDesignSettings().GetDefault();
1419  BOARD_DESIGN_SETTINGS& designSettings = m_board->GetDesignSettings();
1420  ZONE_SETTINGS zoneSettings = m_board->GetZoneSettings();
1421 
1422  // Missing soldermask min width value means that the user has set the value to 0 and
1423  // not the default value (0.25mm)
1424  designSettings.m_SolderMaskMinWidth = 0;
1425 
1426  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1427  {
1428  if( token != T_LEFT )
1429  Expecting( T_LEFT );
1430 
1431  token = NextTok();
1432 
1433  switch( token )
1434  {
1435  case T_stackup:
1437  break;
1438 
1439  case T_last_trace_width: // not used now
1440  /* lastTraceWidth =*/ parseBoardUnits( T_last_trace_width );
1441  NeedRIGHT();
1442  break;
1443 
1444  case T_user_trace_width:
1445  designSettings.m_TrackWidthList.push_back( parseBoardUnits( T_user_trace_width ) );
1446  NeedRIGHT();
1447  break;
1448 
1449  case T_trace_clearance:
1450  defaultNetClass->SetClearance( parseBoardUnits( T_trace_clearance ) );
1451  NeedRIGHT();
1452  break;
1453 
1454  case T_zone_clearance:
1455  zoneSettings.m_ZoneClearance = parseBoardUnits( T_zone_clearance );
1456  NeedRIGHT();
1457  break;
1458 
1459  case T_zone_45_only:
1460  zoneSettings.m_Zone_45_Only = parseBool();
1461  NeedRIGHT();
1462  break;
1463 
1464  case T_trace_min:
1465  designSettings.m_TrackMinWidth = parseBoardUnits( T_trace_min );
1466  NeedRIGHT();
1467  break;
1468 
1469  case T_via_size:
1470  defaultNetClass->SetViaDiameter( parseBoardUnits( T_via_size ) );
1471  NeedRIGHT();
1472  break;
1473 
1474  case T_via_drill:
1475  defaultNetClass->SetViaDrill( parseBoardUnits( T_via_drill ) );
1476  NeedRIGHT();
1477  break;
1478 
1479  case T_via_min_size:
1480  designSettings.m_ViasMinSize = parseBoardUnits( T_via_min_size );
1481  NeedRIGHT();
1482  break;
1483 
1484  case T_via_min_drill:
1485  designSettings.m_ViasMinDrill = parseBoardUnits( T_via_min_drill );
1486  NeedRIGHT();
1487  break;
1488 
1489  case T_user_via:
1490  {
1491  int viaSize = parseBoardUnits( "user via size" );
1492  int viaDrill = parseBoardUnits( "user via drill" );
1493  designSettings.m_ViasDimensionsList.emplace_back( VIA_DIMENSION( viaSize, viaDrill ) );
1494  NeedRIGHT();
1495  }
1496  break;
1497 
1498  case T_uvia_size:
1499  defaultNetClass->SetuViaDiameter( parseBoardUnits( T_uvia_size ) );
1500  NeedRIGHT();
1501  break;
1502 
1503  case T_uvia_drill:
1504  defaultNetClass->SetuViaDrill( parseBoardUnits( T_uvia_drill ) );
1505  NeedRIGHT();
1506  break;
1507 
1508  case T_uvias_allowed:
1509  designSettings.m_MicroViasAllowed = parseBool();
1510  NeedRIGHT();
1511  break;
1512 
1513  case T_blind_buried_vias_allowed:
1514  designSettings.m_BlindBuriedViaAllowed = parseBool();
1515  NeedRIGHT();
1516  break;
1517 
1518  case T_uvia_min_size:
1519  designSettings.m_MicroViasMinSize = parseBoardUnits( T_uvia_min_size );
1520  NeedRIGHT();
1521  break;
1522 
1523  case T_uvia_min_drill:
1524  designSettings.m_MicroViasMinDrill = parseBoardUnits( T_uvia_min_drill );
1525  NeedRIGHT();
1526  break;
1527 
1528  case T_user_diff_pair:
1529  {
1530  int width = parseBoardUnits( "user diff-pair width" );
1531  int gap = parseBoardUnits( "user diff-pair gap" );
1532  int viaGap = parseBoardUnits( "user diff-pair via gap" );
1533  designSettings.m_DiffPairDimensionsList.emplace_back( DIFF_PAIR_DIMENSION( width, gap, viaGap ) );
1534  NeedRIGHT();
1535  }
1536  break;
1537 
1538  case T_segment_width: // note: legacy (pre-6.0) token
1539  designSettings.m_LineThickness[ LAYER_CLASS_COPPER ] = parseBoardUnits( T_segment_width );
1540  NeedRIGHT();
1541  break;
1542 
1543  case T_edge_width: // note: legacy (pre-6.0) token
1544  designSettings.m_LineThickness[ LAYER_CLASS_EDGES ] = parseBoardUnits( T_edge_width );
1545  NeedRIGHT();
1546  break;
1547 
1548  case T_mod_edge_width: // note: legacy (pre-6.0) token
1549  designSettings.m_LineThickness[ LAYER_CLASS_SILK ] = parseBoardUnits( T_mod_edge_width );
1550  NeedRIGHT();
1551  break;
1552 
1553  case T_pcb_text_width: // note: legacy (pre-6.0) token
1554  designSettings.m_TextThickness[ LAYER_CLASS_COPPER ] = parseBoardUnits( T_pcb_text_width );
1555  NeedRIGHT();
1556  break;
1557 
1558  case T_mod_text_width: // note: legacy (pre-6.0) token
1559  designSettings.m_TextThickness[ LAYER_CLASS_SILK ] = parseBoardUnits( T_mod_text_width );
1560  NeedRIGHT();
1561  break;
1562 
1563  case T_pcb_text_size: // note: legacy (pre-6.0) token
1564  designSettings.m_TextSize[ LAYER_CLASS_COPPER ].x = parseBoardUnits( "pcb text width" );
1565  designSettings.m_TextSize[ LAYER_CLASS_COPPER ].y = parseBoardUnits( "pcb text height" );
1566  NeedRIGHT();
1567  break;
1568 
1569  case T_mod_text_size: // note: legacy (pre-6.0) token
1570  designSettings.m_TextSize[ LAYER_CLASS_SILK ].x = parseBoardUnits( "module text width" );
1571  designSettings.m_TextSize[ LAYER_CLASS_SILK ].y = parseBoardUnits( "module text height" );
1572  NeedRIGHT();
1573  break;
1574 
1575  case T_defaults:
1576  parseDefaults( designSettings );
1577  break;
1578 
1579  case T_pad_size:
1580  {
1581  wxSize sz;
1582  sz.SetWidth( parseBoardUnits( "master pad width" ) );
1583  sz.SetHeight( parseBoardUnits( "master pad height" ) );
1584  designSettings.m_Pad_Master.SetSize( sz );
1585  NeedRIGHT();
1586  }
1587  break;
1588 
1589  case T_pad_drill:
1590  {
1591  int drillSize = parseBoardUnits( T_pad_drill );
1592  designSettings.m_Pad_Master.SetDrillSize( wxSize( drillSize, drillSize ) );
1593  NeedRIGHT();
1594  }
1595  break;
1596 
1597  case T_pad_to_mask_clearance:
1598  designSettings.m_SolderMaskMargin = parseBoardUnits( T_pad_to_mask_clearance );
1599  NeedRIGHT();
1600  break;
1601 
1602  case T_solder_mask_min_width:
1603  designSettings.m_SolderMaskMinWidth = parseBoardUnits( T_solder_mask_min_width );
1604  NeedRIGHT();
1605  break;
1606 
1607  case T_pad_to_paste_clearance:
1608  designSettings.m_SolderPasteMargin = parseBoardUnits( T_pad_to_paste_clearance );
1609  NeedRIGHT();
1610  break;
1611 
1612  case T_pad_to_paste_clearance_ratio:
1613  designSettings.m_SolderPasteMarginRatio = parseDouble( T_pad_to_paste_clearance_ratio );
1614  NeedRIGHT();
1615  break;
1616 
1617  case T_aux_axis_origin:
1618  {
1619  int x = parseBoardUnits( "auxiliary origin X" );
1620  int y = parseBoardUnits( "auxiliary origin Y" );
1621  // m_board->SetAuxOrigin( wxPoint( x, y ) ); gets overwritten via SetDesignSettings below
1622  designSettings.m_AuxOrigin = wxPoint( x, y );
1623  NeedRIGHT();
1624  }
1625  break;
1626 
1627  case T_grid_origin:
1628  {
1629  int x = parseBoardUnits( "grid origin X" );
1630  int y = parseBoardUnits( "grid origin Y" );
1631  // m_board->SetGridOrigin( wxPoint( x, y ) ); gets overwritten SetDesignSettings below
1632  designSettings.m_GridOrigin = wxPoint( x, y );
1633  NeedRIGHT();
1634  }
1635  break;
1636 
1637  case T_visible_elements:
1638  designSettings.SetVisibleElements( parseHex() | MIN_VISIBILITY_MASK );
1639  NeedRIGHT();
1640  break;
1641 
1642  case T_max_error:
1643  designSettings.m_MaxError = parseBoardUnits( T_max_error );
1644  NeedRIGHT();
1645  break;
1646 
1647  case T_filled_areas_thickness:
1648  designSettings.m_ZoneUseNoOutlineInFill = not parseBool();
1649  NeedRIGHT();
1650  break;
1651 
1652  case T_pcbplotparams:
1653  {
1654  PCB_PLOT_PARAMS plotParams;
1655  PCB_PLOT_PARAMS_PARSER parser( reader );
1656  // parser must share the same current line as our current PCB parser
1657  // synchronize it.
1658  parser.SyncLineReaderWith( *this );
1659 
1660  plotParams.Parse( &parser );
1661  SyncLineReaderWith( parser );
1662 
1663  m_board->SetPlotOptions( plotParams );
1664  }
1665  break;
1666 
1667  default:
1668  Unexpected( CurText() );
1669  }
1670  }
1671 
1672  //m_board->SetDesignSettings( designSettings );
1673  m_board->SetZoneSettings( zoneSettings );
1674 }
int m_SolderMaskMargin
Solder mask margin.
Struct VIA_DIMENSION is a small helper container to handle a stock of specific vias each with unique ...
wxPoint m_GridOrigin
origin for grid offsets
int m_SolderPasteMargin
Solder paste margin absolute value.
PCB_PLOT_PARAMS_PARSER is the parser class for PCB_PLOT_PARAMS.
std::vector< int > m_TrackWidthList
std::vector< DIFF_PAIR_DIMENSION > m_DiffPairDimensionsList
void parseBoardStackup()
Definition: pcb_parser.cpp:982
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:512
void SetDrillSize(const wxSize &aSize)
Definition: class_pad.h:305
Struct DIFF_PAIR_DIMENSION is a small helper container to handle a stock of specific differential pai...
int parseBoardUnits()
Definition: pcb_parser.h:255
wxSize m_TextSize[LAYER_CLASS_COUNT]
bool parseBool()
Definition: pcb_parser.cpp:179
int m_TextThickness[LAYER_CLASS_COUNT]
#define MIN_VISIBILITY_MASK
void SetSize(const wxSize &aSize)
Definition: class_pad.h:299
int m_ZoneClearance
Minimal clearance value.
Definition: zone_settings.h:74
bool m_BlindBuriedViaAllowed
true to allow blind/buried vias
void SetPlotOptions(const PCB_PLOT_PARAMS &aOptions)
Definition: class_board.h:531
PCB_PLOT_PARAMS handles plot parameters and options when plotting/printing a board.
int m_LineThickness[LAYER_CLASS_COUNT]
void SetZoneSettings(const ZONE_SETTINGS &aSettings)
Set the zone settings for this container.
void parseDefaults(BOARD_DESIGN_SETTINGS &aSettings)
ZONE_SETTINGS handles zones parameters.
Definition: zone_settings.h:58
const ZONE_SETTINGS & GetZoneSettings() const
Fetch the zone settings for this container.
NETCLASSPTR GetDefault() const
Function GetDefault.
bool m_ZoneUseNoOutlineInFill
Option to handle filled polygons in zones: the "legacy" option is using thick outlines around filled ...
BOARD * m_board
Definition: pcb_parser.h:74
D_PAD m_Pad_Master
A dummy pad to store all default parameters.
void SetVisibleElements(int aMask)
Function SetVisibleElements changes the bit-mask of visible element categories.
std::vector< VIA_DIMENSION > m_ViasDimensionsList
double parseDouble()
Function parseDouble parses the current token as an ASCII numeric string with possible leading whites...
Definition: pcb_parser.cpp:149
bool m_MicroViasAllowed
true to allow micro vias
long parseHex()
Definition: pcb_parser.h:304
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.
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_DiffPairDimensionsList, BOARD_DESIGN_SETTINGS::m_GridOrigin, BOARD_DESIGN_SETTINGS::m_LineThickness, BOARD_DESIGN_SETTINGS::m_MaxError, 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, BOARD_DESIGN_SETTINGS::m_ZoneUseNoOutlineInFill, 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 2596 of file pcb_parser.cpp.

2597 {
2598  wxCHECK_MSG( CurTok() == T_fp_text, NULL,
2599  wxString::Format( wxT( "Cannot parse %s as TEXTE_MODULE at line %d, offset %d." ),
2600  GetChars( GetTokenString( CurTok() ) ),
2601  CurLineNumber(), CurOffset() ) );
2602 
2603  T token = NextTok();
2604 
2605  std::unique_ptr<TEXTE_MODULE> text( new TEXTE_MODULE( NULL ) );
2606 
2607  switch( token )
2608  {
2609  case T_reference:
2610  text->SetType( TEXTE_MODULE::TEXT_is_REFERENCE );
2611  break;
2612 
2613  case T_value:
2614  text->SetType( TEXTE_MODULE::TEXT_is_VALUE );
2615  break;
2616 
2617  case T_user:
2618  break; // Default type is user text.
2619 
2620  default:
2621  THROW_IO_ERROR( wxString::Format( _( "Cannot handle footprint text type %s" ),
2622  GetChars( FromUTF8() ) ) );
2623  }
2624 
2625  NeedSYMBOLorNUMBER();
2626 
2627  text->SetText( FromUTF8() );
2628  NeedLEFT();
2629  token = NextTok();
2630 
2631  if( token != T_at )
2632  Expecting( T_at );
2633 
2634  wxPoint pt;
2635 
2636  pt.x = parseBoardUnits( "X coordinate" );
2637  pt.y = parseBoardUnits( "Y coordinate" );
2638  text->SetPos0( pt );
2639 
2640  NextTok();
2641 
2642  if( CurTok() == T_NUMBER )
2643  {
2644  text->SetTextAngle( parseDouble() * 10.0 );
2645  NextTok();
2646  }
2647 
2648  if( CurTok() == T_unlocked )
2649  {
2650  text->SetKeepUpright( false );
2651  NextTok();
2652  }
2653 
2654  if( CurTok() != T_RIGHT )
2655  {
2656  Unexpected( CurText() );
2657  }
2658 
2659  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2660  {
2661  if( token == T_LEFT )
2662  token = NextTok();
2663 
2664  switch( token )
2665  {
2666  case T_layer:
2667  text->SetLayer( parseBoardItemLayer() );
2668  NeedRIGHT();
2669  break;
2670 
2671  case T_hide:
2672  text->SetVisible( false );
2673  break;
2674 
2675  case T_effects:
2676  parseEDA_TEXT( (EDA_TEXT*) text.get() );
2677  break;
2678 
2679  default:
2680  Expecting( "hide or effects" );
2681  }
2682  }
2683 
2684  return text.release();
2685 }
void parseEDA_TEXT(EDA_TEXT *aText)
Function parseEDA_TEXT parses the common settings for any object derived from EDA_TEXT.
Definition: pcb_parser.cpp:263
int parseBoardUnits()
Definition: pcb_parser.h:255
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:109
#define NULL
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:101
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
#define _(s)
Definition: 3d_actions.cpp:33
double parseDouble()
Function parseDouble parses the current token as an ASCII numeric string with possible leading whites...
Definition: pcb_parser.cpp:149

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

◆ parseTEXTE_PCB()

TEXTE_PCB * PCB_PARSER::parseTEXTE_PCB ( )
private

Definition at line 2069 of file pcb_parser.cpp.

2070 {
2071  wxCHECK_MSG( CurTok() == T_gr_text, NULL,
2072  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as TEXTE_PCB." ) );
2073 
2074  T token;
2075 
2076  std::unique_ptr<TEXTE_PCB> text( new TEXTE_PCB( m_board ) );
2077  NeedSYMBOLorNUMBER();
2078 
2079  text->SetText( FromUTF8() );
2080  NeedLEFT();
2081  token = NextTok();
2082 
2083  if( token != T_at )
2084  Expecting( T_at );
2085 
2086  wxPoint pt;
2087 
2088  pt.x = parseBoardUnits( "X coordinate" );
2089  pt.y = parseBoardUnits( "Y coordinate" );
2090  text->SetTextPos( pt );
2091 
2092  // If there is no orientation defined, then it is the default value of 0 degrees.
2093  token = NextTok();
2094 
2095  if( token == T_NUMBER )
2096  {
2097  text->SetTextAngle( parseDouble() * 10.0 );
2098  NeedRIGHT();
2099  }
2100  else if( token != T_RIGHT )
2101  {
2102  Unexpected( CurText() );
2103  }
2104 
2105  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2106  {
2107  if( token != T_LEFT )
2108  Expecting( T_LEFT );
2109 
2110  token = NextTok();
2111 
2112  switch( token )
2113  {
2114  case T_layer:
2115  text->SetLayer( parseBoardItemLayer() );
2116  NeedRIGHT();
2117  break;
2118 
2119  case T_tstamp:
2120  NextTok();
2121  const_cast<KIID&>( text->m_Uuid ) = KIID( CurStr() );
2122  NeedRIGHT();
2123  break;
2124 
2125  case T_effects:
2126  parseEDA_TEXT( (EDA_TEXT*) text.get() );
2127  break;
2128 
2129  default:
2130  Expecting( "layer, tstamp or effects" );
2131  }
2132  }
2133 
2134  return text.release();
2135 }
void parseEDA_TEXT(EDA_TEXT *aText)
Function parseEDA_TEXT parses the common settings for any object derived from EDA_TEXT.
Definition: pcb_parser.cpp:263
int parseBoardUnits()
Definition: pcb_parser.h:255
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:109
Definition: common.h:65
#define NULL
PCB_LAYER_ID parseBoardItemLayer()
Function parseBoardItemLayer parses the layer definition of a BOARD_ITEM object.
BOARD * m_board
Definition: pcb_parser.h:74
double parseDouble()
Function parseDouble parses the current token as an ASCII numeric string with possible leading whites...
Definition: pcb_parser.cpp:149

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

◆ parseTITLE_BLOCK()

void PCB_PARSER::parseTITLE_BLOCK ( )
private

Definition at line 833 of file pcb_parser.cpp.

834 {
835  wxCHECK_RET( CurTok() == T_title_block,
836  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
837  wxT( " as TITLE_BLOCK." ) );
838 
839  T token;
840  TITLE_BLOCK titleBlock;
841 
842  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
843  {
844  if( token != T_LEFT )
845  Expecting( T_LEFT );
846 
847  token = NextTok();
848 
849  switch( token )
850  {
851  case T_title:
852  NextTok();
853  titleBlock.SetTitle( FromUTF8() );
854  break;
855 
856  case T_date:
857  NextTok();
858  titleBlock.SetDate( FromUTF8() );
859  break;
860 
861  case T_rev:
862  NextTok();
863  titleBlock.SetRevision( FromUTF8() );
864  break;
865 
866  case T_company:
867  NextTok();
868  titleBlock.SetCompany( FromUTF8() );
869  break;
870 
871  case T_comment:
872  {
873  int commentNumber = parseInt( "comment" );
874 
875  switch( commentNumber )
876  {
877  case 1:
878  NextTok();
879  titleBlock.SetComment( 0, FromUTF8() );
880  break;
881 
882  case 2:
883  NextTok();
884  titleBlock.SetComment( 1, FromUTF8() );
885  break;
886 
887  case 3:
888  NextTok();
889  titleBlock.SetComment( 2, FromUTF8() );
890  break;
891 
892  case 4:
893  NextTok();
894  titleBlock.SetComment( 3, FromUTF8() );
895  break;
896 
897  case 5:
898  NextTok();
899  titleBlock.SetComment( 4, FromUTF8() );
900  break;
901 
902  case 6:
903  NextTok();
904  titleBlock.SetComment( 5, FromUTF8() );
905  break;
906 
907  case 7:
908  NextTok();
909  titleBlock.SetComment( 6, FromUTF8() );
910  break;
911 
912  case 8:
913  NextTok();
914  titleBlock.SetComment( 7, FromUTF8() );
915  break;
916 
917  case 9:
918  NextTok();
919  titleBlock.SetComment( 8, FromUTF8() );
920  break;
921 
922  default:
923  wxString err;
924  err.Printf( wxT( "%d is not a valid title block comment number" ), commentNumber );
925  THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
926  }
927  }
928  break;
929 
930  default:
931  Expecting( "title, date, rev, company, or comment" );
932  }
933 
934  NeedRIGHT();
935  }
936 
937  m_board->SetTitleBlock( titleBlock );
938 }
void SetRevision(const wxString &aRevision)
Definition: title_block.h:84
void SetTitleBlock(const TITLE_BLOCK &aTitleBlock)
Definition: class_board.h:534
void SetDate(const wxString &aDate)
Function SetDate sets the date field, and defaults to the current time and date.
Definition: title_block.h:74
TITLE_BLOCK holds the information shown in the lower right corner of a plot, printout,...
Definition: title_block.h:40
void SetComment(int aIdx, const wxString &aComment)
Definition: title_block.h:104
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
BOARD * m_board
Definition: pcb_parser.h:74
int parseInt()
Definition: pcb_parser.h:293

References parseInt(), TITLE_BLOCK::SetComment(), 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 3453 of file pcb_parser.cpp.

3454 {
3455  wxCHECK_MSG( CurTok() == T_segment, NULL,
3456  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as TRACK." ) );
3457 
3458  wxPoint pt;
3459  T token;
3460 
3461  std::unique_ptr< TRACK > track( new TRACK( m_board ) );
3462 
3463  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3464  {
3465  if( token != T_LEFT )
3466  Expecting( T_LEFT );
3467 
3468  token = NextTok();
3469 
3470  switch( token )
3471  {
3472  case T_start:
3473  pt.x = parseBoardUnits( "start x" );
3474  pt.y = parseBoardUnits( "start y" );
3475  track->SetStart( pt );
3476  break;
3477 
3478  case T_end:
3479  pt.x = parseBoardUnits( "end x" );
3480  pt.y = parseBoardUnits( "end y" );
3481  track->SetEnd( pt );
3482  break;
3483 
3484  case T_width:
3485  track->SetWidth( parseBoardUnits( "width" ) );
3486  break;
3487 
3488  case T_layer:
3489  track->SetLayer( parseBoardItemLayer() );
3490  break;
3491 
3492  case T_net:
3493  if( ! track->SetNetCode( getNetCode( parseInt( "net number" ) ), /* aNoAssert */ true ) )
3495  wxString::Format( _( "Invalid net ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),
3496  GetChars( CurSource() ), CurLineNumber(), CurOffset() )
3497  );
3498  break;
3499 
3500  case T_tstamp:
3501  NextTok();
3502  const_cast<KIID&>( track->m_Uuid ) = KIID( CurStr() );
3503  break;
3504 
3505  case T_status:
3506  track->SetStatus( static_cast<STATUS_FLAGS>( parseHex() ) );
3507  break;
3508 
3509  default:
3510  Expecting( "start, end, width, layer, net, tstamp, or status" );
3511  }
3512 
3513  NeedRIGHT();
3514  }
3515 
3516  return track.release();
3517 }
int parseBoardUnits()
Definition: pcb_parser.h:255
Definition: common.h:65
#define NULL
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:101
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
#define _(s)
Definition: 3d_actions.cpp:33
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:86
BOARD * m_board
Definition: pcb_parser.h:74
long parseHex()
Definition: pcb_parser.h:304
int parseInt()
Definition: pcb_parser.h:293

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

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

195 {
196  if( NextTok() != T_version )
197  Expecting( GetTokenText( T_version ) );
198 
199  int pcb_version = parseInt( FromUTF8().mb_str( wxConvUTF8 ) );
200 
201  NeedRIGHT();
202 
203  return pcb_version;
204 }
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:293

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

◆ parseVIA()

VIA * PCB_PARSER::parseVIA ( )
private

Definition at line 3520 of file pcb_parser.cpp.

3521 {
3522  wxCHECK_MSG( CurTok() == T_via, NULL,
3523  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as VIA." ) );
3524 
3525  wxPoint pt;
3526  T token;
3527 
3528  std::unique_ptr< VIA > via( new VIA( m_board ) );
3529 
3530  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3531  {
3532  if( token == T_LEFT )
3533  token = NextTok();
3534 
3535  switch( token )
3536  {
3537  case T_blind:
3538  via->SetViaType( VIATYPE::BLIND_BURIED );
3539  break;
3540 
3541  case T_micro:
3542  via->SetViaType( VIATYPE::MICROVIA );
3543  break;
3544 
3545  case T_at:
3546  pt.x = parseBoardUnits( "start x" );
3547  pt.y = parseBoardUnits( "start y" );
3548  via->SetStart( pt );
3549  via->SetEnd( pt );
3550  NeedRIGHT();
3551  break;
3552 
3553  case T_size:
3554  via->SetWidth( parseBoardUnits( "via width" ) );
3555  NeedRIGHT();
3556  break;
3557 
3558  case T_drill:
3559  via->SetDrill( parseBoardUnits( "drill diameter" ) );
3560  NeedRIGHT();
3561  break;
3562 
3563  case T_layers:
3564  {
3565  PCB_LAYER_ID layer1, layer2;
3566  NextTok();
3567  layer1 = lookUpLayer<PCB_LAYER_ID>( m_layerIndices );
3568  NextTok();
3569  layer2 = lookUpLayer<PCB_LAYER_ID>( m_layerIndices );
3570  via->SetLayerPair( layer1, layer2 );
3571  NeedRIGHT();
3572  }
3573  break;
3574 
3575  case T_net:
3576  if(! via->SetNetCode( getNetCode( parseInt( "net number" ) ), /* aNoAssert */ true))
3578  wxString::Format( _( "Invalid net ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),
3579  GetChars( CurSource() ), CurLineNumber(), CurOffset() )
3580  );
3581  NeedRIGHT();
3582  break;
3583 
3584  case T_tstamp:
3585  NextTok();
3586  const_cast<KIID&>( via->m_Uuid ) = KIID( CurStr() );
3587  NeedRIGHT();
3588  break;
3589 
3590  case T_status:
3591  via->SetStatus( static_cast<STATUS_FLAGS>( parseHex() ) );
3592  NeedRIGHT();
3593  break;
3594 
3595  default:
3596  Expecting( "blind, micro, at, size, drill, layers, net, tstamp, or status" );
3597  }
3598  }
3599 
3600  return via.release();
3601 }
int parseBoardUnits()
Definition: pcb_parser.h:255
Definition: common.h:65
PCB_LAYER_ID
A quick note on layer IDs:
#define NULL
#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:101
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
#define _(s)
Definition: 3d_actions.cpp:33
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:86
BOARD * m_board
Definition: pcb_parser.h:74
LAYER_ID_MAP m_layerIndices
map layer name to it's index
Definition: pcb_parser.h:75
long parseHex()
Definition: pcb_parser.h:304
int parseInt()
Definition: pcb_parser.h:293

References _, BLIND_BURIED, Format(), GetChars(), MICROVIA, NULL, parseHex(), parseInt(), THROW_IO_ERROR, VIA, wxPoint::x, and wxPoint::y.

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

232 {
233  if( CurTok() != T_LEFT )
234  NeedLEFT();
235 
236  wxPoint pt;
237  T token = NextTok();
238 
239  if( token != T_xy )
240  Expecting( T_xy );
241 
242  pt.x = parseBoardUnits( "X coordinate" );
243  pt.y = parseBoardUnits( "Y coordinate" );
244 
245  NeedRIGHT();
246 
247  return pt;
248 }
int parseBoardUnits()
Definition: pcb_parser.h:255

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

◆ parseXY() [2/2]

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

Definition at line 251 of file pcb_parser.cpp.

252 {
253  wxPoint pt = parseXY();
254 
255  if( aX )
256  *aX = pt.x;
257 
258  if( aY )
259  *aY = pt.y;
260 }
wxPoint parseXY()
Function parseXY parses a coordinate pair (xy X Y) in board units (mm).
Definition: pcb_parser.cpp:231

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

◆ parseZONE_CONTAINER()

ZONE_CONTAINER * PCB_PARSER::parseZONE_CONTAINER ( BOARD_ITEM_CONTAINER aParent)
private

Definition at line 3604 of file pcb_parser.cpp.

3605 {
3606  wxCHECK_MSG( CurTok() == T_zone, NULL,
3607  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
3608  wxT( " as ZONE_CONTAINER." ) );
3609 
3611 
3612  int hatchPitch = ZONE_CONTAINER::GetDefaultHatchPitch();
3613  wxPoint pt;
3614  T token;
3615  int tmp;
3616  wxString netnameFromfile; // the zone net name find in file
3617 
3618  // bigger scope since each filled_polygon is concatenated in here
3619  SHAPE_POLY_SET pts;
3620  bool inModule = false;
3621 
3622  if( dynamic_cast<MODULE*>( aParent ) ) // The zone belongs a footprint
3623  inModule = true;
3624 
3625  std::unique_ptr<ZONE_CONTAINER> zone( inModule ?
3626  new MODULE_ZONE_CONTAINER( aParent ) :
3627  new ZONE_CONTAINER( aParent ) );
3628 
3629  zone->SetPriority( 0 );
3630 
3631  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3632  {
3633  if( token == T_LEFT )
3634  token = NextTok();
3635 
3636  switch( token )
3637  {
3638  case T_net:
3639  // Init the net code only, not the netname, to be sure
3640  // the zone net name is the name read in file.
3641  // (When mismatch, the user will be prompted in DRC, to fix the actual name)
3642  tmp = getNetCode( parseInt( "net number" ) );
3643 
3644  if( tmp < 0 )
3645  tmp = 0;
3646 
3647  if( ! zone->SetNetCode( tmp, /* aNoAssert */ true ) )
3649  wxString::Format( _( "Invalid net ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),
3650  GetChars( CurSource() ), CurLineNumber(), CurOffset() )
3651  );
3652 
3653  NeedRIGHT();
3654  break;
3655 
3656  case T_net_name:
3657  NeedSYMBOLorNUMBER();
3658  netnameFromfile = FromUTF8();
3659  NeedRIGHT();
3660  break;
3661 
3662  case T_layer: // keyword for zones that are on only one layer
3663  zone->SetLayer( parseBoardItemLayer() );
3664  NeedRIGHT();
3665  break;
3666 
3667  case T_layers: // keyword for zones that can live on a set of layer
3668  // currently: keepout zones
3669  zone->SetLayerSet( parseBoardItemLayersAsMask() );
3670  break;
3671 
3672  case T_tstamp:
3673  NextTok();
3674  const_cast<KIID&>( zone->m_Uuid ) = KIID( CurStr() );
3675  NeedRIGHT();
3676  break;
3677 
3678  case T_hatch:
3679  token = NextTok();
3680 
3681  if( token != T_none && token != T_edge && token != T_full )
3682  Expecting( "none, edge, or full" );
3683 
3684  switch( token )
3685  {
3686  default:
3687  case T_none:
3688  hatchStyle = ZONE_HATCH_STYLE::NO_HATCH;
3689  break;
3690  case T_edge:
3691  hatchStyle = ZONE_HATCH_STYLE::DIAGONAL_EDGE;
3692  break;
3693  case T_full:
3694  hatchStyle = ZONE_HATCH_STYLE::DIAGONAL_FULL;
3695  }
3696 
3697  hatchPitch = parseBoardUnits( "hatch pitch" );
3698  NeedRIGHT();
3699  break;
3700 
3701  case T_priority:
3702  zone->SetPriority( parseInt( "zone priority" ) );
3703  NeedRIGHT();
3704  break;
3705 
3706  case T_connect_pads:
3707  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3708  {
3709  if( token == T_LEFT )
3710  token = NextTok();
3711 
3712  switch( token )
3713  {
3714  case T_yes:
3715  zone->SetPadConnection( ZONE_CONNECTION::FULL );
3716  break;
3717 
3718  case T_no:
3719  zone->SetPadConnection( ZONE_CONNECTION::NONE );
3720  break;
3721 
3722  case T_thru_hole_only:
3723  zone->SetPadConnection( ZONE_CONNECTION::THT_THERMAL );
3724  break;
3725 
3726  case T_clearance:
3727  zone->SetZoneClearance( parseBoardUnits( "zone clearance" ) );
3728  NeedRIGHT();
3729  break;
3730 
3731  default:
3732  Expecting( "yes, no, or clearance" );
3733  }
3734  }
3735 
3736  break;
3737 
3738  case T_min_thickness:
3739  zone->SetMinThickness( parseBoardUnits( T_min_thickness ) );
3740  NeedRIGHT();
3741  break;
3742 
3743  case T_filled_areas_thickness:
3744  zone->SetFilledPolysUseThickness( parseBool() );
3745  NeedRIGHT();
3746  break;
3747 
3748  case T_fill:
3749  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3750  {
3751  if( token == T_LEFT )
3752  token = NextTok();
3753 
3754  switch( token )
3755  {
3756  case T_yes:
3757  zone->SetIsFilled( true );
3758  break;
3759 
3760  case T_mode:
3761  token = NextTok();
3762 
3763  if( token != T_segment && token != T_hatch && token != T_polygon )
3764  Expecting( "segment, hatch or polygon" );
3765 
3766  if( token == T_segment ) // deprecated
3767  {
3768  // SEGMENT fill mode no longer supported. Make sure user is OK with converting them.
3770  {
3771  KIDIALOG dlg( nullptr,
3772  _( "The legacy segment fill mode is no longer supported.\n"
3773  "Convert zones to polygon fills?"),
3774  _( "Legacy Zone Warning" ),
3775  wxYES_NO | wxICON_WARNING );
3776 
3777  dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
3778 
3779  if( dlg.ShowModal() == wxID_NO )
3780  THROW_IO_ERROR( wxT( "CANCEL" ) );
3781 
3782  m_showLegacyZoneWarning = false;
3783  }
3784 
3785  zone->SetFillMode( ZONE_FILL_MODE::POLYGONS );
3786  m_board->SetModified();
3787  }
3788  else if( token == T_hatch )
3789  zone->SetFillMode( ZONE_FILL_MODE::HATCH_PATTERN );
3790  else
3791  zone->SetFillMode( ZONE_FILL_MODE::POLYGONS );
3792  NeedRIGHT();
3793  break;
3794 
3795  case T_hatch_thickness:
3796  zone->SetHatchFillTypeThickness( parseBoardUnits( T_hatch_thickness ) );
3797  NeedRIGHT();
3798  break;
3799 
3800  case T_hatch_gap:
3801  zone->SetHatchFillTypeGap( parseBoardUnits( T_hatch_gap ) );
3802  NeedRIGHT();
3803  break;
3804 
3805  case T_hatch_orientation:
3806  zone->SetHatchFillTypeOrientation( parseDouble( T_hatch_orientation ) );
3807  NeedRIGHT();
3808  break;
3809 
3810  case T_hatch_smoothing_level:
3811  zone->SetHatchFillTypeSmoothingLevel( parseDouble( T_hatch_smoothing_level ) );
3812  NeedRIGHT();
3813  break;
3814 
3815  case T_hatch_smoothing_value:
3816  zone->SetHatchFillTypeSmoothingValue( parseDouble( T_hatch_smoothing_value ) );
3817  NeedRIGHT();
3818  break;
3819 
3820  case T_arc_segments:
3821  static_cast<void>( parseInt( "arc segment count" ) );
3822  NeedRIGHT();
3823  break;
3824 
3825  case T_thermal_gap:
3826  zone->SetThermalReliefGap( parseBoardUnits( T_thermal_gap ) );
3827  NeedRIGHT();
3828  break;
3829 
3830  case T_thermal_bridge_width:
3831  zone->SetThermalReliefCopperBridge( parseBoardUnits( T_thermal_bridge_width ) );
3832  NeedRIGHT();
3833  break;
3834 
3835  case T_smoothing:
3836  switch( NextTok() )
3837  {
3838  case T_none:
3839  zone->SetCornerSmoothingType( ZONE_SETTINGS::SMOOTHING_NONE );
3840  break;
3841 
3842  case T_chamfer:
3843  if( !zone->GetIsKeepout() ) // smoothing has meaning only for filled zones
3844  zone->SetCornerSmoothingType( ZONE_SETTINGS::SMOOTHING_CHAMFER );
3845  break;
3846 
3847  case T_fillet:
3848  if( !zone->GetIsKeepout() ) // smoothing has meaning only for filled zones
3849  zone->SetCornerSmoothingType( ZONE_SETTINGS::SMOOTHING_FILLET );
3850  break;
3851 
3852  default:
3853  Expecting( "none, chamfer, or fillet" );
3854  }
3855  NeedRIGHT();
3856  break;
3857 
3858  case T_radius:
3859  tmp = parseBoardUnits( "corner radius" );
3860  if( !zone->GetIsKeepout() ) // smoothing has meaning only for filled zones
3861  zone->SetCornerRadius( tmp );
3862  NeedRIGHT();
3863  break;
3864 
3865  default:
3866  Expecting( "mode, arc_segments, thermal_gap, thermal_bridge_width, "
3867  "hatch_thickness, hatch_gap, hatch_orientation, "
3868  "hatch_smoothing_level, hatch_smoothing_value, smoothing, or radius" );
3869  }
3870  }
3871  break;
3872 
3873  case T_keepout:
3874  zone->SetIsKeepout( true );
3875 
3876  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3877  {
3878  if( token == T_LEFT )
3879  token = NextTok();
3880 
3881  switch( token )
3882  {
3883  case T_tracks:
3884  token = NextTok();
3885 
3886  if( token != T_allowed && token != T_not_allowed )
3887  Expecting( "allowed or not_allowed" );
3888  zone->SetDoNotAllowTracks( token == T_not_allowed );
3889  break;
3890 
3891  case T_vias:
3892  token = NextTok();
3893 
3894  if( token != T_allowed && token != T_not_allowed )
3895  Expecting( "allowed or not_allowed" );
3896  zone->SetDoNotAllowVias( token == T_not_allowed );
3897  break;
3898 
3899  case T_copperpour:
3900  token = NextTok();
3901 
3902  if( token != T_allowed && token != T_not_allowed )
3903  Expecting( "allowed or not_allowed" );
3904  zone->SetDoNotAllowCopperPour( token == T_not_allowed );
3905  break;
3906 
3907  default:
3908  Expecting( "tracks, vias or copperpour" );
3909  }
3910 
3911  NeedRIGHT();
3912  }
3913 
3914  break;
3915 
3916  case T_polygon:
3917  {
3918  std::vector< wxPoint > corners;
3919 
3920  NeedLEFT();
3921  token = NextTok();
3922 
3923  if( token != T_pts )
3924  Expecting( T_pts );
3925 
3926  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3927  {
3928  corners.push_back( parseXY() );
3929  }
3930 
3931  NeedRIGHT();
3932 
3933  // Remark: The first polygon is the main outline.
3934  // Others are holes inside the main outline.
3935  zone->AddPolygon( corners );
3936  }
3937  break;
3938 
3939  case T_filled_polygon:
3940  {
3941  // "(filled_polygon (pts"
3942  NeedLEFT();
3943  token = NextTok();
3944 
3945  if( token != T_pts )
3946  Expecting( T_pts );
3947 
3948  pts.NewOutline();
3949 
3950  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3951  {
3952  pts.Append( parseXY() );
3953  }
3954 
3955  NeedRIGHT();
3956  }
3957  break;
3958 
3959  case T_fill_segments:
3960  {
3961  ZONE_SEGMENT_FILL segs;
3962 
3963  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3964  {
3965  if( token != T_LEFT )
3966  Expecting( T_LEFT );
3967 
3968  token = NextTok();
3969 
3970  if( token != T_pts )
3971  Expecting( T_pts );
3972 
3973  SEG segment( parseXY(), parseXY() );
3974  NeedRIGHT();
3975  segs.push_back( segment );
3976  }
3977 
3978  zone->SetFillSegments( segs );
3979  }
3980  break;
3981 
3982  default:
3983  Expecting( "net, layer/layers, tstamp, hatch, priority, connect_pads, min_thickness, "
3984  "fill, polygon, filled_polygon, or fill_segments" );
3985  }
3986  }
3987 
3988  if( zone->GetNumCorners() > 2 )
3989  {
3990  if( !zone->IsOnCopperLayer() )
3991  {
3992  //zone->SetFillMode( ZONE_FILL_MODE::POLYGONS );
3993  zone->SetNetCode( NETINFO_LIST::UNCONNECTED );
3994  }
3995 
3996  // Set hatch here, after outlines corners are read
3997  zone->SetHatch( hatchStyle, hatchPitch, true );
3998  }
3999 
4000  if( !pts.IsEmpty() )
4001  {
4002  zone->SetFilledPolysList( pts );
4003  zone->CalculateFilledArea();
4004  }
4005 
4006  // Ensure keepout and non copper zones do not have a net
4007  // (which have no sense for these zones)
4008  // the netcode 0 is used for these zones
4009  bool zone_has_net = zone->IsOnCopperLayer() && !zone->GetIsKeepout();
4010 
4011  if( !zone_has_net )
4012  zone->SetNetCode( NETINFO_LIST::UNCONNECTED );
4013 
4014  // Ensure the zone net name is valid, and matches the net code, for copper zones
4015  if( zone_has_net && ( zone->GetNet()->GetNetname() != netnameFromfile ) )
4016  {
4017  // Can happens which old boards, with nonexistent nets ...
4018  // or after being edited by hand
4019  // We try to fix the mismatch.
4020  NETINFO_ITEM* net = m_board->FindNet( netnameFromfile );
4021 
4022  if( net ) // An existing net has the same net name. use it for the zone
4023  zone->SetNetCode( net->GetNet() );
4024  else // Not existing net: add a new net to keep trace of the zone netname
4025  {
4026  int newnetcode = m_board->GetNetCount();
4027  net = new NETINFO_ITEM( m_board, netnameFromfile, newnetcode );
4028  m_board->Add( net );
4029 
4030  // Store the new code mapping
4031  pushValueIntoMap( newnetcode, net->GetNet() );
4032  // and update the zone netcode
4033  zone->SetNetCode( net->GetNet() );
4034 
4035  // FIXME: a call to any GUI item is not allowed in io plugins:
4036  // Change this code to generate a warning message outside this plugin
4037  // Prompt the user
4038  wxString msg;
4039  msg.Printf( _( "There is a zone that belongs to a not existing net\n"
4040  "\"%s\"\n"
4041  "you should verify and edit it (run DRC test)." ),
4042  GetChars( netnameFromfile ) );
4043  DisplayError( NULL, msg );
4044  }
4045  }
4046 
4047  // Clear flags used in zone edition:
4048  zone->SetNeedRefill( false );
4049 
4050  return zone.release();
4051 }
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:239
NETINFO_ITEM * FindNet(int aNetcode) const
Function FindNet searches for a net with the given netcode.
void SetModified()
Definition: base_struct.cpp:94
ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:60
std::vector< SEG > ZONE_SEGMENT_FILL
Definition: class_zone.h:47
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:231
static int GetDefaultHatchPitch()
Function GetDefaultHatchPitchMils.
int parseBoardUnits()
Definition: pcb_parser.h:255
bool parseBool()
Definition: pcb_parser.cpp:179
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Adds an item to the container.
Definition: common.h:65
pads are covered by copper
#define NULL
unsigned GetNetCount() const
Function GetNetCount.
Definition: class_board.h:742
SHAPE_POLY_SET.
void SetNetCode(int aNetCode)
Definition: netinfo.h:226
PCB_LAYER_ID parseBoardItemLayer()
Function parseBoardItemLayer parses the layer definition of a BOARD_ITEM object.
#define THROW_IO_ERROR(msg)
bool m_showLegacyZoneWarning
Definition: pcb_parser.h:82
int NewOutline()
Creates a new empty polygon in the set and returns its index
Thermal relief only for THT pads.
Definition: seg.h:39
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:101
ZONE_HATCH_STYLE
Zone hatch styles.
Definition: zone_settings.h:45
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:224
#define _(s)
Definition: 3d_actions.cpp:33
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:86
BOARD * m_board
Definition: pcb_parser.h:74
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:137
MODULE_ZONE_CONTAINER is the same item as ZONE_CONTAINER, but with a specific type id ZONE_CONTAINER ...
Definition: class_zone.h:848
Pads are not covered.
double parseDouble()
Function parseDouble parses the current token as an ASCII numeric string with possible leading whites...
Definition: pcb_parser.cpp:149
int parseInt()
Definition: pcb_parser.h:293
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
Definition: netinfo.h:462
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(), DIAGONAL_EDGE, DIAGONAL_FULL, DisplayError(), KIDIALOG::DoNotShowCheckbox(), Format(), FULL, GetChars(), ZONE_CONTAINER::GetDefaultHatchPitch(), NETINFO_ITEM::GetNet(), HATCH_PATTERN, SHAPE_POLY_SET::IsEmpty(), SHAPE_POLY_SET::NewOutline(), NO_HATCH, NONE, NULL, parseDouble(), parseInt(), POLYGONS, NETINFO_ITEM::SetNetCode(), KIDIALOG::ShowModal(), ZONE_SETTINGS::SMOOTHING_CHAMFER, ZONE_SETTINGS::SMOOTHING_FILLET, ZONE_SETTINGS::SMOOTHING_NONE, THROW_IO_ERROR, THT_THERMAL, and NETINFO_LIST::UNCONNECTED.

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

138 {
139  // Add aValue in netcode mapping (m_netCodes) at index aNetCode
140  // ensure there is room in m_netCodes for that, and add room if needed.
141 
142  if( (int)m_netCodes.size() <= aIndex )
143  m_netCodes.resize( aIndex+1 );
144 
145  m_netCodes[aIndex] = aValue;
146 }
std::vector< int > m_netCodes
net codes mapping for boards being loaded
Definition: pcb_parser.h:78

◆ SetBoard()

void PCB_PARSER::SetBoard ( BOARD aBoard)
inline

Definition at line 342 of file pcb_parser.h.

343  {
344  init();
345  m_board = aBoard;
346  }
BOARD * m_board
Definition: pcb_parser.h:74
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 335 of file pcb_parser.h.

336  {
337  LINE_READER* ret = PopReader();
338  PushReader( aReader );
339  return ret;
340  }
LINE_READER is an abstract class from which implementation specific LINE_READERs may be derived to re...
Definition: richio.h:81

Referenced by GITHUB_PLUGIN::FootprintLoad(), CLIPBOARD_IO::Load(), PCB_IO::Load(), FP_CACHE::Load(), parse(), PCB_IO::Parse(), KI_TEST::ReadBoardItemFromFile(), and KI_TEST::ReadBoardItemFromStream().

◆ skipCurrent()

void PCB_PARSER::skipCurrent ( )
private

Function skipCurrent Skip the current token level, i.e search for the RIGHT parenthesis which closes the current description.

Definition at line 116 of file pcb_parser.cpp.

117 {
118  int curr_level = 0;
119  T token;
120 
121  while( ( token = NextTok() ) != T_EOF )
122  {
123  if( token == T_LEFT )
124  curr_level--;
125 
126  if( token == T_RIGHT )
127  {
128  curr_level++;
129 
130  if( curr_level > 0 )
131  return;
132  }
133  }
134 }

Member Data Documentation

◆ m_board

BOARD* PCB_PARSER::m_board
private

Definition at line 74 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 75 of file pcb_parser.h.

◆ m_layerMasks

LSET_MAP PCB_PARSER::m_layerMasks
private

map layer names to their masks

Definition at line 76 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 78 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 80 of file pcb_parser.h.

◆ m_showLegacyZoneWarning

bool PCB_PARSER::m_showLegacyZoneWarning
private

Definition at line 82 of file pcb_parser.h.

◆ m_tooRecent

bool PCB_PARSER::m_tooRecent
private

true if version parses as later than supported

Definition at line 79 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 77 of file pcb_parser.h.


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