varconf  1.0.3
Configuration library for the Worldforge system.
variable.cpp
1 /*
2  * variable.cpp - implementation of the typeless value container.
3  * Copyright (C) 2001, Stefanus Du Toit, Joseph Zupko
4  * (C) 2003-2006 Alistair Riddoch
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  *
20  * Contact: Joseph Zupko
21  * jaz147@psu.edu
22  *
23  * 189 Reese St.
24  * Old Forge, PA 18518
25  */
26 
27 #include "variable.h"
28 
29 #include <string>
30 #include <cstdlib>
31 #include <utility>
32 
33 namespace varconf {
34 
35 VarBase::VarBase()
36  : m_have_bool(false), m_have_int(false), m_have_double(false),
37  m_have_string(false), m_val_bool(false), m_val_int(0), m_val_double(0.0),
38  m_val(""), m_scope(GLOBAL)
39 {
40 }
41 
42 VarBase::VarBase(const VarBase& c)
43  : sigc::trackable(c), m_have_bool(c.m_have_bool), m_have_int(c.m_have_int),
44  m_have_double(c.m_have_double), m_have_string(c.m_have_string),
45  m_val_bool(c.m_val_bool), m_val_int(c.m_val_int),
46  m_val_double(c.m_val_double), m_val(c.m_val), m_scope(GLOBAL)
47 {
48 }
49 
50 VarBase::VarBase(bool b)
51  : m_have_bool(true), m_have_int(false), m_have_double(false),
52  m_have_string(true), m_val_bool(b), m_val_int(0), m_val_double(0.0),
53  m_scope(GLOBAL)
54 {
55  m_val = (b ? "true" : "false");
56 }
57 
58 VarBase::VarBase(int i)
59  : m_have_bool(false), m_have_int(true), m_have_double(false),
60  m_have_string(true), m_val_bool(false), m_val_int(i), m_val_double(0.0),
61  m_val(std::to_string(i)), m_scope(GLOBAL)
62 {
63 }
64 
65 VarBase::VarBase(double d)
66  : m_have_bool(false), m_have_int(false), m_have_double(true),
67  m_have_string(true), m_val_bool(false), m_val_int(0), m_val_double(d),
68  m_val(std::to_string(d)), m_scope(GLOBAL)
69 {
70 }
71 
72 VarBase::VarBase(std::string s)
73  : m_have_bool(false), m_have_int(false), m_have_double(false),
74  m_have_string(true), m_val_bool(false), m_val_int(0), m_val_double(0.0),
75  m_val(std::move(s)), m_scope(GLOBAL)
76 {
77 }
78 
79 VarBase::VarBase(const char* s)
80  : m_have_bool(false), m_have_int(false), m_have_double(false),
81  m_have_string(true), m_val_bool(false), m_val_int(0), m_val_double(0.0),
82  m_val(s), m_scope(GLOBAL)
83 {
84 }
85 
86 VarBase::~VarBase() = default;
87 
88 std::ostream& operator<<( std::ostream& out, const VarBase& v)
89 {
90  for (char i : v.m_val) {
91  if (i == '"' || i == '\\') {
92  out << '\\';
93  }
94  out << i;
95  }
96  return out;
97 }
98 
99 bool operator ==( const VarBase& one, const VarBase& two)
100 {
101  return one.m_val == two.m_val;
102  // scope is explicitly excluded as its nothing to do with value comparisons
103 
104 }
105 
106 bool operator !=(const VarBase& one, const VarBase& two)
107 {
108  return !(one == two);
109 }
110 
111 VarBase& VarBase::operator=(const VarBase& c)
112 {
113  if (&c == this) return (*this);
114  m_have_bool = c.m_have_bool; m_have_int = c.m_have_int;
115  m_have_double = c.m_have_double; m_have_string = c.m_have_string;
116  m_val_bool = c.m_val_bool; m_val_int = c.m_val_int;
117  m_val_double = c.m_val_double; m_val = c.m_val;
118  m_scope = c.m_scope;
119  return (*this);
120 }
121 
122 VarBase& VarBase::operator=(bool b)
123 {
124  m_have_bool = true; m_have_int = false;
125  m_have_double = false; m_have_string = true;
126  m_val_bool = b; m_val_int = 0;
127  m_val_double = 0.0; m_val = (b ? "true" : "false");
128  m_scope = INSTANCE;
129  return (*this);
130 }
131 
132 VarBase& VarBase::operator=(int i)
133 {
134  m_have_bool = false; m_have_int = true;
135  m_have_double = false; m_have_string = true;
136  m_val_bool = false; m_val_int = i;
137  m_val_double = 0.0;
138  m_val = std::to_string(i);
139  m_scope = INSTANCE;
140  return (*this);
141 }
142 
143 VarBase& VarBase::operator=(double d)
144 {
145  m_have_bool = false; m_have_int = false;
146  m_have_double = true; m_have_string = true;
147  m_val_bool = false; m_val_int = 0;
148  m_val_double = d;
149  m_val = std::to_string(d);
150  m_scope = INSTANCE;
151  return (*this);
152 }
153 
154 VarBase& VarBase::operator=(const std::string& s)
155 {
156  m_have_bool = false; m_have_int = false;
157  m_have_double = false; m_have_string = true;
158  m_val_bool = false; m_val_int = 0;
159  m_val_double = 0.0; m_val = s;
160  m_scope = INSTANCE;
161  return (*this);
162 }
163 
164 VarBase& VarBase::operator=(const char* s)
165 {
166  m_have_bool = false; m_have_int = false;
167  m_have_double = false; m_have_string = true;
168  m_val_bool = false; m_val_int = 0;
169  m_val_double = 0.0; m_val = s;
170  m_scope = INSTANCE;
171  return (*this);
172 }
173 
174 VarBase::operator bool() const
175 {
176  if (!m_have_bool) {
177  m_val_bool = (m_val == "on") ||
178  (m_val == "1") ||
179  (m_val == "true") ||
180  (m_val =="yes") ||
181  (m_val == "y");
182  m_have_bool = true;
183  }
184  return m_val_bool;
185 }
186 
187 VarBase::operator int() const
188 {
189  if (!m_have_int) {
190  m_val_int = atoi(m_val.c_str());
191  m_have_int = true;
192  }
193  return m_val_int;
194 }
195 
196 VarBase::operator double() const
197 {
198  if (!m_have_double) {
199  m_val_double = atof(m_val.c_str());
200  m_have_double = true;
201  }
202  return m_val_double;
203 }
204 
205 VarBase::operator std::string() const
206 {
207  return m_val;
208 }
209 
210 bool VarBase::is_bool()
211 {
212  if (!is_string()) return false;
213  return (m_val == "on") || (m_val == "off")
214  || (m_val == "1") || (m_val == "0")
215  || (m_val == "true") || (m_val == "false")
216  || (m_val == "yes") || (m_val == "no")
217  || (m_val == "y") || (m_val == "n");
218 }
219 
220 bool VarBase::is_int()
221 {
222  if (!is_string()) return false;
223  for (char i : m_val) if (!isdigit(i))
224  return false;
225  return true;
226 }
227 
228 bool VarBase::is_double()
229 {
230  if (!is_string()) return false;
231 
232  char* p;
233 
234  // strtod() points p to the first character
235  // in the string that doesn't look like
236  // part of a double
237  strtod(m_val.c_str(), &p); //-V530
238 
239  return p == m_val.c_str() + m_val.size();
240 }
241 
242 bool VarBase::is_string()
243 {
244  return m_have_string;
245 }
246 
247 Variable::Variable (const Variable& c) : VarPtr(c.is_array()
248  ? VarPtr(new VarArray(*(c.array()))) : static_cast<const VarPtr&>(c))
249 {
250 
251 }
252 
253 Variable::Variable( const int n, const Variable& v)
254  : VarPtr(new VarArray(n, v))
255 {
256 
257 }
258 
259 Variable::Variable( const VarList& v) : VarPtr(new VarArray(v))
260 {
261 
262 }
263 
264 Variable::~Variable() = default;
265 
266 Variable& Variable::operator=( const Variable& c)
267 {
268  VarList *array_val = c.array();
269 
270  if(array_val) // Equivalent to c.is_array()
271  VarPtr::operator=(new VarArray(*array_val));
272  else
273  VarPtr::operator=(c);
274  return *this;
275 }
276 
277 Variable& Variable::operator=( VarBase* vb)
278 {
279  VarPtr::operator=(vb);
280  return *this;
281 }
282 
283 Variable& Variable::operator=( const bool b)
284 {
285  VarPtr::operator=(new VarBase(b));
286  return *this;
287 }
288 
289 Variable& Variable::operator=( const int i)
290 {
291  VarPtr::operator=(new VarBase(i));
292  return *this;
293 }
294 
295 Variable& Variable::operator=( const double d)
296 {
297  VarPtr::operator=(new VarBase(d));
298  return *this;
299 }
300 
301 Variable& Variable::operator=( const std::string& s)
302 {
303  VarPtr::operator=(new VarBase(s));
304  return *this;
305 }
306 
307 Variable& Variable::operator=( const char* s)
308 {
309  VarPtr::operator=(new VarBase(s));
310  return *this;
311 }
312 
313 Variable& Variable::operator=( const VarList& v)
314 {
315  VarPtr::operator=(new VarArray(v));
316  return *this;
317 }
318 
319 Variable& Variable::operator[](const int i)
320 {
321  std::vector<Variable> *the_array = array();
322 
323  if(!the_array) {
324  auto *new_array = new VarArray(i + 1);
325  (*new_array)[0] = *this;
326  VarPtr::operator=(new_array);
327  the_array = new_array;
328  }
329  else if ((int)the_array->size() < i + 1)
330  the_array->resize(i + 1);
331 
332  return (*the_array)[i];
333 }
334 
335 
336 VarArray::~VarArray() = default;
337 
338 std::ostream& operator<<( std::ostream& out, const VarArray& v)
339 {
340  out << "(";
341 
342  auto i = v.begin();
343  while(true) {
344  out << *i;
345  if(++i == v.end())
346  break;
347  out << ",";
348  }
349 
350  out << ")";
351  return out;
352 }
353 
354 bool operator ==( const VarArray& one, const VarArray& two)
355 {
356  if(one.size() != two.size())
357  return false;
358 
359  VarArray::const_iterator i1, i2;
360 
361  for(i1 = one.begin(), i2 = two.begin(); i1 != one.end(); ++i1, ++i2)
362  if(i1->elem() != i2->elem())
363  return false;
364 
365  return true;
366 }
367 
368 VarArray::operator bool() const
369 {
370  return false;
371 }
372 
373 VarArray::operator int() const
374 {
375  return 0;
376 }
377 
378 VarArray::operator double() const
379 {
380  return 0;
381 }
382 
383 VarArray::operator std::string() const
384 {
385  return "";
386 }
387 
388 
389 bool VarArray::is_bool()
390 {
391  return false;
392 }
393 
394 bool VarArray::is_int()
395 {
396  return false;
397 }
398 
399 bool VarArray::is_double()
400 {
401  return false;
402 }
403 
404 bool VarArray::is_string()
405 {
406  return false;
407 }
408 
409 } // namespace varconf
STL namespace.