diff options
Diffstat (limited to 'ingen/Configuration.hpp')
-rw-r--r-- | ingen/Configuration.hpp | 159 |
1 files changed, 156 insertions, 3 deletions
diff --git a/ingen/Configuration.hpp b/ingen/Configuration.hpp index f45f3869..fac798d1 100644 --- a/ingen/Configuration.hpp +++ b/ingen/Configuration.hpp @@ -17,19 +17,172 @@ #ifndef INGEN_CONFIGURATION_HPP #define INGEN_CONFIGURATION_HPP -#include "raul/Configuration.hpp" +#include <assert.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include <list> +#include <map> +#include <string> + +#include "raul/Exception.hpp" namespace Ingen { -/** Ingen configuration (command line options). +/** Ingen configuration (command line options and/or configuration file). * @ingroup IngenShared */ -class Configuration : public Raul::Configuration { +class Configuration { public: Configuration(); + + enum OptionType { + NOTHING, + BOOL, + INT, + STRING + }; + + class Value { + public: + Value() : _type(NOTHING) { _val._string = NULL; } + Value(bool v) : _type(BOOL) { _val._bool = v; } + Value(int v) : _type(INT) { _val._int = v; } + + Value(const char* v) : _type(STRING) { + const size_t len = strlen(v); + _val._string = (char*)calloc(len + 1, 1); + memcpy(_val._string, v, len + 1); + } + + Value(const std::string& v) : _type(STRING) { + _val._string = (char*)calloc(v.length() + 1, 1); + memcpy(_val._string, v.c_str(), v.length() + 1); + } + + Value(const Value& copy) + : _type(copy._type) + , _val(copy._val) + { + if (_type == STRING) { + const size_t len = strlen(copy.get_string()); + _val._string = (char*)malloc(len + 1); + memcpy(_val._string, copy.get_string(), len + 1); + } + } + + Value& operator=(const Value& other) + { + if (&other == this) { + return *this; + } + if (_type == STRING) { + free(_val._string); + } + _type = other._type; + _val = other._val; + if (_type == STRING) { + const size_t len = strlen(other.get_string()); + _val._string = (char*)malloc(len + 1); + memcpy(_val._string, other.get_string(), len + 1); + } + return *this; + } + + ~Value() { + if (_type == STRING) { + free(_val._string); + } + } + + inline OptionType type() const { return _type; } + inline bool is_valid() const { return _type != NOTHING; } + + inline int32_t get_int() const { assert(_type == INT); return _val._int; } + inline bool get_bool() const { assert(_type == BOOL); return _val._bool; } + inline const char* get_string() const { assert(_type == STRING); return _val._string; } + + private: + OptionType _type; + union { + bool _bool; + int32_t _int; + char* _string; + } _val; + }; + + Configuration& add(const std::string& name, + char letter, + const std::string& desc, + OptionType type, + const Value& value); + + void print_usage(const std::string& program, std::ostream& os); + + struct CommandLineError : public Exception { + explicit CommandLineError(const std::string& m) : Exception(m) {} + }; + + void parse(int argc, char** argv) throw (CommandLineError); + + void print(std::ostream& os, const std::string mime_type="text/plain") const; + + const Value& option(const std::string& long_name) const; + bool set(const std::string& long_name, const Value& value); + + const std::list<std::string>& files() const { return _files; } + +private: + struct Option { + public: + Option(const std::string& n, char l, const std::string& d, + const OptionType type, const Value& def) + : name(n), letter(l), desc(d), type(type), default_value(def), value(def) + {} + + std::string name; + char letter; + std::string desc; + OptionType type; + Value default_value; + Value value; + }; + + struct OptionNameOrder { + inline bool operator()(const Option& a, const Option& b) { + return a.name < b.name; + } + }; + + typedef std::map<std::string, Option> Options; + typedef std::map<char, std::string> ShortNames; + typedef std::list<std::string> Files; + + int set_value_from_string(Configuration::Option& option, const std::string& value) + throw (Configuration::CommandLineError); + + const std::string _shortdesc; + const std::string _desc; + Options _options; + ShortNames _short_names; + Files _files; + size_t _max_name_length; }; } // namespace Ingen +static inline std::ostream& +operator<<(std::ostream& os, const Ingen::Configuration::Value& value) +{ + switch (value.type()) { + case Ingen::Configuration::NOTHING: return os << "(nil)"; + case Ingen::Configuration::INT: return os << value.get_int(); + case Ingen::Configuration::BOOL: return os << (value.get_bool() ? "true" : "false"); + case Ingen::Configuration::STRING: return os << value.get_string(); + } + return os; +} + #endif // INGEN_CONFIGURATION_HPP |