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