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