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-2021 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 <core/wx_stl_compat.h>
35 #include <hashtables.h>
36 #include <layer_ids.h> // PCB_LAYER_ID
37 #include <pcb_lexer.h>
38 #include <kiid.h>
39 
40 #include <chrono>
41 #include <unordered_map>
42 
43 
44 class PCB_ARC;
45 class BOARD;
46 class BOARD_ITEM;
48 class PAD;
50 class PCB_DIMENSION_BASE;
51 class PCB_SHAPE;
52 class EDA_TEXT;
53 class FP_SHAPE;
54 class FP_TEXT;
55 class PCB_TEXT;
56 class PCB_TRACK;
57 class FOOTPRINT;
58 class PCB_GROUP;
59 class PCB_TARGET;
60 class PCB_VIA;
61 class ZONE;
62 class FP_3DMODEL;
63 class SHAPE_LINE_CHAIN;
64 struct LAYER;
65 class PROGRESS_REPORTER;
66 
67 
72 class PCB_PARSER : public PCB_LEXER
73 {
74 public:
75  PCB_PARSER( LINE_READER* aReader = nullptr ) :
76  PCB_LEXER( aReader ),
77  m_board( nullptr ),
78  m_resetKIIDs( false ),
79  m_progressReporter( nullptr ),
80  m_lineReader( nullptr ),
81  m_lastProgressTime( std::chrono::steady_clock::now() ),
82  m_lineCount( 0 )
83  {
84  init();
85  }
86 
87  // ~PCB_PARSER() {}
88 
96  {
97  LINE_READER* ret = PopReader();
98  PushReader( aReader );
99  return ret;
100  }
101 
102  void SetBoard( BOARD* aBoard )
103  {
104  init();
105  m_board = aBoard;
106 
107  if( aBoard != nullptr )
108  m_resetKIIDs = true;
109  }
110 
111  void SetProgressReporter( PROGRESS_REPORTER* aProgressReporter, const LINE_READER* aLineReader,
112  unsigned aLineCount )
113  {
114  m_progressReporter = aProgressReporter;
115  m_lineReader = aLineReader;
116  m_lastProgressTime = std::chrono::steady_clock::now();
117  m_lineCount = aLineCount;
118  }
119 
120  BOARD_ITEM* Parse();
121 
128  FOOTPRINT* parseFOOTPRINT( wxArrayString* aInitialComments = nullptr );
129 
133  bool IsTooRecent()
134  {
135  return m_tooRecent;
136  }
137 
142  wxString GetRequiredVersion();
143 
144 private:
147  inline int getNetCode( int aNetCode )
148  {
149  if( ( aNetCode >= 0 ) && ( aNetCode < (int) m_netCodes.size() ) )
150  return m_netCodes[aNetCode];
151 
152  return aNetCode;
153  }
154 
163  void pushValueIntoMap( int aIndex, int aValue );
164 
171  void init();
172 
173  void checkpoint();
174 
182  void createOldLayerMapping( std::unordered_map< std::string, std::string >& aMap );
183 
188  void skipCurrent();
189 
190  void parseHeader();
191  void parseGeneralSection();
192  void parsePAGE_INFO();
193  void parseTITLE_BLOCK();
194 
195  void parseLayers();
196  void parseLayer( LAYER* aLayer );
197 
198  void parseBoardStackup();
199 
200  void parseSetup();
201  void parseDefaults( BOARD_DESIGN_SETTINGS& aSettings );
202  void parseDefaultTextDims( BOARD_DESIGN_SETTINGS& aSettings, int aLayer );
203  void parseNETINFO_ITEM();
204  void parseNETCLASS();
205 
209 
210  // Parse a footprint, but do not replace PARSE_ERROR with FUTURE_FORMAT_ERROR automatically.
211  FOOTPRINT* parseFOOTPRINT_unchecked( wxArrayString* aInitialComments = nullptr );
212 
215  PAD* parsePAD( FOOTPRINT* aParent = nullptr );
216 
217  // Parse only the (option ...) inside a pad description
218  bool parsePAD_option( PAD* aPad );
219 
220  PCB_ARC* parseARC();
223  ZONE* parseZONE( BOARD_ITEM_CONTAINER* aParent );
225  BOARD* parseBOARD();
226  void parseGROUP( BOARD_ITEM* aParent );
227 
228  // Parse a board, but do not replace PARSE_ERROR with FUTURE_FORMAT_ERROR automatically.
230 
239  template<class T, class M>
240  T lookUpLayer( const M& aMap );
241 
250 
259 
270  wxPoint parseXY();
271 
272  void parseXY( int* aX, int* aY );
273 
274  std::pair<wxString, wxString> parseProperty();
275 
283  void parseOutlinePoints( SHAPE_LINE_CHAIN& aPoly );
284 
291  void parseEDA_TEXT( EDA_TEXT* aText );
292 
294 
302  double parseDouble();
303 
304  inline double parseDouble( const char* aExpected )
305  {
306  NeedNUMBER( aExpected );
307  return parseDouble();
308  }
309 
310  inline double parseDouble( PCB_KEYS_T::T aToken )
311  {
312  return parseDouble( GetTokenText( aToken ) );
313  }
314 
318  double parseAngle() { return parseDouble() * 10.0; }
319 
320  inline double parseAngle( const char* aExpected )
321  {
322  return parseDouble( aExpected ) * 10.0;
323  }
324 
325  int parseBoardUnits();
326 
327  int parseBoardUnits( const char* aExpected );
328 
329  inline int parseBoardUnits( PCB_KEYS_T::T aToken )
330  {
331  return parseBoardUnits( GetTokenText( aToken ) );
332  }
333 
334  inline int parseInt()
335  {
336  return (int)strtol( CurText(), nullptr, 10 );
337  }
338 
339  inline int parseInt( const char* aExpected )
340  {
341  NeedNUMBER( aExpected );
342  return parseInt();
343  }
344 
345  inline long parseHex()
346  {
347  NextTok();
348  return strtol( CurText(), nullptr, 16 );
349  }
350 
351  bool parseBool();
352 
353  /*
354  * @return if m_resetKIIDs, returns new KIID(), otherwise returns CurStr() as KIID.
355  */
356  KIID CurStrToKIID();
357 
362  void resolveGroups( BOARD_ITEM* aParent );
363 
364  typedef std::unordered_map< std::string, PCB_LAYER_ID > LAYER_ID_MAP;
365  typedef std::unordered_map< std::string, LSET > LSET_MAP;
366  typedef std::unordered_map< wxString, KIID > KIID_MAP;
367 
369  using TIMEOUT = std::chrono::milliseconds;
370 
372  using CLOCK = std::chrono::steady_clock;
373 
375  using TIME_PT = std::chrono::time_point<CLOCK>;
376 
380  std::set<wxString> m_undefinedLayers;
381  std::vector<int> m_netCodes;
382  bool m_tooRecent;
385 
388 
390 
394  unsigned m_lineCount;
395 
396  // Group membership info refers to other Uuids in the file.
397  // We don't want to rely on group declarations being last in the file, so
398  // we store info about the group declarations here during parsing and then resolve
399  // them into BOARD_ITEM* after we've parsed the rest of the file.
400  struct GROUP_INFO
401  {
403  wxString name;
404  bool locked;
406  std::vector<KIID> memberUuids;
407  };
408 
409  std::vector<GROUP_INFO> m_groupInfos;
410 };
411 
412 
413 #endif // _PCBNEW_PARSER_H_
void parseHeader()
void SetProgressReporter(PROGRESS_REPORTER *aProgressReporter, const LINE_READER *aLineReader, unsigned aLineCount)
Definition: pcb_parser.h:111
PCB_DIMENSION_BASE * parseDIMENSION()
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
The type of progress bar timeout.
Definition: pcb_parser.h:366
std::chrono::milliseconds TIMEOUT
The clock used for the timestamp (guaranteed to be monotonic).
Definition: pcb_parser.h:371
LSET parseBoardItemLayersAsMask()
Parse 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:49
unsigned m_lineCount
for progress reporting
Definition: pcb_parser.h:394
A set of BOARD_ITEMs (i.e., without duplicates).
Definition: pcb_group.h:50
Read a Pcbnew s-expression formatted LINE_READER object and returns the appropriate BOARD_ITEM object...
Definition: pcb_parser.h:72
A progress reporter interface for use in multi-threaded environments.
std::vector< KIID > memberUuids
Definition: pcb_parser.h:406
void parseBoardStackup()
wxPoint parseXY()
Parse a coordinate pair (xy X Y) in board units (mm).
Definition: pcb_parser.cpp:270
void parseNETINFO_ITEM()
void createOldLayerMapping(std::unordered_map< std::string, std::string > &aMap)
Create a mapping from the (short-lived) bug where layer names were translated.
FOOTPRINT * parseFOOTPRINT(wxArrayString *aInitialComments=nullptr)
BOARD * parseBOARD()
Definition: pcb_parser.cpp:676
double parseAngle()
Parse angles into deci-degrees.
Definition: pcb_parser.h:318
Definition: bitmap.cpp:64
void parseEDA_TEXT(EDA_TEXT *aText)
Parse the common settings for any object derived from EDA_TEXT.
Definition: pcb_parser.cpp:402
Abstract dimension API.
Definition: pcb_dimension.h:95
void checkpoint()
Definition: pcb_parser.cpp:112
bool m_tooRecent
true if version parses as later than supported
Definition: pcb_parser.h:382
void parseTITLE_BLOCK()
PCB_SHAPE * parsePCB_SHAPE()
int parseBoardUnits(PCB_KEYS_T::T aToken)
Definition: pcb_parser.h:329
PCB_ARC * parseARC()
int parseBoardUnits()
Definition: pcb_parser.cpp:197
void parseLayers()
std::unordered_map< std::string, LSET > LSET_MAP
Definition: pcb_parser.h:365
const LINE_READER * m_lineReader
for progress reporting
Definition: pcb_parser.h:392
std::unordered_map< std::string, PCB_LAYER_ID > LAYER_ID_MAP
Definition: pcb_parser.h:364
FP_SHAPE * parseFP_SHAPE()
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:140
KIID_MAP m_resetKIIDMap
Definition: pcb_parser.h:387
void parsePAGE_INFO()
bool parseBool()
Definition: pcb_parser.cpp:231
void skipCurrent()
Skip the current token level, i.e search for the RIGHT parenthesis which closes the current descripti...
Definition: pcb_parser.cpp:134
Definition: kiid.h:44
bool parsePAD_option(PAD *aPad)
PROGRESS_REPORTER * m_progressReporter
optional; may be nullptr
Definition: pcb_parser.h:391
wxString GetRequiredVersion()
Return a string representing the version of KiCad required to open this file.
Definition: pcb_parser.cpp:246
TIME_PT m_lastProgressTime
for progress reporting
Definition: pcb_parser.h:393
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:505
PCB_VIA * parsePCB_VIA()
void SetBoard(BOARD *aBoard)
Definition: pcb_parser.h:102
std::pair< wxString, wxString > parseProperty()
Definition: pcb_parser.cpp:387
PCB_TRACK * parsePCB_TRACK()
PCB_TEXT * parsePCB_TEXT()
PCB_TARGET * parsePCB_TARGET()
PCB_LAYER_ID parseBoardItemLayer()
Parse the layer definition of a BOARD_ITEM object.
std::vector< GROUP_INFO > m_groupInfos
Definition: pcb_parser.h:409
FP_TEXT * parseFP_TEXT()
Handle a list of polygons defining a copper zone.
Definition: zone.h:56
FOOTPRINT * parseFOOTPRINT_unchecked(wxArrayString *aInitialComments=nullptr)
void parseOutlinePoints(SHAPE_LINE_CHAIN &aPoly)
Parses possible outline points and stores them into aPoly.
Definition: pcb_parser.cpp:290
BOARD_ITEM * Parse()
Definition: pcb_parser.cpp:626
void parseNETCLASS()
bool m_showLegacyZoneWarning
Definition: pcb_parser.h:389
PAD * parsePAD(FOOTPRINT *aParent=nullptr)
LINE_READER * SetLineReader(LINE_READER *aReader)
Set aLineReader into the parser, and returns the previous one, if any.
Definition: pcb_parser.h:95
void parseDefaults(BOARD_DESIGN_SETTINGS &aSettings)
int parseInt(const char *aExpected)
Definition: pcb_parser.h:339
void parseGROUP(BOARD_ITEM *aParent)
BOARD * parseBOARD_unchecked()
Definition: pcb_parser.cpp:692
void parseLayer(LAYER *aLayer)
int m_requiredVersion
set to the KiCad format version this board requires
Definition: pcb_parser.h:383
bool IsTooRecent()
Return whether a version number, if any was parsed, was too recent.
Definition: pcb_parser.h:133
void parseDefaultTextDims(BOARD_DESIGN_SETTINGS &aSettings, int aLayer)
Container to hold information pertinent to a layer of a BOARD.
Definition: board.h:82
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:191
std::vector< int > m_netCodes
net codes mapping for boards being loaded
Definition: pcb_parser.h:381
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65
int getNetCode(int aNetCode)
< Convert net code using the mapping table if available, otherwise returns unchanged net code if < 0 ...
Definition: pcb_parser.h:147
BOARD * m_board
Definition: pcb_parser.h:377
void parseGeneralSection()
void init()
Clear and re-establish m_layerMap with the default layer names.
Definition: pcb_parser.cpp:67
std::chrono::time_point< CLOCK > TIME_PT
Definition: pcb_parser.h:375
void pushValueIntoMap(int aIndex, int aValue)
Add aValue value in netcode mapping (m_netCodes) at aIndex.
Definition: pcb_parser.cpp:155
double parseDouble(PCB_KEYS_T::T aToken)
Definition: pcb_parser.h:310
double parseDouble()
Parse the current token as an ASCII numeric string with possible leading whitespace into a double pre...
Definition: pcb_parser.cpp:167
const char * GetTokenText(T aTok)
The DSN namespace and returns the C string representing a SPECCTRA_DB::keyword.
Definition: specctra.cpp:70
std::chrono::steady_clock CLOCK
The type of the time stamps.
Definition: pcb_parser.h:374
LAYER_ID_MAP m_layerIndices
map layer name to it's index
Definition: pcb_parser.h:378
Abstract interface for BOARD_ITEMs capable of storing other items inside.
long parseHex()
Definition: pcb_parser.h:345
Definition: pad.h:57
int parseInt()
Definition: pcb_parser.h:334
BOARD_ITEM * parent
Definition: pcb_parser.h:402
double parseAngle(const char *aExpected)
Definition: pcb_parser.h:320
void resolveGroups(BOARD_ITEM *aParent)
Called after parsing a footprint definition or board to build the group membership lists.
Definition: pcb_parser.cpp:936
PCB_PARSER(LINE_READER *aReader=nullptr)
Definition: pcb_parser.h:75
FP_3DMODEL * parse3DModel()
Definition: pcb_parser.cpp:520
LSET_MAP m_layerMasks
map layer names to their masks
Definition: pcb_parser.h:379
void parseSetup()
T lookUpLayer(const M &aMap)
Parse 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:380
bool m_resetKIIDs
reading into an existing board; reset UUIDs
Definition: pcb_parser.h:384
double parseDouble(const char *aExpected)
Definition: pcb_parser.h:304
Container for design settings for a BOARD object.
ZONE * parseZONE(BOARD_ITEM_CONTAINER *aParent)