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 
26 namespace 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
109  if( m_type == SEXPR_TYPE::SEXPR_TYPE_ATOM_DOUBLE )
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  {
130  if( m_type != SEXPR_TYPE::SEXPR_TYPE_ATOM_SYMBOL )
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 
259  SEXPR_LIST& operator<< ( SEXPR_LIST& list, const _OUT_STRING setting )
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  }
441  else if( arg.type == SEXPR_SCAN_ARG::Type::SEXPR_STRING )
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  }
453  else if( arg.type == SEXPR_SCAN_ARG::Type::STRING_COMP )
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  }
500  else if( arg.type == SEXPR_CHILDREN_ARG::Type::LONGINT )
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 }
std::vector< class SEXPR * > SEXPR_VECTOR
Definition: sexpr.h:43
SEXPR_LIST & operator>>(SEXPR_LIST &input, ISEXPRABLE &obj)
Definition: sexpr.cpp:277
union SEXPR::SEXPR_CHILDREN_ARG::@36 u
double * dbl_value
Definition: sexpr.h:192
SEXPR_LIST & operator<<(SEXPR_LIST &list, const ISEXPRABLE &obj)
Definition: sexpr.cpp:215
size_t doScan(const SEXPR_SCAN_ARG *args, size_t num_args)
Definition: sexpr.cpp:407
const std::string & _String
Definition: sexpr.h:122
SEXPR_VECTOR m_children
Definition: sexpr.h:255
int m_inStreamChild
Definition: sexpr.h:293
void doAddChildren(const SEXPR_CHILDREN_ARG *args, size_t num_args)
Definition: sexpr.cpp:484
void AddChild(SEXPR *aChild)
Definition: sexpr.cpp:58
SEXPR * GetChild(size_t aIndex) const
Definition: sexpr.cpp:48
virtual SEXPR * SerializeSEXPR() const
Definition: isexprable.h:32
virtual ~SEXPR_LIST()
Definition: sexpr.cpp:205
_OUT_STRING AsString(const std::string &aString)
Definition: sexpr.h:131
std::string str_value
Definition: sexpr.h:239
SEXPR_TYPE
Definition: sexpr.h:34
virtual void DeserializeSEXPR(SEXPR &sexp)
Definition: isexprable.h:33
std::string & _String
Definition: sexpr.h:140
int64_t * lint_value
Definition: sexpr.h:190
std::string * str_value
Definition: sexpr.h:193
_IN_STRING * sexpr_str
Definition: sexpr.h:194
union SEXPR::SEXPR_SCAN_ARG::@35 u