• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* ----------------------------------------------------------------------------
2   libconfig - A library for processing structured configuration files
3   Copyright (C) 2005-2018  Mark A Lindner
4
5   This file is part of libconfig.
6
7   This library is free software; you can redistribute it and/or
8   modify it under the terms of the GNU Lesser General Public License
9   as published by the Free Software Foundation; either version 2.1 of
10   the License, or (at your option) any later version.
11
12   This library is distributed in the hope that it will be useful, but
13   WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15   Lesser General Public License for more details.
16
17   You should have received a copy of the GNU Library General Public
18   License along with this library; if not, see
19   <http://www.gnu.org/licenses/>.
20   ----------------------------------------------------------------------------
21*/
22
23#ifndef __libconfig_hpp
24#define __libconfig_hpp
25
26#include <stdio.h>
27#include <exception>
28#include <string>
29
30#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
31#if defined(LIBCONFIGXX_STATIC)
32#define LIBCONFIGXX_API
33#elif defined(LIBCONFIGXX_EXPORTS)
34#define LIBCONFIGXX_API __declspec(dllexport)
35#else /* ! LIBCONFIGXX_EXPORTS */
36#define LIBCONFIGXX_API __declspec(dllimport)
37#endif /* LIBCONFIGXX_STATIC */
38#else /* ! WIN32 */
39#define LIBCONFIGXX_API
40#endif /* WIN32 */
41
42#define LIBCONFIGXX_VER_MAJOR    1
43#define LIBCONFIGXX_VER_MINOR    7
44#define LIBCONFIGXX_VER_REVISION 0
45
46#if __cplusplus < 201103L
47#define LIBCONFIGXX_NOEXCEPT throw()
48#else
49#define LIBCONFIGXX_NOEXCEPT noexcept
50#endif
51
52struct config_t; // fwd decl
53struct config_setting_t; // fwd decl
54
55namespace libconfig {
56
57class LIBCONFIGXX_API ConfigException : public std::exception { };
58
59class Setting; // fwd decl
60class SettingIterator;
61class SettingConstIterator;
62
63class LIBCONFIGXX_API SettingException : public ConfigException
64{
65  public:
66
67  SettingException(const Setting &setting);
68  SettingException(const Setting &setting, int idx);
69  SettingException(const Setting &setting, const char *name);
70  SettingException(const char *path);
71
72  SettingException(const SettingException &other);
73  SettingException& operator=(const SettingException &other);
74
75  virtual ~SettingException() LIBCONFIGXX_NOEXCEPT;
76
77  const char *getPath() const;
78
79  virtual const char *what() const LIBCONFIGXX_NOEXCEPT;
80
81  private:
82
83  char *_path;
84};
85
86class LIBCONFIGXX_API SettingTypeException : public SettingException
87{
88  public:
89
90  SettingTypeException(const Setting &setting);
91  SettingTypeException(const Setting &setting, int idx);
92  SettingTypeException(const Setting &setting, const char *name);
93
94  virtual const char *what() const LIBCONFIGXX_NOEXCEPT;
95};
96
97class LIBCONFIGXX_API SettingNotFoundException : public SettingException
98{
99  public:
100
101  SettingNotFoundException(const char *path);
102  SettingNotFoundException(const Setting &setting, int idx);
103  SettingNotFoundException(const Setting &setting, const char *name);
104
105  virtual const char *what() const LIBCONFIGXX_NOEXCEPT;
106};
107
108class LIBCONFIGXX_API SettingNameException : public SettingException
109{
110  public:
111
112  SettingNameException(const Setting &setting, const char *name);
113
114  virtual const char *what() const LIBCONFIGXX_NOEXCEPT;
115};
116
117class LIBCONFIGXX_API FileIOException : public ConfigException
118{
119  public:
120
121  virtual const char *what() const LIBCONFIGXX_NOEXCEPT;
122};
123
124class LIBCONFIGXX_API ParseException : public ConfigException
125{
126  public:
127
128  ParseException(const char *file, int line, const char *error);
129
130  ParseException(const ParseException &other);
131
132  virtual ~ParseException() LIBCONFIGXX_NOEXCEPT;
133
134  inline const char *getFile() const
135  { return(_file); }
136
137  inline int getLine() const
138  { return(_line); }
139
140  inline const char *getError() const
141  { return(_error); }
142
143  virtual const char *what() const LIBCONFIGXX_NOEXCEPT;
144
145  private:
146
147  const char *_file;
148  int _line;
149  const char *_error;
150};
151
152class LIBCONFIGXX_API Setting
153{
154  friend class Config;
155
156  public:
157
158  enum Type
159  {
160    TypeNone = 0,
161    // scalar types
162    TypeInt,
163    TypeInt64,
164    TypeFloat,
165    TypeString,
166    TypeBoolean,
167    // aggregate types
168    TypeGroup,
169    TypeArray,
170    TypeList
171  };
172
173  enum Format
174  {
175    FormatDefault = 0,
176    FormatHex = 1
177  };
178
179  typedef SettingIterator iterator;
180  typedef SettingConstIterator const_iterator;
181
182  public:
183
184  virtual ~Setting();
185
186  inline Type getType() const { return(_type); }
187
188  inline Format getFormat() const { return(_format); }
189  void setFormat(Format format);
190
191  operator bool() const;
192  operator int() const;
193  operator unsigned int() const;
194  operator long() const;
195  operator unsigned long() const;
196  operator long long() const;
197  operator unsigned long long() const;
198  operator double() const;
199  operator float() const;
200  operator const char *() const;
201  operator std::string() const;
202
203  inline const char *c_str() const
204  { return operator const char *(); }
205
206  Setting & operator=(bool value);
207  Setting & operator=(int value);
208  Setting & operator=(long value);
209  Setting & operator=(const long long &value);
210  Setting & operator=(const double &value);
211  Setting & operator=(float value);
212  Setting & operator=(const char *value);
213  Setting & operator=(const std::string &value);
214
215  Setting & lookup(const char *path) const;
216  inline Setting & lookup(const std::string &path) const
217  { return(lookup(path.c_str())); }
218
219  Setting & operator[](const char *name) const;
220
221  inline Setting & operator[](const std::string &name) const
222  { return(operator[](name.c_str())); }
223
224  Setting & operator[](int index) const;
225
226  bool lookupValue(const char *name, bool &value) const;
227  bool lookupValue(const char *name, int &value) const;
228  bool lookupValue(const char *name, unsigned int &value) const;
229  bool lookupValue(const char *name, long long &value) const;
230  bool lookupValue(const char *name, unsigned long long &value) const;
231  bool lookupValue(const char *name, double &value) const;
232  bool lookupValue(const char *name, float &value) const;
233  bool lookupValue(const char *name, const char *&value) const;
234  bool lookupValue(const char *name, std::string &value) const;
235
236  inline bool lookupValue(const std::string &name, bool &value) const
237  { return(lookupValue(name.c_str(), value)); }
238
239  inline bool lookupValue(const std::string &name, int &value) const
240  { return(lookupValue(name.c_str(), value)); }
241
242  inline bool lookupValue(const std::string &name, unsigned int &value) const
243  { return(lookupValue(name.c_str(), value)); }
244
245  inline bool lookupValue(const std::string &name, long long &value) const
246  { return(lookupValue(name.c_str(), value)); }
247
248  inline bool lookupValue(const std::string &name,
249                          unsigned long long &value) const
250  { return(lookupValue(name.c_str(), value)); }
251
252  inline bool lookupValue(const std::string &name, double &value) const
253  { return(lookupValue(name.c_str(), value)); }
254
255  inline bool lookupValue(const std::string &name, float &value) const
256  { return(lookupValue(name.c_str(), value)); }
257
258  inline bool lookupValue(const std::string &name, const char *&value) const
259  { return(lookupValue(name.c_str(), value)); }
260
261  inline bool lookupValue(const std::string &name, std::string &value) const
262  { return(lookupValue(name.c_str(), value)); }
263
264  void remove(const char *name);
265
266  inline void remove(const std::string &name)
267  { remove(name.c_str()); }
268
269  void remove(unsigned int idx);
270
271  Setting & add(const char *name, Type type);
272
273  inline Setting & add(const std::string &name, Type type)
274  { return(add(name.c_str(), type)); }
275
276  Setting & add(Type type);
277
278  bool exists(const char *name) const;
279
280  inline bool exists(const std::string &name) const
281  { return(exists(name.c_str())); }
282
283  int getLength() const;
284  const char *getName() const;
285  std::string getPath() const;
286  int getIndex() const;
287
288  const Setting & getParent() const;
289  Setting & getParent();
290
291  bool isRoot() const;
292
293  inline bool isGroup() const
294  { return(_type == TypeGroup); }
295
296  inline bool isArray() const
297  { return(_type == TypeArray); }
298
299  inline bool isList() const
300  { return(_type == TypeList); }
301
302  inline bool isAggregate() const
303  { return(_type >= TypeGroup); }
304
305  inline bool isScalar() const
306  { return((_type > TypeNone) && (_type < TypeGroup)); }
307
308  inline bool isNumber() const
309  {
310    return((_type == TypeInt) || (_type == TypeInt64) || (_type == TypeFloat));
311  }
312
313  inline bool isString() const
314  { return(_type == TypeString); }
315
316  unsigned int getSourceLine() const;
317  const char *getSourceFile() const;
318
319  iterator begin();
320  iterator end();
321
322  const_iterator begin() const;
323  const_iterator end() const;
324
325  private:
326
327  config_setting_t *_setting;
328  Type _type;
329  Format _format;
330
331  Setting(config_setting_t *setting);
332
333  void assertType(Type type) const;
334  static Setting & wrapSetting(config_setting_t *setting);
335
336  Setting(const Setting& other); // not supported
337  Setting& operator=(const Setting& other); // not supported
338};
339
340
341class LIBCONFIGXX_API SettingIterator
342{
343  public:
344
345  SettingIterator(Setting &setting, bool endIterator = false);
346  SettingIterator(const SettingIterator &other);
347  SettingIterator& operator=(const SettingIterator &other);
348
349  // Equality comparison.
350  inline bool operator==(SettingIterator const &other) const
351  { return((_setting == other._setting) && (_idx == other._idx)); }
352
353  inline bool operator!=(SettingIterator const &other) const
354  { return(!operator==(other)); }
355
356  bool operator<(SettingIterator const &other) const;
357
358  // Dereference operators.
359  inline Setting & operator*()
360  { return((*_setting)[_idx]); }
361
362  inline Setting * operator->()
363  { return(&(*_setting)[_idx]); }
364
365  inline const Setting & operator*() const
366  { return(*_setting)[_idx]; }
367  inline const Setting * operator->() const
368  { return(&(*_setting)[_idx]); }
369
370  // Increment and decrement operators.
371  SettingIterator & operator++();
372  SettingIterator operator++(int);
373
374  SettingIterator & operator--();
375  SettingIterator operator--(int);
376
377  // Arithmetic operators.
378  SettingIterator operator+(int offset) const;
379  SettingIterator & operator+=(int offset);
380
381  SettingIterator operator-(int offset) const;
382  SettingIterator & operator-=(int offset);
383
384  int operator-(const SettingIterator &other) const;
385
386  private:
387
388  Setting *_setting;
389
390  int _count;
391  int _idx;
392};
393
394SettingIterator operator+(int offset, const SettingIterator &si);
395
396class LIBCONFIGXX_API SettingConstIterator
397{
398  public:
399
400  SettingConstIterator(const Setting &setting, bool endIterator = false);
401  SettingConstIterator(const SettingConstIterator &rhs);
402  SettingConstIterator& operator=(const SettingConstIterator &rhs);
403
404  // Equality comparison.
405  bool operator==(SettingConstIterator const &other) const
406  { return((_setting == other._setting) && (_idx == other._idx)); }
407
408  inline bool operator!=(SettingConstIterator const &other) const
409  { return(!operator==(other)); }
410
411  // Dereference operators.
412  inline Setting const & operator*()
413  { return((*_setting)[_idx]); }
414  inline Setting const * operator->()
415  { return(&(*_setting)[_idx]); }
416
417  inline const Setting& operator*() const
418  { return((*_setting)[_idx]); }
419  inline const Setting * operator->() const
420  { return(&(*_setting)[_idx]); }
421
422  // Increment and decrement operators.
423  SettingConstIterator & operator++();
424  SettingConstIterator operator++(int);
425
426  SettingConstIterator & operator--();
427  SettingConstIterator operator--(int);
428
429  // Arithmetic operators.
430  SettingConstIterator operator+(int offset) const;
431  SettingConstIterator & operator+=(int offset);
432
433  SettingConstIterator operator-(int offset) const;
434  SettingConstIterator & operator-=(int offset);
435
436  int operator-(const SettingConstIterator &other) const;
437
438  private:
439
440  const Setting *_setting;
441
442  int _count;
443  int _idx;
444};
445
446SettingConstIterator operator+(int offset, const SettingConstIterator &si);
447
448class LIBCONFIGXX_API Config
449{
450  public:
451
452  enum Option
453  {
454    OptionNone = 0,
455    OptionAutoConvert = 0x01,
456    OptionSemicolonSeparators = 0x02,
457    OptionColonAssignmentForGroups = 0x04,
458    OptionColonAssignmentForNonGroups = 0x08,
459    OptionOpenBraceOnSeparateLine = 0x10,
460    OptionAllowScientificNotation = 0x20,
461    OptionFsync = 0x40,
462    OptionAllowOverrides = 0x80
463  };
464
465  Config();
466  virtual ~Config();
467
468  void clear();
469
470  void setOptions(int options);
471  int getOptions() const;
472
473  void setOption(Config::Option option, bool flag);
474  bool getOption(Config::Option option) const;
475
476  inline void setAutoConvert(bool flag)
477  { setOption(Config::OptionAutoConvert, flag); }
478  inline bool getAutoConvert() const
479  { return(getOption(Config::OptionAutoConvert)); }
480
481  void setDefaultFormat(Setting::Format format);
482  inline Setting::Format getDefaultFormat() const
483  { return(_defaultFormat); }
484
485  void setTabWidth(unsigned short width);
486  unsigned short getTabWidth() const;
487
488  void setFloatPrecision(unsigned short digits);
489  unsigned short getFloatPrecision() const;
490
491  void setIncludeDir(const char *includeDir);
492  const char *getIncludeDir() const;
493
494  virtual const char **evaluateIncludePath(const char *path,
495                                           const char **error);
496
497  void read(FILE *stream);
498  void write(FILE *stream) const;
499
500  void readString(const char *str);
501  inline void readString(const std::string &str)
502  { return(readString(str.c_str())); }
503
504  void readFile(const char *filename);
505  inline void readFile(const std::string &filename)
506  { readFile(filename.c_str()); }
507
508  void writeFile(const char *filename);
509  inline void writeFile(const std::string &filename)
510  { writeFile(filename.c_str()); }
511
512  Setting & lookup(const char *path) const;
513  inline Setting & lookup(const std::string &path) const
514  { return(lookup(path.c_str())); }
515
516  bool exists(const char *path) const;
517  inline bool exists(const std::string &path) const
518  { return(exists(path.c_str())); }
519
520  bool lookupValue(const char *path, bool &value) const;
521  bool lookupValue(const char *path, int &value) const;
522  bool lookupValue(const char *path, unsigned int &value) const;
523  bool lookupValue(const char *path, long long &value) const;
524  bool lookupValue(const char *path, unsigned long long &value) const;
525  bool lookupValue(const char *path, double &value) const;
526  bool lookupValue(const char *path, float &value) const;
527  bool lookupValue(const char *path, const char *&value) const;
528  bool lookupValue(const char *path, std::string &value) const;
529
530  inline bool lookupValue(const std::string &path, bool &value) const
531  { return(lookupValue(path.c_str(), value)); }
532
533  inline bool lookupValue(const std::string &path, int &value) const
534  { return(lookupValue(path.c_str(), value)); }
535
536  inline bool lookupValue(const std::string &path, unsigned int &value) const
537  { return(lookupValue(path.c_str(), value)); }
538
539  inline bool lookupValue(const std::string &path, long long &value) const
540  { return(lookupValue(path.c_str(), value)); }
541
542  inline bool lookupValue(const std::string &path,
543                          unsigned long long &value) const
544  { return(lookupValue(path.c_str(), value)); }
545
546  inline bool lookupValue(const std::string &path, double &value) const
547  { return(lookupValue(path.c_str(), value)); }
548
549  inline bool lookupValue(const std::string &path, float &value) const
550  { return(lookupValue(path.c_str(), value)); }
551
552  inline bool lookupValue(const std::string &path, const char *&value) const
553  { return(lookupValue(path.c_str(), value)); }
554
555  inline bool lookupValue(const std::string &path, std::string &value) const
556  { return(lookupValue(path.c_str(), value)); }
557
558  Setting & getRoot() const;
559
560  private:
561
562  static void ConfigDestructor(void *arg);
563  void handleError() const;
564
565  config_t *_config;
566  Setting::Format _defaultFormat;
567
568  Config(const Config& other); // not supported
569  Config& operator=(const Config& other); // not supported
570};
571
572} // namespace libconfig
573
574#endif // __libconfig_hpp
575