KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcb_io_kicad_sexpr_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-2023 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 <core/wx_stl_compat.h>
34#include <hashtables.h>
35#include <layer_ids.h> // PCB_LAYER_ID
36#include <lset.h>
37#include <pcb_lexer.h>
38#include <kiid.h>
39#include <math/box2.h>
40#include <string_any_map.h>
41
42#include <chrono>
43#include <unordered_map>
44
45
46class PCB_ARC;
47class BOARD;
48class BOARD_ITEM;
50class PAD;
53class PCB_SHAPE;
55class EDA_TEXT;
56class PCB_TEXT;
57class PCB_TRACK;
58class PCB_TABLE;
59class PCB_TABLECELL;
60class FOOTPRINT;
61class PCB_GROUP;
62class PCB_TARGET;
63class PCB_VIA;
64class ZONE;
65class FP_3DMODEL;
67struct LAYER;
70
71
76class PCB_IO_KICAD_SEXPR_PARSER : public PCB_LEXER
77{
78public:
80 std::function<bool( wxString, int, wxString, wxString )> aQueryUserCallback,
81 PROGRESS_REPORTER* aProgressReporter = nullptr, unsigned aLineCount = 0 ) :
82 PCB_LEXER( aReader ),
83 m_board( aAppendToMe ),
84 m_appendToExisting( aAppendToMe != nullptr ),
85 m_progressReporter( aProgressReporter ),
86 m_lastProgressTime( std::chrono::steady_clock::now() ),
87 m_lineCount( aLineCount ),
88 m_queryUserCallback( std::move( aQueryUserCallback ) )
89 {
90 init();
91 }
92
93 // ~PCB_IO_KICAD_SEXPR_PARSER() {}
94
96
103 FOOTPRINT* parseFOOTPRINT( wxArrayString* aInitialComments = nullptr );
104
109 {
110 return m_tooRecent;
111 }
112
117 wxString GetRequiredVersion();
118
123 bool IsValidBoardHeader();
124
125private:
126
127 // Group membership info refers to other Uuids in the file.
128 // We don't want to rely on group declarations being last in the file, so
129 // we store info about the group declarations here during parsing and then resolve
130 // them into BOARD_ITEM* after we've parsed the rest of the file.
132 {
133 virtual ~GROUP_INFO() = default; // Make polymorphic
134
136 wxString name;
137 bool locked;
139 std::vector<KIID> memberUuids;
140 };
141
143 {
145 wxString genType;
147 };
148
151 inline int getNetCode( int aNetCode )
152 {
153 if( ( aNetCode >= 0 ) && ( aNetCode < (int) m_netCodes.size() ) )
154 return m_netCodes[aNetCode];
155
156 return aNetCode;
157 }
158
167 void pushValueIntoMap( int aIndex, int aValue );
168
175 void init();
176
177 void checkpoint();
178
186 void createOldLayerMapping( std::unordered_map< std::string, std::string >& aMap );
187
192 void skipCurrent();
193
194 void parseHeader();
195 void parseGeneralSection();
196 void parsePAGE_INFO();
197 void parseTITLE_BLOCK();
198
199 void parseLayers();
200 void parseLayer( LAYER* aLayer );
201
202 void parseBoardStackup();
203
204 void parseSetup();
205 void parseDefaults( BOARD_DESIGN_SETTINGS& aSettings );
206 void parseDefaultTextDims( BOARD_DESIGN_SETTINGS& aSettings, int aLayer );
207 void parseNETINFO_ITEM();
208 void parseNETCLASS();
209
211
212 void parseTextBoxContent( PCB_TEXTBOX* aTextBox );
213
215 PCB_TEXT* parsePCB_TEXT( BOARD_ITEM* aParent );
216 void parsePCB_TEXT_effects( PCB_TEXT* aText );
222
223 // Parse a footprint, but do not replace PARSE_ERROR with FUTURE_FORMAT_ERROR automatically.
224 FOOTPRINT* parseFOOTPRINT_unchecked( wxArrayString* aInitialComments = nullptr );
225
226 PAD* parsePAD( FOOTPRINT* aParent = nullptr );
227
228 // Parse only the (option ...) inside a pad description
229 bool parsePAD_option( PAD* aPad );
230
231 PCB_ARC* parseARC();
236 BOARD* parseBOARD();
237 void parseGROUP_members( GROUP_INFO& aGroupInfo );
238 void parseGROUP( BOARD_ITEM* aParent );
239 void parseGENERATOR( BOARD_ITEM* aParent );
240
241 // Parse a board, but do not replace PARSE_ERROR with FUTURE_FORMAT_ERROR automatically.
243
252 template<class T, class M>
253 T lookUpLayer( const M& aMap );
254
263
272
284
285 void parseXY( int* aX, int* aY );
286
287 void parseMargins( int& aLeft, int& aTop, int& aRight, int& aBottom );
288
289 std::pair<wxString, wxString> parseBoardProperty();
290
299
306 void parseEDA_TEXT( EDA_TEXT* aText );
307
315
317
326 int parseBoardUnits();
327
328 int parseBoardUnits( const char* aExpected );
329
330 inline int parseBoardUnits( PCB_KEYS_T::T aToken )
331 {
332 return parseBoardUnits( GetTokenText( aToken ) );
333 }
334
335 inline int parseInt()
336 {
337 return (int)strtol( CurText(), nullptr, 10 );
338 }
339
340 inline int parseInt( const char* aExpected )
341 {
342 NeedNUMBER( aExpected );
343 return parseInt();
344 }
345
346 inline long parseHex()
347 {
348 NextTok();
349 return strtol( CurText(), nullptr, 16 );
350 }
351
352 bool parseBool();
353
364 bool parseMaybeAbsentBool( bool aDefaultValue );
365
366 /*
367 * @return if m_appendToExisting, returns new KIID(), otherwise returns CurStr() as KIID.
368 */
370
375 void resolveGroups( BOARD_ITEM* aParent );
376
377 typedef std::unordered_map< std::string, PCB_LAYER_ID > LAYER_ID_MAP;
378 typedef std::unordered_map< std::string, LSET > LSET_MAP;
379 typedef std::unordered_map< wxString, KIID > KIID_MAP;
380
382 using TIMEOUT = std::chrono::milliseconds;
383
385 using CLOCK = std::chrono::steady_clock;
386
388 using TIME_PT = std::chrono::time_point<CLOCK>;
389
393 std::set<wxString> m_undefinedLayers;
394 std::vector<int> m_netCodes;
399
402
405
408 unsigned m_lineCount;
409
410 std::map<EDA_TEXT*, std::tuple<wxString, bool, bool>> m_fontTextMap;
411
412 std::vector<GROUP_INFO> m_groupInfos;
413 std::vector<GENERATOR_INFO> m_generatorInfos;
414
415 std::function<bool( wxString aTitle, int aIcon, wxString aMsg, wxString aAction )> m_queryUserCallback;
416};
417
418
419#endif // _PCBNEW_PARSER_H_
Container for design settings for a BOARD object.
Abstract interface for BOARD_ITEMs capable of storing other items inside.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:79
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:289
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:79
Definition: kiid.h:49
An abstract class from which implementation specific LINE_READERs may be derived to read single lines...
Definition: richio.h:93
LSET is a set of PCB_LAYER_IDs.
Definition: lset.h:35
Definition: pad.h:54
Abstract dimension API.
A set of BOARD_ITEMs (i.e., without duplicates).
Definition: pcb_group.h:52
Read a Pcbnew s-expression formatted LINE_READER object and returns the appropriate BOARD_ITEM object...
wxString m_generatorVersion
Set to the generator version this board requires.
PCB_TABLECELL * parsePCB_TABLECELL(BOARD_ITEM *aParent)
std::unordered_map< std::string, PCB_LAYER_ID > LAYER_ID_MAP
std::vector< int > m_netCodes
net codes mapping for boards being loaded
void parseOutlinePoints(SHAPE_LINE_CHAIN &aPoly)
Parses possible outline points and stores them into aPoly.
std::set< wxString > m_undefinedLayers
set of layers not defined in layers section
PROGRESS_REPORTER * m_progressReporter
optional; may be nullptr
void createOldLayerMapping(std::unordered_map< std::string, std::string > &aMap)
Create a mapping from the (short-lived) bug where layer names were translated.
std::unordered_map< std::string, LSET > LSET_MAP
void parseEDA_TEXT(EDA_TEXT *aText)
Parse the common settings for any object derived from EDA_TEXT.
int parseInt(const char *aExpected)
bool m_tooRecent
true if version parses as later than supported
void parsePCB_TEXT_effects(PCB_TEXT *aText)
PCB_REFERENCE_IMAGE * parsePCB_REFERENCE_IMAGE(BOARD_ITEM *aParent)
LAYER_ID_MAP m_layerIndices
map layer name to it's index
void parseTextBoxContent(PCB_TEXTBOX *aTextBox)
FOOTPRINT * parseFOOTPRINT(wxArrayString *aInitialComments=nullptr)
void pushValueIntoMap(int aIndex, int aValue)
Add aValue value in netcode mapping (m_netCodes) at aIndex.
std::chrono::steady_clock CLOCK
The type of the time stamps.
void init()
Clear and re-establish m_layerMap with the default layer names.
void parseGROUP(BOARD_ITEM *aParent)
std::map< EDA_TEXT *, std::tuple< wxString, bool, bool > > m_fontTextMap
void skipCurrent()
Skip the current token level, i.e search for the RIGHT parenthesis which closes the current descripti...
void parseMargins(int &aLeft, int &aTop, int &aRight, int &aBottom)
PCB_LAYER_ID parseBoardItemLayer()
Parse the layer definition of a BOARD_ITEM object.
void parseGENERATOR(BOARD_ITEM *aParent)
T lookUpLayer(const M &aMap)
Parse the current token for the layer definition of a BOARD_ITEM object.
std::chrono::milliseconds TIMEOUT
The clock used for the timestamp (guaranteed to be monotonic).
LSET parseBoardItemLayersAsMask()
Parse the layers definition of a BOARD_ITEM object.
void resolveGroups(BOARD_ITEM *aParent)
Called after parsing a footprint definition or board to build the group membership lists.
void parseDefaultTextDims(BOARD_DESIGN_SETTINGS &aSettings, int aLayer)
std::vector< GROUP_INFO > m_groupInfos
ZONE * parseZONE(BOARD_ITEM_CONTAINER *aParent)
PCB_TABLE * parsePCB_TABLE(BOARD_ITEM *aParent)
std::vector< GENERATOR_INFO > m_generatorInfos
int parseBoardUnits(PCB_KEYS_T::T aToken)
PCB_TEXTBOX * parsePCB_TEXTBOX(BOARD_ITEM *aParent)
PCB_TEXT * parsePCB_TEXT(BOARD_ITEM *aParent)
std::chrono::time_point< CLOCK > TIME_PT
unsigned m_lineCount
for progress reporting
VECTOR2I parseXY()
Parse a coordinate pair (xy X Y) in board units (mm).
void parseTEARDROP_PARAMETERS(TEARDROP_PARAMETERS *tdParams)
int m_requiredVersion
set to the KiCad format version this board requires
PAD * parsePAD(FOOTPRINT *aParent=nullptr)
std::function< bool(wxString aTitle, int aIcon, wxString aMsg, wxString aAction)> m_queryUserCallback
FOOTPRINT * parseFOOTPRINT_unchecked(wxArrayString *aInitialComments=nullptr)
void parseRenderCache(EDA_TEXT *text)
Parse the render cache for any object derived from EDA_TEXT.
TIME_PT m_lastProgressTime
for progress reporting
void parseGROUP_members(GROUP_INFO &aGroupInfo)
bool IsTooRecent()
Return whether a version number, if any was parsed, was too recent.
bool IsValidBoardHeader()
Partially parse the input and check if it matches expected header.
std::pair< wxString, wxString > parseBoardProperty()
LSET_MAP m_layerMasks
map layer names to their masks
bool parseMaybeAbsentBool(bool aDefaultValue)
Parses a boolean flag inside a list that existed before boolean normalization.
int parseBoardUnits()
Parse the current token as an ASCII numeric string with possible leading whitespace into a double pre...
std::unordered_map< wxString, KIID > KIID_MAP
The type of progress bar timeout.
PCB_DIMENSION_BASE * parseDIMENSION(BOARD_ITEM *aParent)
PCB_IO_KICAD_SEXPR_PARSER(LINE_READER *aReader, BOARD *aAppendToMe, std::function< bool(wxString, int, wxString, wxString)> aQueryUserCallback, PROGRESS_REPORTER *aProgressReporter=nullptr, unsigned aLineCount=0)
bool m_appendToExisting
reading into an existing board; reset UUIDs
PCB_SHAPE * parsePCB_SHAPE(BOARD_ITEM *aParent)
void parseDefaults(BOARD_DESIGN_SETTINGS &aSettings)
wxString GetRequiredVersion()
Return a string representing the version of KiCad required to open this file.
Object to handle a bitmap image that can be inserted in a PCB.
A progress reporter interface for use in multi-threaded environments.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
A name/value tuple with unique names and wxAny values.
TEARDROP_PARAMETARS is a helper class to handle parameters needed to build teardrops for a board thes...
Handle a list of polygons defining a copper zone.
Definition: zone.h:73
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
STL namespace.
Container to hold information pertinent to a layer of a BOARD.
Definition: board.h:168
Convert net code using the mapping table if available, otherwise returns unchanged net code if < 0 or...