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