KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sexpr.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2016 Mark Roszko <[email protected]>
3 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include "sexpr/sexpr.h"
20#include <cctype>
21#include <iterator>
22#include <stdexcept>
23#include <iomanip>
24#include <sstream>
25#include <wx/debug.h>
26
27namespace SEXPR
28{
29 SEXPR::SEXPR( SEXPR_TYPE aType, size_t aLineNumber ) :
30 m_type( aType ), m_lineNumber( aLineNumber )
31 {
32 }
33
35 m_type( aType ), m_lineNumber( 1 )
36 {
37 }
38
40 {
41 if( m_type != SEXPR_TYPE::SEXPR_TYPE_LIST )
42 {
43 throw INVALID_TYPE_EXCEPTION("SEXPR is not a list type!");
44 }
45
46 return &static_cast< SEXPR_LIST const * >(this)->m_children;
47 }
48
49 SEXPR* SEXPR::GetChild( size_t aIndex ) const
50 {
51 if( m_type != SEXPR_TYPE::SEXPR_TYPE_LIST )
52 {
53 throw INVALID_TYPE_EXCEPTION("SEXPR is not a list type!");
54 }
55
56 return static_cast< SEXPR_LIST const * >(this)->m_children[aIndex];
57 }
58
59 void SEXPR::AddChild( SEXPR* aChild )
60 {
61 if( m_type != SEXPR_TYPE::SEXPR_TYPE_LIST )
62 {
63 throw INVALID_TYPE_EXCEPTION("SEXPR is not a list type!");
64 }
65
66 SEXPR_LIST* list = static_cast< SEXPR_LIST * >( this );
67
68 list->m_children.push_back( aChild );
69 }
70
72 {
73 if( m_type != SEXPR_TYPE::SEXPR_TYPE_LIST )
74 {
75 throw INVALID_TYPE_EXCEPTION("SEXPR is not a list type!");
76 }
77
78 return static_cast< SEXPR_LIST const * >(this)->m_children.size();
79 }
80
81 std::string const & SEXPR::GetString() const
82 {
84 {
85 throw INVALID_TYPE_EXCEPTION("SEXPR is not a string type!");
86 }
87
88 return static_cast< SEXPR_STRING const * >(this)->m_value;
89 }
90
91 int32_t SEXPR::GetInteger() const
92 {
93 return static_cast< int >( GetLongInteger() );
94 }
95
96 int64_t SEXPR::GetLongInteger() const
97 {
99 {
100 throw INVALID_TYPE_EXCEPTION("SEXPR is not a integer type!");
101 }
102
103 return static_cast< SEXPR_INTEGER const * >(this)->m_value;
104 }
105
106 double SEXPR::GetDouble() const
107 {
108 // we may end up parsing "intended" floats/doubles as ints
109 // so here we allow silent casting back to doubles
111 {
112 return static_cast< SEXPR_DOUBLE const * >(this)->m_value;
113 }
114 else if( m_type == SEXPR_TYPE::SEXPR_TYPE_ATOM_INTEGER )
115 {
116 return static_cast< SEXPR_INTEGER const * >(this)->m_value;
117 }
118 else
119 {
120 throw INVALID_TYPE_EXCEPTION("SEXPR is not a double type!");
121 }
122 }
123
124 float SEXPR::GetFloat() const
125 {
126 return static_cast< float >( GetDouble() );
127 }
128
129 std::string const & SEXPR::GetSymbol() const
130 {
132 {
133 std::string err_msg( "GetSymbol(): SEXPR is not a symbol type! error line ");
134 err_msg += std::to_string( GetLineNumber() );
135 throw INVALID_TYPE_EXCEPTION( err_msg );
136 }
137
138 return static_cast< SEXPR_SYMBOL const * >(this)->m_value;
139 }
140
141
143 {
144 if( m_type != SEXPR_TYPE::SEXPR_TYPE_LIST )
145 {
146 throw INVALID_TYPE_EXCEPTION("SEXPR is not a list type!");
147 }
148
149 return static_cast< SEXPR_LIST* >(this);
150 }
151
152 std::string SEXPR::AsString( size_t aLevel ) const
153 {
154 std::string result;
155
156 if( IsList() )
157 {
158 if( aLevel != 0 )
159 {
160 result = "\n";
161 }
162
163 result.append( aLevel * 2, ' ' );
164 aLevel++;
165 result += "(";
166
167 SEXPR_VECTOR const* list = GetChildren();
168
169 for( std::vector<SEXPR *>::const_iterator it = list->begin(); it != list->end(); ++it )
170 {
171 result += (*it)->AsString( aLevel );
172
173 if( it != list->end() - 1 )
174 {
175 result += " ";
176 }
177 }
178 result += ")";
179
180 aLevel--;
181 }
182 else if( IsString() )
183 {
184 result += "\"" + GetString() + "\"";
185 }
186 else if( IsSymbol() )
187 {
188 result += GetSymbol();
189 }
190 else if( IsInteger() )
191 {
192 std::stringstream out;
193 out << GetInteger();
194 result += out.str();
195 }
196 else if( IsDouble() )
197 {
198 std::stringstream out;
199 out << std::setprecision( 16 ) << GetDouble();
200 result += out.str();
201 }
202
203 return result;
204 }
205
207 {
208 for( auto child : m_children )
209 {
210 delete child;
211 }
212
213 m_children.clear();
214 }
215
216 SEXPR_LIST& operator<< ( SEXPR_LIST& list, const ISEXPRABLE& obj )
217 {
218 SEXPR* sobj = obj.SerializeSEXPR();
219 list.AddChild( sobj );
220
221 return list;
222 }
223
224 SEXPR_LIST& operator<< ( SEXPR_LIST& list, int64_t value )
225 {
226 list.AddChild( new SEXPR_INTEGER( value ) );
227 return list;
228 }
229
230 SEXPR_LIST& operator<< ( SEXPR_LIST& list, int32_t value )
231 {
232 list.AddChild( new SEXPR_INTEGER( value ) );
233 return list;
234 }
235
236 SEXPR_LIST& operator<< ( SEXPR_LIST& list, float value )
237 {
238 list.AddChild( new SEXPR_DOUBLE( value ) );
239 return list;
240 }
241
242 SEXPR_LIST& operator<< ( SEXPR_LIST& list, double value )
243 {
244 list.AddChild( new SEXPR_DOUBLE( value ) );
245 return list;
246 }
247
248 SEXPR_LIST& operator<< ( SEXPR_LIST& list, std::string value )
249 {
250 list.AddChild( new SEXPR_STRING( value ) );
251 return list;
252 }
253
254 SEXPR_LIST& operator<< ( SEXPR_LIST& list, SEXPR* obj )
255 {
256 list.AddChild( obj );
257 return list;
258 }
259
260 SEXPR_LIST& operator<< ( SEXPR_LIST& list, const _OUT_STRING setting )
261 {
262 SEXPR *res;
263
264 if( setting._Symbol )
265 {
266 res = new SEXPR_SYMBOL( setting._String );
267 }
268 else
269 {
270 res = new SEXPR_STRING( setting._String );
271 }
272
273 list.AddChild( res );
274
275 return list;
276 }
277
279 {
280 obj.DeserializeSEXPR( input );
281
282 return input;
283 }
284
285 SEXPR_LIST& operator>> ( SEXPR_LIST& input, int32_t& inte )
286 {
287 SEXPR* child = input.GetChild( input.m_inStreamChild );
288
289 if( child->IsInteger() )
290 {
291 inte = child->GetInteger();
292 input.m_inStreamChild++;
293 }
294 else
295 {
296 throw std::invalid_argument( "SEXPR is not a integer type!" );
297 }
298
299 return input;
300 }
301
302 SEXPR_LIST& operator>> ( SEXPR_LIST& input, std::string& str )
303 {
304 SEXPR* child = input.GetChild( input.m_inStreamChild );
305
306 if( child->IsString() || child->IsSymbol() )
307 {
308 str = child->GetString();
309 input.m_inStreamChild++;
310 }
311 else
312 {
313 throw std::invalid_argument( "SEXPR is not a string type!" );
314 }
315
316 return input;
317 }
318
319 SEXPR_LIST& operator>> ( SEXPR_LIST& input, int64_t& lint )
320 {
321 SEXPR* child = input.GetChild( input.m_inStreamChild );
322
323 if( child->IsInteger() )
324 {
325 lint = child->GetLongInteger();
326 input.m_inStreamChild++;
327 }
328 else
329 {
330 throw std::invalid_argument("SEXPR is not a long integer type!");
331 }
332
333 return input;
334 }
335
336 SEXPR_LIST& operator>> ( SEXPR_LIST& input, float& fl )
337 {
338 SEXPR* child = input.GetChild( input.m_inStreamChild );
339 if( child->IsDouble() )
340 {
341 fl = child->GetFloat();
342 input.m_inStreamChild++;
343 }
344 else
345 {
346 throw std::invalid_argument( "SEXPR is not a float type!" );
347 }
348
349 return input;
350 }
351
352 SEXPR_LIST& operator>> ( SEXPR_LIST& input, double& dbl )
353 {
354 SEXPR* child = input.GetChild( input.m_inStreamChild );
355
356 if( child->IsDouble() )
357 {
358 dbl = child->GetDouble();
359 input.m_inStreamChild++;
360 }
361 else
362 {
363 throw std::invalid_argument( "SEXPR is not a double type!" );
364 }
365
366 return input;
367 }
368
370 {
371 SEXPR* child = input.GetChild( input.m_inStreamChild );
372
373 if( is._Symbol )
374 {
375 if( child->IsSymbol() )
376 {
377 is._String = child->GetSymbol();
378 input.m_inStreamChild++;
379 }
380 else
381 {
382 throw std::invalid_argument( "operator>>: SEXPR is not a symbol type!" );
383 }
384 }
385 else
386 {
387 if( child->IsString() )
388 {
389 is._String = child->GetString();
390 input.m_inStreamChild++;
391 }
392 else
393 {
394 throw std::invalid_argument( "SEXPR is not a string type!" );
395 }
396 }
397
398 return input;
399 }
400
401 SEXPR_LIST& operator<< ( SEXPR_LIST& list, SEXPR_LIST* list2 )
402 {
403 list.AddChild( list2 );
404
405 return list;
406 }
407
408 size_t SEXPR_LIST::doScan( const SEXPR_SCAN_ARG *args, size_t num_args )
409 {
410 size_t i = 0;
411
412 for( i = 0; i < num_args; i++ )
413 {
414 SEXPR* child = GetChild( i );
415 const SEXPR_SCAN_ARG& arg = args[i];
416
417 try
418 {
420 {
421 *arg.u.dbl_value = child->GetDouble();
422 }
423 else if( arg.type == SEXPR_SCAN_ARG::Type::INT )
424 {
425 *arg.u.dbl_value = child->GetInteger();
426 }
427 else if( arg.type == SEXPR_SCAN_ARG::Type::STRING )
428 {
429 if( child->IsSymbol() )
430 {
431 *arg.u.str_value = child->GetSymbol();
432 }
433 else if( child->IsString() )
434 {
435 *arg.u.str_value = child->GetString();
436 }
437 }
438 else if( arg.type == SEXPR_SCAN_ARG::Type::LONGINT )
439 {
440 *arg.u.lint_value = child->GetLongInteger();
441 }
443 {
444 if( arg.u.sexpr_str->_Symbol )
445 {
446 arg.u.sexpr_str->_String = child->GetSymbol();
447 }
448 else
449 {
450 arg.u.sexpr_str->_String = child->GetString();
451 }
452
453 }
455 {
456 if( child->IsSymbol() )
457 {
458 if( child->GetSymbol() != arg.str_value )
459 {
460 return i;
461 }
462 }
463 else if( child->IsString() )
464 {
465 if( child->GetString() != arg.str_value )
466 {
467 return i;
468 }
469 }
470 }
471 else
472 {
473 throw std::invalid_argument( "unsupported argument type, this shouldn't have happened" );
474 }
475 }
476 catch( const INVALID_TYPE_EXCEPTION& )
477 {
478 return i;
479 }
480 }
481
482 return i;
483 }
484
485 void SEXPR_LIST::doAddChildren( const SEXPR_CHILDREN_ARG *args, size_t num_args )
486 {
487 size_t i = 0;
488
489 for( i = 0; i < num_args; i++ )
490 {
491 const SEXPR_CHILDREN_ARG& arg = args[i];
492
494 {
495 AddChild( new SEXPR_DOUBLE( arg.u.dbl_value ) );
496 }
497 else if( arg.type == SEXPR_CHILDREN_ARG::Type::INT )
498 {
499 AddChild( new SEXPR_INTEGER( arg.u.int_value ) );
500 }
502 {
503 AddChild( new SEXPR_INTEGER( arg.u.lint_value ) );
504 }
505 else if( arg.type == SEXPR_CHILDREN_ARG::Type::STRING )
506 {
507 AddChild( new SEXPR_STRING( arg.str_value ) );
508 }
510 {
511 AddChild( arg.u.sexpr_ptr );
512 }
514 {
515 if( arg.u.symbol )
516 {
517 AddChild( new SEXPR_SYMBOL( arg.str_value ) );
518 }
519 else
520 {
521 AddChild( new SEXPR_STRING( arg.str_value ) );
522 }
523 }
524 else
525 {
526 throw std::invalid_argument( "unexpected argument type, this shouldn't have happened" );
527 }
528 }
529 }
530}
virtual void DeserializeSEXPR(SEXPR &sexp)
Definition: isexprable.h:33
virtual SEXPR * SerializeSEXPR() const
Definition: isexprable.h:32
union SEXPR::SEXPR_CHILDREN_ARG::@43 u
std::string str_value
Definition: sexpr.h:239
int m_inStreamChild
Definition: sexpr.h:293
void doAddChildren(const SEXPR_CHILDREN_ARG *args, size_t num_args)
Definition: sexpr.cpp:485
virtual ~SEXPR_LIST()
Definition: sexpr.cpp:206
size_t doScan(const SEXPR_SCAN_ARG *args, size_t num_args)
Definition: sexpr.cpp:408
SEXPR_VECTOR m_children
Definition: sexpr.h:257
double * dbl_value
Definition: sexpr.h:192
union SEXPR::SEXPR_SCAN_ARG::@42 u
_IN_STRING * sexpr_str
Definition: sexpr.h:194
std::string * str_value
Definition: sexpr.h:193
int64_t * lint_value
Definition: sexpr.h:190
SEXPR_VECTOR const * GetChildren() const
Definition: sexpr.cpp:39
void AddChild(SEXPR *aChild)
Definition: sexpr.cpp:59
std::string const & GetSymbol() const
Definition: sexpr.cpp:129
std::string AsString(size_t aLevel=0) const
Definition: sexpr.cpp:152
int32_t GetInteger() const
Definition: sexpr.cpp:91
size_t GetNumberOfChildren() const
Definition: sexpr.cpp:71
float GetFloat() const
Definition: sexpr.cpp:124
int64_t GetLongInteger() const
Definition: sexpr.cpp:96
std::string const & GetString() const
Definition: sexpr.cpp:81
SEXPR * GetChild(size_t aIndex) const
Definition: sexpr.cpp:49
double GetDouble() const
Definition: sexpr.cpp:106
SEXPR_LIST * GetList()
Definition: sexpr.cpp:142
SEXPR_LIST & operator>>(SEXPR_LIST &input, ISEXPRABLE &obj)
Definition: sexpr.cpp:278
std::vector< class SEXPR * > SEXPR_VECTOR
Definition: sexpr.h:43
SEXPR_TYPE
Definition: sexpr.h:35
std::string & _String
Definition: sexpr.h:140
const std::string & _String
Definition: sexpr.h:122
VECTOR3I res