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
33namespace varconf {
34
35VarBase::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
42VarBase::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
50VarBase::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
58VarBase::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
65VarBase::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
72VarBase::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
79VarBase::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
86VarBase::~VarBase() = default;
87
88std::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
99bool 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
106bool operator !=(const VarBase& one, const VarBase& two)
107{
108 return !(one == two);
109}
110
111VarBase& 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
122VarBase& 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
132VarBase& 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
143VarBase& 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
154VarBase& 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
164VarBase& 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
174VarBase::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
187VarBase::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
196VarBase::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
205VarBase::operator std::string() const
206{
207 return m_val;
208}
209
210bool 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
220bool 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
228bool 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
242bool VarBase::is_string()
243{
244 return m_have_string;
245}
246
247Variable::Variable (const Variable& c) : VarPtr(c.is_array()
248 ? VarPtr(new VarArray(*(c.array()))) : static_cast<const VarPtr&>(c))
249{
250
251}
252
253Variable::Variable( const int n, const Variable& v)
254 : VarPtr(new VarArray(n, v))
255{
256
257}
258
259Variable::Variable( const VarList& v) : VarPtr(new VarArray(v))
260{
261
262}
263
264Variable::~Variable() = default;
265
266Variable& 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
277Variable& Variable::operator=( VarBase* vb)
278{
279 VarPtr::operator=(vb);
280 return *this;
281}
282
283Variable& Variable::operator=( const bool b)
284{
285 VarPtr::operator=(new VarBase(b));
286 return *this;
287}
288
289Variable& Variable::operator=( const int i)
290{
291 VarPtr::operator=(new VarBase(i));
292 return *this;
293}
294
295Variable& Variable::operator=( const double d)
296{
297 VarPtr::operator=(new VarBase(d));
298 return *this;
299}
300
301Variable& Variable::operator=( const std::string& s)
302{
303 VarPtr::operator=(new VarBase(s));
304 return *this;
305}
306
307Variable& Variable::operator=( const char* s)
308{
309 VarPtr::operator=(new VarBase(s));
310 return *this;
311}
312
313Variable& Variable::operator=( const VarList& v)
314{
315 VarPtr::operator=(new VarArray(v));
316 return *this;
317}
318
319Variable& 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
336VarArray::~VarArray() = default;
337
338std::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
354bool 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
368VarArray::operator bool() const
369{
370 return false;
371}
372
373VarArray::operator int() const
374{
375 return 0;
376}
377
378VarArray::operator double() const
379{
380 return 0;
381}
382
383VarArray::operator std::string() const
384{
385 return "";
386}
387
388
389bool VarArray::is_bool()
390{
391 return false;
392}
393
394bool VarArray::is_int()
395{
396 return false;
397}
398
399bool VarArray::is_double()
400{
401 return false;
402}
403
404bool VarArray::is_string()
405{
406 return false;
407}
408
409} // namespace varconf