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 PAD;
48 class DIMENSION_BASE;
49 class PCB_SHAPE;
50 class EDA_TEXT;
51 class FP_SHAPE;
52 class FP_TEXT;
53 class PCB_TEXT;
54 class TRACK;
55 class FOOTPRINT;
56 class PCB_GROUP;
57 class PCB_TARGET;
58 class VIA;
59 class ZONE;
60 class FP_3DMODEL;
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  typedef std::unordered_map< wxString, KIID > KIID_MAP;
74 
78  std::set<wxString> m_undefinedLayers;
79  std::vector<int> m_netCodes;
80  bool m_tooRecent;
82  bool m_resetKIIDs;
84 
86 
87  // Group membership info refers to other Uuids in the file.
88  // We don't want to rely on group declarations being last in the file, so
89  // we store info about the group declarations here during parsing and then resolve
90  // them into BOARD_ITEM* after we've parsed the rest of the file.
91  typedef struct
92  {
94  wxString name;
96  std::vector<KIID> memberUuids;
97  } GROUP_INFO;
98 
99  std::vector<GROUP_INFO> m_groupInfos;
100 
103  inline int getNetCode( int aNetCode )
104  {
105  if( ( aNetCode >= 0 ) && ( aNetCode < (int) m_netCodes.size() ) )
106  return m_netCodes[aNetCode];
107 
108  return aNetCode;
109  }
110 
118  void pushValueIntoMap( int aIndex, int aValue );
119 
126  void init();
127 
134  void createOldLayerMapping( std::unordered_map< std::string, std::string >& aMap );
135 
141  void skipCurrent();
142 
143  void parseHeader();
144  void parseGeneralSection();
145  void parsePAGE_INFO();
146  void parseTITLE_BLOCK();
147 
148  void parseLayers();
149  void parseLayer( LAYER* aLayer );
150 
151  void parseBoardStackup();
152 
153  void parseSetup();
154  void parseDefaults( BOARD_DESIGN_SETTINGS& aSettings );
155  void parseDefaultTextDims( BOARD_DESIGN_SETTINGS& aSettings, int aLayer );
156  void parseNETINFO_ITEM();
157  void parseNETCLASS();
158 
162 
163  // Parse a footprint, but do not replace PARSE_ERROR with FUTURE_FORMAT_ERROR automatically.
164  FOOTPRINT* parseFOOTPRINT_unchecked( wxArrayString* aInitialComments = 0 );
165 
168  PAD* parsePAD( FOOTPRINT* aParent = NULL );
169 
170  // Parse only the (option ...) inside a pad description
171  bool parsePAD_option( PAD* aPad );
172 
173  ARC* parseARC();
174  TRACK* parseTRACK();
175  VIA* parseVIA();
176  ZONE* parseZONE( BOARD_ITEM_CONTAINER* aParent );
178  BOARD* parseBOARD();
179  void parseGROUP( BOARD_ITEM* aParent );
180 
181  // Parse a board, but do not replace PARSE_ERROR with FUTURE_FORMAT_ERROR automatically.
183 
194  template<class T, class M>
195  T lookUpLayer( const M& aMap );
196 
206 
216 
228  wxPoint parseXY();
229 
230  void parseXY( int* aX, int* aY );
231 
232  std::pair<wxString, wxString> parseProperty();
233 
241  void parseEDA_TEXT( EDA_TEXT* aText );
242 
244 
253  double parseDouble();
254 
255  inline double parseDouble( const char* aExpected )
256  {
257  NeedNUMBER( aExpected );
258  return parseDouble();
259  }
260 
261  inline double parseDouble( PCB_KEYS_T::T aToken )
262  {
263  return parseDouble( GetTokenText( aToken ) );
264  }
265 
266  inline int parseBoardUnits()
267  {
268  // There should be no major rounding issues here, since the values in
269  // the file are in mm and get converted to nano-meters.
270  // See test program tools/test-nm-biu-to-ascii-mm-round-tripping.cpp
271  // to confirm or experiment. Use a similar strategy in both places, here
272  // and in the test program. Make that program with:
273  // $ make test-nm-biu-to-ascii-mm-round-tripping
274  auto retval = parseDouble() * IU_PER_MM;
275 
276  // N.B. we currently represent board units as integers. Any values that are
277  // larger or smaller than those board units represent undefined behavior for
278  // the system. We limit values to the largest that is visible on the screen
279  // This is the diagonal distance of the full screen ~1.5m
280  double int_limit = std::numeric_limits<int>::max() * 0.7071; // 0.7071 = roughly 1/sqrt(2)
281  return KiROUND( Clamp<double>( -int_limit, retval, int_limit ) );
282  }
283 
284  inline int parseBoardUnits( const char* aExpected )
285  {
286  auto retval = parseDouble( aExpected ) * IU_PER_MM;
287 
288  // N.B. we currently represent board units as integers. Any values that are
289  // larger or smaller than those board units represent undefined behavior for
290  // the system. We limit values to the largest that is visible on the screen
291  double int_limit = std::numeric_limits<int>::max() * 0.7071;
292 
293  // Use here KiROUND, not KIROUND (see comments about them)
294  // when having a function as argument, because it will be called twice
295  // with KIROUND
296  return KiROUND( Clamp<double>( -int_limit, retval, int_limit ) );
297  }
298 
299  inline int parseBoardUnits( PCB_KEYS_T::T aToken )
300  {
301  return parseBoardUnits( GetTokenText( aToken ) );
302  }
303 
304  inline int parseInt()
305  {
306  return (int)strtol( CurText(), NULL, 10 );
307  }
308 
309  inline int parseInt( const char* aExpected )
310  {
311  NeedNUMBER( aExpected );
312  return parseInt();
313  }
314 
315  inline long parseHex()
316  {
317  NextTok();
318  return strtol( CurText(), NULL, 16 );
319  }
320 
321  bool parseBool();
322 
323  /*
324  * @return if m_resetKIIDs, returns new KIID(), otehrwise returns CurStr() as KIID.
325  */
326  KIID CurStrToKIID();
327 
332  void resolveGroups( BOARD_ITEM* aParent );
333 
334 public:
335 
336  PCB_PARSER( LINE_READER* aReader = NULL ) :
337  PCB_LEXER( aReader ),
338  m_board( nullptr ),
339  m_resetKIIDs( false )
340  {
341  init();
342  }
343 
344  // ~PCB_PARSER() {}
345 
353  {
354  LINE_READER* ret = PopReader();
355  PushReader( aReader );
356  return ret;
357  }
358 
359  void SetBoard( BOARD* aBoard )
360  {
361  init();
362  m_board = aBoard;
363 
364  if( aBoard != nullptr )
365  m_resetKIIDs = true;
366  }
367 
368  BOARD_ITEM* Parse();
375  FOOTPRINT* parseFOOTPRINT( wxArrayString* aInitialComments = 0 );
376 
380  bool IsTooRecent()
381  {
382  return m_tooRecent;
383  }
384 
389  wxString GetRequiredVersion();
390 
391 };
392 
393 
394 #endif // _PCBNEW_PARSER_H_
void parseHeader()
Definition: pcb_parser.cpp:821
Definition: track.h:344
An abstract class from which implementation specific LINE_READERs may be derived to read single lines...
Definition: richio.h:80
KIID CurStrToKIID()
std::unordered_map< wxString, KIID > KIID_MAP
Definition: pcb_parser.h:73
LSET parseBoardItemLayersAsMask()
Function parseBoardItemLayersAsMask parses the layers definition of a BOARD_ITEM object.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:82
TRACK * parseTRACK()
static constexpr double IU_PER_MM
Mock up a conversion function.
VIA * parseVIA()
PCB_GROUP is a set of BOARD_ITEMs (i.e., without duplicates)
Definition: pcb_group.h:50
PCB_PARSER reads a Pcbnew s-expression formatted LINE_READER object and returns the appropriate BOARD...
Definition: pcb_parser.h:69
std::vector< KIID > memberUuids
Definition: pcb_parser.h:96
void parseBoardStackup()
wxPoint parseXY()
Function parseXY parses a coordinate pair (xy X Y) in board units (mm).
Definition: pcb_parser.cpp:208
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:517
void parseEDA_TEXT(EDA_TEXT *aText)
Function parseEDA_TEXT parses the common settings for any object derived from EDA_TEXT.
Definition: pcb_parser.cpp:255
ARC * parseARC()
bool m_tooRecent
true if version parses as later than supported
Definition: pcb_parser.h:80
void parseTITLE_BLOCK()
Definition: pcb_parser.cpp:949
PCB_SHAPE * parsePCB_SHAPE()
int parseBoardUnits(PCB_KEYS_T::T aToken)
Definition: pcb_parser.h:299
int parseBoardUnits()
Definition: pcb_parser.h:266
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
FP_SHAPE * parseFP_SHAPE()
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:119
KIID_MAP m_resetKIIDMap
if resetting UUIDs, record new ones to update groups with
Definition: pcb_parser.h:83
void parsePAGE_INFO()
Definition: pcb_parser.cpp:893
bool parseBool()
Definition: pcb_parser.cpp:169
void skipCurrent()
Function skipCurrent Skip the current token level, i.e search for the RIGHT parenthesis which closes ...
Definition: pcb_parser.cpp:106
Definition: kiid.h:44
bool parsePAD_option(PAD *aPad)
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:184
LSET is a set of PCB_LAYER_IDs.
void SetBoard(BOARD *aBoard)
Definition: pcb_parser.h:359
#define NULL
std::pair< wxString, wxString > parseProperty()
Definition: pcb_parser.cpp:240
PCB_TEXT * parsePCB_TEXT()
PCB_PARSER(LINE_READER *aReader=NULL)
Definition: pcb_parser.h:336
PCB_TARGET * parsePCB_TARGET()
PCB_LAYER_ID parseBoardItemLayer()
Function parseBoardItemLayer parses the layer definition of a BOARD_ITEM object.
FOOTPRINT * parseFOOTPRINT(wxArrayString *aInitialComments=0)
Function parseFOOTPRINT.
std::vector< GROUP_INFO > m_groupInfos
Definition: pcb_parser.h:99
FP_TEXT * parseFP_TEXT()
PAD * parsePAD(FOOTPRINT *aParent=NULL)
FOOTPRINT * parseFOOTPRINT_unchecked(wxArrayString *aInitialComments=0)
ZONE handles a list of polygons defining a copper zone.
Definition: zone.h:57
BOARD_ITEM * Parse()
Definition: pcb_parser.cpp:473
void parseNETCLASS()
bool m_showLegacyZoneWarning
Definition: pcb_parser.h:85
LINE_READER * SetLineReader(LINE_READER *aReader)
Function SetLineReader sets aLineReader into the parser, and returns the previous one,...
Definition: pcb_parser.h:352
void parseDefaults(BOARD_DESIGN_SETTINGS &aSettings)
int parseInt(const char *aExpected)
Definition: pcb_parser.h:309
void parseGROUP(BOARD_ITEM *aParent)
BOARD * parseBOARD_unchecked()
Definition: pcb_parser.cpp:533
void parseLayer(LAYER *aLayer)
int m_requiredVersion
set to the KiCad format version this board requires
Definition: pcb_parser.h:81
bool IsTooRecent()
Return whether a version number, if any was parsed, was too recent.
Definition: pcb_parser.h:380
void parseDefaultTextDims(BOARD_DESIGN_SETTINGS &aSettings, int aLayer)
Board layer functions and definitions.
Definition: track.h:262
Container to hold information pertinent to a layer of a BOARD.
Definition: board.h:75
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:189
std::vector< int > m_netCodes
net codes mapping for boards being loaded
Definition: pcb_parser.h:79
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:103
BOARD * m_board
Definition: pcb_parser.h:75
void parseGeneralSection()
Definition: pcb_parser.cpp:860
void init()
Function init clears and re-establishes m_layerMap with the default layer names.
Definition: pcb_parser.cpp:61
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:127
double parseDouble(PCB_KEYS_T::T aToken)
Definition: pcb_parser.h:261
double parseDouble()
Function parseDouble parses the current token as an ASCII numeric string with possible leading whites...
Definition: pcb_parser.cpp:139
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:76
Abstract interface for BOARD_ITEMs capable of storing other items inside.
long parseHex()
Definition: pcb_parser.h:315
Definition: pad.h:60
int parseInt()
Definition: pcb_parser.h:304
BOARD_ITEM * parent
Definition: pcb_parser.h:93
DIMENSION_BASE * parseDIMENSION()
Abstract dimension API.
Definition: dimension.h:95
void resolveGroups(BOARD_ITEM *aParent)
Called after parsing a footprint definition or board to build the group membership lists.
Definition: pcb_parser.cpp:747
FP_3DMODEL * parse3DModel()
Definition: pcb_parser.cpp:367
LSET_MAP m_layerMasks
map layer names to their masks
Definition: pcb_parser.h:77
Definition: track.h:83
void parseSetup()
int parseBoardUnits(const char *aExpected)
Definition: pcb_parser.h:284
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:78
bool m_resetKIIDs
reading into an existing board; reset UUIDs
Definition: pcb_parser.h:82
double parseDouble(const char *aExpected)
Definition: pcb_parser.h:255
Container for design settings for a BOARD object.
ZONE * parseZONE(BOARD_ITEM_CONTAINER *aParent)