KiCad PCB EDA Suite
pcb_parser.h
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2012 CERN
5  * Copyright (C) 2012-2019 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
30 #ifndef _PCBNEW_PARSER_H_
31 #define _PCBNEW_PARSER_H_
32 
33 #include <convert_to_biu.h> // IU_PER_MM
34 #include <hashtables.h>
35 #include <layers_id_colors_and_visibility.h> // PCB_LAYER_ID
36 #include <math/util.h> // KiROUND, Clamp
37 #include <pcb_lexer.h>
38 
39 #include <unordered_map>
40 
41 
42 class ARC;
43 class BOARD;
44 class BOARD_ITEM;
46 class D_PAD;
48 class DIMENSION;
49 class DRAWSEGMENT;
50 class EDA_TEXT;
51 class EDGE_MODULE;
52 class TEXTE_MODULE;
53 class TEXTE_PCB;
54 class TRACK;
55 class MODULE;
56 class PCB_TARGET;
57 class VIA;
58 class ZONE_CONTAINER;
59 class MARKER_PCB;
60 class MODULE_3D_SETTINGS;
61 struct LAYER;
62 
63 
69 class PCB_PARSER : public PCB_LEXER
70 {
71  typedef std::unordered_map< std::string, PCB_LAYER_ID > LAYER_ID_MAP;
72  typedef std::unordered_map< std::string, LSET > LSET_MAP;
73 
77  std::set<wxString> m_undefinedLayers;
78  std::vector<int> m_netCodes;
79  bool m_tooRecent;
81  bool m_resetKIIDs;
82 
84 
87  inline int getNetCode( int aNetCode )
88  {
89  if( ( aNetCode >= 0 ) && ( aNetCode < (int) m_netCodes.size() ) )
90  return m_netCodes[aNetCode];
91 
92  return aNetCode;
93  }
94 
102  void pushValueIntoMap( int aIndex, int aValue );
103 
110  void init();
111 
118  void createOldLayerMapping( std::unordered_map< std::string, std::string >& aMap );
119 
125  void skipCurrent();
126 
127  void parseHeader();
128  void parseGeneralSection();
129  void parsePAGE_INFO();
130  void parseTITLE_BLOCK();
131 
132  void parseLayers();
133  void parseLayer( LAYER* aLayer );
134 
135  void parseBoardStackup();
136 
137  void parseSetup();
138  void parseDefaults( BOARD_DESIGN_SETTINGS& aSettings );
139  void parseDefaultTextDims( BOARD_DESIGN_SETTINGS& aSettings, int aLayer );
140  void parseNETINFO_ITEM();
141  void parseNETCLASS();
142 
147  DRAWSEGMENT* parseDRAWSEGMENT( bool aAllowCirclesZeroWidth = false );
150 
155  MODULE* parseMODULE_unchecked( wxArrayString* aInitialComments = 0 );
158  D_PAD* parseD_PAD( MODULE* aParent = NULL );
159  // Parse only the (option ...) inside a pad description
160  bool parseD_PAD_option( D_PAD* aPad );
161  ARC* parseARC();
162  TRACK* parseTRACK();
163  VIA* parseVIA();
167  BOARD* parseBOARD();
168 
174 
175 
186  template<class T, class M>
187  T lookUpLayer( const M& aMap );
188 
198 
208 
220  wxPoint parseXY();
221 
222  void parseXY( int* aX, int* aY );
223 
231  void parseEDA_TEXT( EDA_TEXT* aText );
232 
234 
243  double parseDouble();
244 
245  inline double parseDouble( const char* aExpected )
246  {
247  NeedNUMBER( aExpected );
248  return parseDouble();
249  }
250 
251  inline double parseDouble( PCB_KEYS_T::T aToken )
252  {
253  return parseDouble( GetTokenText( aToken ) );
254  }
255 
256  inline int parseBoardUnits()
257  {
258  // There should be no major rounding issues here, since the values in
259  // the file are in mm and get converted to nano-meters.
260  // See test program tools/test-nm-biu-to-ascii-mm-round-tripping.cpp
261  // to confirm or experiment. Use a similar strategy in both places, here
262  // and in the test program. Make that program with:
263  // $ make test-nm-biu-to-ascii-mm-round-tripping
264  auto retval = parseDouble() * IU_PER_MM;
265 
266  // N.B. we currently represent board units as integers. Any values that are
267  // larger or smaller than those board units represent undefined behavior for
268  // the system. We limit values to the largest that is visible on the screen
269  // This is the diagonal distance of the full screen ~1.5m
270  double int_limit = std::numeric_limits<int>::max() * 0.7071; // 0.7071 = roughly 1/sqrt(2)
271  return KiROUND( Clamp<double>( -int_limit, retval, int_limit ) );
272  }
273 
274  inline int parseBoardUnits( const char* aExpected )
275  {
276  auto retval = parseDouble( aExpected ) * IU_PER_MM;
277 
278  // N.B. we currently represent board units as integers. Any values that are
279  // larger or smaller than those board units represent undefined behavior for
280  // the system. We limit values to the largest that is visible on the screen
281  double int_limit = std::numeric_limits<int>::max() * 0.7071;
282 
283  // Use here KiROUND, not KIROUND (see comments about them)
284  // when having a function as argument, because it will be called twice
285  // with KIROUND
286  return KiROUND( Clamp<double>( -int_limit, retval, int_limit ) );
287  }
288 
289  inline int parseBoardUnits( PCB_KEYS_T::T aToken )
290  {
291  return parseBoardUnits( GetTokenText( aToken ) );
292  }
293 
294  inline int parseInt()
295  {
296  return (int)strtol( CurText(), NULL, 10 );
297  }
298 
299  inline int parseInt( const char* aExpected )
300  {
301  NeedNUMBER( aExpected );
302  return parseInt();
303  }
304 
305  inline long parseHex()
306  {
307  NextTok();
308  return strtol( CurText(), NULL, 16 );
309  }
310 
311  bool parseBool();
312 
317  int parseVersion();
318 
319 public:
320 
321  PCB_PARSER( LINE_READER* aReader = NULL ) :
322  PCB_LEXER( aReader ),
323  m_board( 0 ),
324  m_resetKIIDs( false )
325  {
326  init();
327  }
328 
329  // ~PCB_PARSER() {}
330 
338  {
339  LINE_READER* ret = PopReader();
340  PushReader( aReader );
341  return ret;
342  }
343 
344  void SetBoard( BOARD* aBoard )
345  {
346  init();
347  m_board = aBoard;
348 
349  if( aBoard != nullptr )
350  m_resetKIIDs = true;
351  }
352 
353  BOARD_ITEM* Parse();
360  MODULE* parseMODULE( wxArrayString* aInitialComments = 0 );
361 
365  bool IsTooRecent()
366  {
367  return m_tooRecent;
368  }
369 
374  wxString GetRequiredVersion();
375 
376 };
377 
378 
379 #endif // _PCBNEW_PARSER_H_
void parseHeader()
Definition: pcb_parser.cpp:714
int parseVersion()
Parse a format version tag like (version 20160417) return the version.
Definition: pcb_parser.cpp:195
ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:61
LINE_READER is an abstract class from which implementation specific LINE_READERs may be derived to re...
Definition: richio.h:81
DRAWSEGMENT * parseDRAWSEGMENT(bool aAllowCirclesZeroWidth=false)
Read a DRAWSEGMENT description.
LSET parseBoardItemLayersAsMask()
Function parseBoardItemLayersAsMask parses the layers definition of a BOARD_ITEM object.
BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class,...
TRACK * parseTRACK()
static constexpr double IU_PER_MM
Mock up a conversion function.
VIA * parseVIA()
PCB_PARSER reads a Pcbnew s-expression formatted LINE_READER object and returns the appropriate BOARD...
Definition: pcb_parser.h:69
void parseBoardStackup()
wxPoint parseXY()
Function parseXY parses a coordinate pair (xy X Y) in board units (mm).
Definition: pcb_parser.cpp:232
void parseNETINFO_ITEM()
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...
BOARD * parseBOARD()
Definition: pcb_parser.cpp:520
bool parseD_PAD_option(D_PAD *aPad)
void parseEDA_TEXT(EDA_TEXT *aText)
Function parseEDA_TEXT parses the common settings for any object derived from EDA_TEXT.
Definition: pcb_parser.cpp:264
ARC * parseARC()
DIMENSION * parseDIMENSION()
bool m_tooRecent
true if version parses as later than supported
Definition: pcb_parser.h:79
T
enum T contains all this lexer's tokens.
void parseTITLE_BLOCK()
Definition: pcb_parser.cpp:852
int parseBoardUnits(PCB_KEYS_T::T aToken)
Definition: pcb_parser.h:289
int parseBoardUnits()
Definition: pcb_parser.h:256
void parseLayers()
std::unordered_map< std::string, LSET > LSET_MAP
Definition: pcb_parser.h:72
std::unordered_map< std::string, PCB_LAYER_ID > LAYER_ID_MAP
Definition: pcb_parser.h:71
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:113
void parsePAGE_INFO()
Definition: pcb_parser.cpp:796
bool parseBool()
Definition: pcb_parser.cpp:180
void skipCurrent()
Function skipCurrent Skip the current token level, i.e search for the RIGHT parenthesis which closes ...
Definition: pcb_parser.cpp:117
PCB_LAYER_ID
A quick note on layer IDs:
wxString GetRequiredVersion()
Return a string representing the version of kicad required to open this file.
Definition: pcb_parser.cpp:208
LSET is a set of PCB_LAYER_IDs.
void SetBoard(BOARD *aBoard)
Definition: pcb_parser.h:344
#define NULL
PCB_PARSER(LINE_READER *aReader=NULL)
Definition: pcb_parser.h:321
MODULE * parseMODULE_unchecked(wxArrayString *aInitialComments=0)
Function parseMODULE_unchecked Parse a module, but do not replace PARSE_ERROR with FUTURE_FORMAT_ERRO...
PCB_TARGET * parsePCB_TARGET()
PCB_LAYER_ID parseBoardItemLayer()
Function parseBoardItemLayer parses the layer definition of a BOARD_ITEM object.
ZONE_CONTAINER * parseZONE_CONTAINER(BOARD_ITEM_CONTAINER *aParent)
TEXTE_PCB * parseTEXTE_PCB()
BOARD_ITEM * Parse()
Definition: pcb_parser.cpp:481
void parseNETCLASS()
bool m_showLegacyZoneWarning
Definition: pcb_parser.h:83
LINE_READER * SetLineReader(LINE_READER *aReader)
Function SetLineReader sets aLineReader into the parser, and returns the previous one,...
Definition: pcb_parser.h:337
MARKER_PCB * parseMARKER(BOARD_ITEM_CONTAINER *aParent)
void parseDefaults(BOARD_DESIGN_SETTINGS &aSettings)
int parseInt(const char *aExpected)
Definition: pcb_parser.h:299
BOARD * parseBOARD_unchecked()
Function parseBOARD_unchecked Parse a module, but do not replace PARSE_ERROR with FUTURE_FORMAT_ERROR...
Definition: pcb_parser.cpp:536
void parseLayer(LAYER *aLayer)
Definition: pcb_parser.cpp:960
int m_requiredVersion
set to the KiCad format version this board requires
Definition: pcb_parser.h:80
bool IsTooRecent()
Return whether a version number, if any was parsed, was too recent.
Definition: pcb_parser.h:365
void parseDefaultTextDims(BOARD_DESIGN_SETTINGS &aSettings, int aLayer)
EDGE_MODULE * parseEDGE_MODULE()
Board layer functions and definitions.
LAYER holds information pertinent to a layer of a BOARD.
Definition: class_board.h:80
BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:180
std::vector< int > m_netCodes
net codes mapping for boards being loaded
Definition: pcb_parser.h:78
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:87
BOARD * m_board
Definition: pcb_parser.h:74
void parseGeneralSection()
Definition: pcb_parser.cpp:750
void init()
Function init clears and re-establishes m_layerMap with the default layer names.
Definition: pcb_parser.cpp:58
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:68
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:138
double parseDouble(PCB_KEYS_T::T aToken)
Definition: pcb_parser.h:251
double parseDouble()
Function parseDouble parses the current token as an ASCII numeric string with possible leading whites...
Definition: pcb_parser.cpp:150
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
LAYER_ID_MAP m_layerIndices
map layer name to it's index
Definition: pcb_parser.h:75
TEXTE_MODULE * parseTEXTE_MODULE()
Abstract interface for BOARD_ITEMs capable of storing other items inside.
D_PAD * parseD_PAD(MODULE *aParent=NULL)
MODULE * parseMODULE(wxArrayString *aInitialComments=0)
Function parseMODULE.
long parseHex()
Definition: pcb_parser.h:305
int parseInt()
Definition: pcb_parser.h:294
LSET_MAP m_layerMasks
map layer names to their masks
Definition: pcb_parser.h:76
DIMENSION.
void parseSetup()
int parseBoardUnits(const char *aExpected)
Definition: pcb_parser.h:274
T lookUpLayer(const M &aMap)
Function lookUpLayer parses the current token for the layer definition of a BOARD_ITEM object.
std::set< wxString > m_undefinedLayers
set of layers not defined in layers section
Definition: pcb_parser.h:77
bool m_resetKIIDs
reading into an existing board; reset UUIDs
Definition: pcb_parser.h:81
double parseDouble(const char *aExpected)
Definition: pcb_parser.h:245
BOARD_DESIGN_SETTINGS contains design settings for a BOARD object.
MODULE_3D_SETTINGS * parse3DModel()
Definition: pcb_parser.cpp:375