575 lines
16 KiB
C++
575 lines
16 KiB
C++
|
/* ----------------------------------------------------------------------------
|
||
|
libconfig - A library for processing structured configuration files
|
||
|
Copyright (C) 2005-2018 Mark A Lindner
|
||
|
|
||
|
This file is part of libconfig.
|
||
|
|
||
|
This library is free software; you can redistribute it and/or
|
||
|
modify it under the terms of the GNU Lesser General Public License
|
||
|
as published by the Free Software Foundation; either version 2.1 of
|
||
|
the License, or (at your option) any later version.
|
||
|
|
||
|
This library is distributed in the hope that it will be useful, but
|
||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
Lesser General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU Library General Public
|
||
|
License along with this library; if not, see
|
||
|
<http://www.gnu.org/licenses/>.
|
||
|
----------------------------------------------------------------------------
|
||
|
*/
|
||
|
|
||
|
#ifndef __libconfig_hpp
|
||
|
#define __libconfig_hpp
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <exception>
|
||
|
#include <string>
|
||
|
|
||
|
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
|
||
|
#if defined(LIBCONFIGXX_STATIC)
|
||
|
#define LIBCONFIGXX_API
|
||
|
#elif defined(LIBCONFIGXX_EXPORTS)
|
||
|
#define LIBCONFIGXX_API __declspec(dllexport)
|
||
|
#else /* ! LIBCONFIGXX_EXPORTS */
|
||
|
#define LIBCONFIGXX_API __declspec(dllimport)
|
||
|
#endif /* LIBCONFIGXX_STATIC */
|
||
|
#else /* ! WIN32 */
|
||
|
#define LIBCONFIGXX_API
|
||
|
#endif /* WIN32 */
|
||
|
|
||
|
#define LIBCONFIGXX_VER_MAJOR 1
|
||
|
#define LIBCONFIGXX_VER_MINOR 7
|
||
|
#define LIBCONFIGXX_VER_REVISION 0
|
||
|
|
||
|
#if __cplusplus < 201103L
|
||
|
#define LIBCONFIGXX_NOEXCEPT throw()
|
||
|
#else
|
||
|
#define LIBCONFIGXX_NOEXCEPT noexcept
|
||
|
#endif
|
||
|
|
||
|
struct config_t; // fwd decl
|
||
|
struct config_setting_t; // fwd decl
|
||
|
|
||
|
namespace libconfig {
|
||
|
|
||
|
class LIBCONFIGXX_API ConfigException : public std::exception { };
|
||
|
|
||
|
class Setting; // fwd decl
|
||
|
class SettingIterator;
|
||
|
class SettingConstIterator;
|
||
|
|
||
|
class LIBCONFIGXX_API SettingException : public ConfigException
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
SettingException(const Setting &setting);
|
||
|
SettingException(const Setting &setting, int idx);
|
||
|
SettingException(const Setting &setting, const char *name);
|
||
|
SettingException(const char *path);
|
||
|
|
||
|
SettingException(const SettingException &other);
|
||
|
SettingException& operator=(const SettingException &other);
|
||
|
|
||
|
virtual ~SettingException() LIBCONFIGXX_NOEXCEPT;
|
||
|
|
||
|
const char *getPath() const;
|
||
|
|
||
|
virtual const char *what() const LIBCONFIGXX_NOEXCEPT;
|
||
|
|
||
|
private:
|
||
|
|
||
|
char *_path;
|
||
|
};
|
||
|
|
||
|
class LIBCONFIGXX_API SettingTypeException : public SettingException
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
SettingTypeException(const Setting &setting);
|
||
|
SettingTypeException(const Setting &setting, int idx);
|
||
|
SettingTypeException(const Setting &setting, const char *name);
|
||
|
|
||
|
virtual const char *what() const LIBCONFIGXX_NOEXCEPT;
|
||
|
};
|
||
|
|
||
|
class LIBCONFIGXX_API SettingNotFoundException : public SettingException
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
SettingNotFoundException(const char *path);
|
||
|
SettingNotFoundException(const Setting &setting, int idx);
|
||
|
SettingNotFoundException(const Setting &setting, const char *name);
|
||
|
|
||
|
virtual const char *what() const LIBCONFIGXX_NOEXCEPT;
|
||
|
};
|
||
|
|
||
|
class LIBCONFIGXX_API SettingNameException : public SettingException
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
SettingNameException(const Setting &setting, const char *name);
|
||
|
|
||
|
virtual const char *what() const LIBCONFIGXX_NOEXCEPT;
|
||
|
};
|
||
|
|
||
|
class LIBCONFIGXX_API FileIOException : public ConfigException
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
virtual const char *what() const LIBCONFIGXX_NOEXCEPT;
|
||
|
};
|
||
|
|
||
|
class LIBCONFIGXX_API ParseException : public ConfigException
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
ParseException(const char *file, int line, const char *error);
|
||
|
|
||
|
ParseException(const ParseException &other);
|
||
|
|
||
|
virtual ~ParseException() LIBCONFIGXX_NOEXCEPT;
|
||
|
|
||
|
inline const char *getFile() const
|
||
|
{ return(_file); }
|
||
|
|
||
|
inline int getLine() const
|
||
|
{ return(_line); }
|
||
|
|
||
|
inline const char *getError() const
|
||
|
{ return(_error); }
|
||
|
|
||
|
virtual const char *what() const LIBCONFIGXX_NOEXCEPT;
|
||
|
|
||
|
private:
|
||
|
|
||
|
const char *_file;
|
||
|
int _line;
|
||
|
const char *_error;
|
||
|
};
|
||
|
|
||
|
class LIBCONFIGXX_API Setting
|
||
|
{
|
||
|
friend class Config;
|
||
|
|
||
|
public:
|
||
|
|
||
|
enum Type
|
||
|
{
|
||
|
TypeNone = 0,
|
||
|
// scalar types
|
||
|
TypeInt,
|
||
|
TypeInt64,
|
||
|
TypeFloat,
|
||
|
TypeString,
|
||
|
TypeBoolean,
|
||
|
// aggregate types
|
||
|
TypeGroup,
|
||
|
TypeArray,
|
||
|
TypeList
|
||
|
};
|
||
|
|
||
|
enum Format
|
||
|
{
|
||
|
FormatDefault = 0,
|
||
|
FormatHex = 1
|
||
|
};
|
||
|
|
||
|
typedef SettingIterator iterator;
|
||
|
typedef SettingConstIterator const_iterator;
|
||
|
|
||
|
public:
|
||
|
|
||
|
virtual ~Setting();
|
||
|
|
||
|
inline Type getType() const { return(_type); }
|
||
|
|
||
|
inline Format getFormat() const { return(_format); }
|
||
|
void setFormat(Format format);
|
||
|
|
||
|
operator bool() const;
|
||
|
operator int() const;
|
||
|
operator unsigned int() const;
|
||
|
operator long() const;
|
||
|
operator unsigned long() const;
|
||
|
operator long long() const;
|
||
|
operator unsigned long long() const;
|
||
|
operator double() const;
|
||
|
operator float() const;
|
||
|
operator const char *() const;
|
||
|
operator std::string() const;
|
||
|
|
||
|
inline const char *c_str() const
|
||
|
{ return operator const char *(); }
|
||
|
|
||
|
Setting & operator=(bool value);
|
||
|
Setting & operator=(int value);
|
||
|
Setting & operator=(long value);
|
||
|
Setting & operator=(const long long &value);
|
||
|
Setting & operator=(const double &value);
|
||
|
Setting & operator=(float value);
|
||
|
Setting & operator=(const char *value);
|
||
|
Setting & operator=(const std::string &value);
|
||
|
|
||
|
Setting & lookup(const char *path) const;
|
||
|
inline Setting & lookup(const std::string &path) const
|
||
|
{ return(lookup(path.c_str())); }
|
||
|
|
||
|
Setting & operator[](const char *name) const;
|
||
|
|
||
|
inline Setting & operator[](const std::string &name) const
|
||
|
{ return(operator[](name.c_str())); }
|
||
|
|
||
|
Setting & operator[](int index) const;
|
||
|
|
||
|
bool lookupValue(const char *name, bool &value) const;
|
||
|
bool lookupValue(const char *name, int &value) const;
|
||
|
bool lookupValue(const char *name, unsigned int &value) const;
|
||
|
bool lookupValue(const char *name, long long &value) const;
|
||
|
bool lookupValue(const char *name, unsigned long long &value) const;
|
||
|
bool lookupValue(const char *name, double &value) const;
|
||
|
bool lookupValue(const char *name, float &value) const;
|
||
|
bool lookupValue(const char *name, const char *&value) const;
|
||
|
bool lookupValue(const char *name, std::string &value) const;
|
||
|
|
||
|
inline bool lookupValue(const std::string &name, bool &value) const
|
||
|
{ return(lookupValue(name.c_str(), value)); }
|
||
|
|
||
|
inline bool lookupValue(const std::string &name, int &value) const
|
||
|
{ return(lookupValue(name.c_str(), value)); }
|
||
|
|
||
|
inline bool lookupValue(const std::string &name, unsigned int &value) const
|
||
|
{ return(lookupValue(name.c_str(), value)); }
|
||
|
|
||
|
inline bool lookupValue(const std::string &name, long long &value) const
|
||
|
{ return(lookupValue(name.c_str(), value)); }
|
||
|
|
||
|
inline bool lookupValue(const std::string &name,
|
||
|
unsigned long long &value) const
|
||
|
{ return(lookupValue(name.c_str(), value)); }
|
||
|
|
||
|
inline bool lookupValue(const std::string &name, double &value) const
|
||
|
{ return(lookupValue(name.c_str(), value)); }
|
||
|
|
||
|
inline bool lookupValue(const std::string &name, float &value) const
|
||
|
{ return(lookupValue(name.c_str(), value)); }
|
||
|
|
||
|
inline bool lookupValue(const std::string &name, const char *&value) const
|
||
|
{ return(lookupValue(name.c_str(), value)); }
|
||
|
|
||
|
inline bool lookupValue(const std::string &name, std::string &value) const
|
||
|
{ return(lookupValue(name.c_str(), value)); }
|
||
|
|
||
|
void remove(const char *name);
|
||
|
|
||
|
inline void remove(const std::string &name)
|
||
|
{ remove(name.c_str()); }
|
||
|
|
||
|
void remove(unsigned int idx);
|
||
|
|
||
|
Setting & add(const char *name, Type type);
|
||
|
|
||
|
inline Setting & add(const std::string &name, Type type)
|
||
|
{ return(add(name.c_str(), type)); }
|
||
|
|
||
|
Setting & add(Type type);
|
||
|
|
||
|
bool exists(const char *name) const;
|
||
|
|
||
|
inline bool exists(const std::string &name) const
|
||
|
{ return(exists(name.c_str())); }
|
||
|
|
||
|
int getLength() const;
|
||
|
const char *getName() const;
|
||
|
std::string getPath() const;
|
||
|
int getIndex() const;
|
||
|
|
||
|
const Setting & getParent() const;
|
||
|
Setting & getParent();
|
||
|
|
||
|
bool isRoot() const;
|
||
|
|
||
|
inline bool isGroup() const
|
||
|
{ return(_type == TypeGroup); }
|
||
|
|
||
|
inline bool isArray() const
|
||
|
{ return(_type == TypeArray); }
|
||
|
|
||
|
inline bool isList() const
|
||
|
{ return(_type == TypeList); }
|
||
|
|
||
|
inline bool isAggregate() const
|
||
|
{ return(_type >= TypeGroup); }
|
||
|
|
||
|
inline bool isScalar() const
|
||
|
{ return((_type > TypeNone) && (_type < TypeGroup)); }
|
||
|
|
||
|
inline bool isNumber() const
|
||
|
{
|
||
|
return((_type == TypeInt) || (_type == TypeInt64) || (_type == TypeFloat));
|
||
|
}
|
||
|
|
||
|
inline bool isString() const
|
||
|
{ return(_type == TypeString); }
|
||
|
|
||
|
unsigned int getSourceLine() const;
|
||
|
const char *getSourceFile() const;
|
||
|
|
||
|
iterator begin();
|
||
|
iterator end();
|
||
|
|
||
|
const_iterator begin() const;
|
||
|
const_iterator end() const;
|
||
|
|
||
|
private:
|
||
|
|
||
|
config_setting_t *_setting;
|
||
|
Type _type;
|
||
|
Format _format;
|
||
|
|
||
|
Setting(config_setting_t *setting);
|
||
|
|
||
|
void assertType(Type type) const;
|
||
|
static Setting & wrapSetting(config_setting_t *setting);
|
||
|
|
||
|
Setting(const Setting& other); // not supported
|
||
|
Setting& operator=(const Setting& other); // not supported
|
||
|
};
|
||
|
|
||
|
|
||
|
class LIBCONFIGXX_API SettingIterator
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
SettingIterator(Setting &setting, bool endIterator = false);
|
||
|
SettingIterator(const SettingIterator &other);
|
||
|
SettingIterator& operator=(const SettingIterator &other);
|
||
|
|
||
|
// Equality comparison.
|
||
|
inline bool operator==(SettingIterator const &other) const
|
||
|
{ return((_setting == other._setting) && (_idx == other._idx)); }
|
||
|
|
||
|
inline bool operator!=(SettingIterator const &other) const
|
||
|
{ return(!operator==(other)); }
|
||
|
|
||
|
bool operator<(SettingIterator const &other) const;
|
||
|
|
||
|
// Dereference operators.
|
||
|
inline Setting & operator*()
|
||
|
{ return((*_setting)[_idx]); }
|
||
|
|
||
|
inline Setting * operator->()
|
||
|
{ return(&(*_setting)[_idx]); }
|
||
|
|
||
|
inline const Setting & operator*() const
|
||
|
{ return(*_setting)[_idx]; }
|
||
|
inline const Setting * operator->() const
|
||
|
{ return(&(*_setting)[_idx]); }
|
||
|
|
||
|
// Increment and decrement operators.
|
||
|
SettingIterator & operator++();
|
||
|
SettingIterator operator++(int);
|
||
|
|
||
|
SettingIterator & operator--();
|
||
|
SettingIterator operator--(int);
|
||
|
|
||
|
// Arithmetic operators.
|
||
|
SettingIterator operator+(int offset) const;
|
||
|
SettingIterator & operator+=(int offset);
|
||
|
|
||
|
SettingIterator operator-(int offset) const;
|
||
|
SettingIterator & operator-=(int offset);
|
||
|
|
||
|
int operator-(const SettingIterator &other) const;
|
||
|
|
||
|
private:
|
||
|
|
||
|
Setting *_setting;
|
||
|
|
||
|
int _count;
|
||
|
int _idx;
|
||
|
};
|
||
|
|
||
|
SettingIterator operator+(int offset, const SettingIterator &si);
|
||
|
|
||
|
class LIBCONFIGXX_API SettingConstIterator
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
SettingConstIterator(const Setting &setting, bool endIterator = false);
|
||
|
SettingConstIterator(const SettingConstIterator &rhs);
|
||
|
SettingConstIterator& operator=(const SettingConstIterator &rhs);
|
||
|
|
||
|
// Equality comparison.
|
||
|
bool operator==(SettingConstIterator const &other) const
|
||
|
{ return((_setting == other._setting) && (_idx == other._idx)); }
|
||
|
|
||
|
inline bool operator!=(SettingConstIterator const &other) const
|
||
|
{ return(!operator==(other)); }
|
||
|
|
||
|
// Dereference operators.
|
||
|
inline Setting const & operator*()
|
||
|
{ return((*_setting)[_idx]); }
|
||
|
inline Setting const * operator->()
|
||
|
{ return(&(*_setting)[_idx]); }
|
||
|
|
||
|
inline const Setting& operator*() const
|
||
|
{ return((*_setting)[_idx]); }
|
||
|
inline const Setting * operator->() const
|
||
|
{ return(&(*_setting)[_idx]); }
|
||
|
|
||
|
// Increment and decrement operators.
|
||
|
SettingConstIterator & operator++();
|
||
|
SettingConstIterator operator++(int);
|
||
|
|
||
|
SettingConstIterator & operator--();
|
||
|
SettingConstIterator operator--(int);
|
||
|
|
||
|
// Arithmetic operators.
|
||
|
SettingConstIterator operator+(int offset) const;
|
||
|
SettingConstIterator & operator+=(int offset);
|
||
|
|
||
|
SettingConstIterator operator-(int offset) const;
|
||
|
SettingConstIterator & operator-=(int offset);
|
||
|
|
||
|
int operator-(const SettingConstIterator &other) const;
|
||
|
|
||
|
private:
|
||
|
|
||
|
const Setting *_setting;
|
||
|
|
||
|
int _count;
|
||
|
int _idx;
|
||
|
};
|
||
|
|
||
|
SettingConstIterator operator+(int offset, const SettingConstIterator &si);
|
||
|
|
||
|
class LIBCONFIGXX_API Config
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
enum Option
|
||
|
{
|
||
|
OptionNone = 0,
|
||
|
OptionAutoConvert = 0x01,
|
||
|
OptionSemicolonSeparators = 0x02,
|
||
|
OptionColonAssignmentForGroups = 0x04,
|
||
|
OptionColonAssignmentForNonGroups = 0x08,
|
||
|
OptionOpenBraceOnSeparateLine = 0x10,
|
||
|
OptionAllowScientificNotation = 0x20,
|
||
|
OptionFsync = 0x40,
|
||
|
OptionAllowOverrides = 0x80
|
||
|
};
|
||
|
|
||
|
Config();
|
||
|
virtual ~Config();
|
||
|
|
||
|
void clear();
|
||
|
|
||
|
void setOptions(int options);
|
||
|
int getOptions() const;
|
||
|
|
||
|
void setOption(Config::Option option, bool flag);
|
||
|
bool getOption(Config::Option option) const;
|
||
|
|
||
|
inline void setAutoConvert(bool flag)
|
||
|
{ setOption(Config::OptionAutoConvert, flag); }
|
||
|
inline bool getAutoConvert() const
|
||
|
{ return(getOption(Config::OptionAutoConvert)); }
|
||
|
|
||
|
void setDefaultFormat(Setting::Format format);
|
||
|
inline Setting::Format getDefaultFormat() const
|
||
|
{ return(_defaultFormat); }
|
||
|
|
||
|
void setTabWidth(unsigned short width);
|
||
|
unsigned short getTabWidth() const;
|
||
|
|
||
|
void setFloatPrecision(unsigned short digits);
|
||
|
unsigned short getFloatPrecision() const;
|
||
|
|
||
|
void setIncludeDir(const char *includeDir);
|
||
|
const char *getIncludeDir() const;
|
||
|
|
||
|
virtual const char **evaluateIncludePath(const char *path,
|
||
|
const char **error);
|
||
|
|
||
|
void read(FILE *stream);
|
||
|
void write(FILE *stream) const;
|
||
|
|
||
|
void readString(const char *str);
|
||
|
inline void readString(const std::string &str)
|
||
|
{ return(readString(str.c_str())); }
|
||
|
|
||
|
void readFile(const char *filename);
|
||
|
inline void readFile(const std::string &filename)
|
||
|
{ readFile(filename.c_str()); }
|
||
|
|
||
|
void writeFile(const char *filename);
|
||
|
inline void writeFile(const std::string &filename)
|
||
|
{ writeFile(filename.c_str()); }
|
||
|
|
||
|
Setting & lookup(const char *path) const;
|
||
|
inline Setting & lookup(const std::string &path) const
|
||
|
{ return(lookup(path.c_str())); }
|
||
|
|
||
|
bool exists(const char *path) const;
|
||
|
inline bool exists(const std::string &path) const
|
||
|
{ return(exists(path.c_str())); }
|
||
|
|
||
|
bool lookupValue(const char *path, bool &value) const;
|
||
|
bool lookupValue(const char *path, int &value) const;
|
||
|
bool lookupValue(const char *path, unsigned int &value) const;
|
||
|
bool lookupValue(const char *path, long long &value) const;
|
||
|
bool lookupValue(const char *path, unsigned long long &value) const;
|
||
|
bool lookupValue(const char *path, double &value) const;
|
||
|
bool lookupValue(const char *path, float &value) const;
|
||
|
bool lookupValue(const char *path, const char *&value) const;
|
||
|
bool lookupValue(const char *path, std::string &value) const;
|
||
|
|
||
|
inline bool lookupValue(const std::string &path, bool &value) const
|
||
|
{ return(lookupValue(path.c_str(), value)); }
|
||
|
|
||
|
inline bool lookupValue(const std::string &path, int &value) const
|
||
|
{ return(lookupValue(path.c_str(), value)); }
|
||
|
|
||
|
inline bool lookupValue(const std::string &path, unsigned int &value) const
|
||
|
{ return(lookupValue(path.c_str(), value)); }
|
||
|
|
||
|
inline bool lookupValue(const std::string &path, long long &value) const
|
||
|
{ return(lookupValue(path.c_str(), value)); }
|
||
|
|
||
|
inline bool lookupValue(const std::string &path,
|
||
|
unsigned long long &value) const
|
||
|
{ return(lookupValue(path.c_str(), value)); }
|
||
|
|
||
|
inline bool lookupValue(const std::string &path, double &value) const
|
||
|
{ return(lookupValue(path.c_str(), value)); }
|
||
|
|
||
|
inline bool lookupValue(const std::string &path, float &value) const
|
||
|
{ return(lookupValue(path.c_str(), value)); }
|
||
|
|
||
|
inline bool lookupValue(const std::string &path, const char *&value) const
|
||
|
{ return(lookupValue(path.c_str(), value)); }
|
||
|
|
||
|
inline bool lookupValue(const std::string &path, std::string &value) const
|
||
|
{ return(lookupValue(path.c_str(), value)); }
|
||
|
|
||
|
Setting & getRoot() const;
|
||
|
|
||
|
private:
|
||
|
|
||
|
static void ConfigDestructor(void *arg);
|
||
|
void handleError() const;
|
||
|
|
||
|
config_t *_config;
|
||
|
Setting::Format _defaultFormat;
|
||
|
|
||
|
Config(const Config& other); // not supported
|
||
|
Config& operator=(const Config& other); // not supported
|
||
|
};
|
||
|
|
||
|
} // namespace libconfig
|
||
|
|
||
|
#endif // __libconfig_hpp
|