summaryrefslogtreecommitdiffstats
path: root/ingen
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2012-11-21 03:49:32 +0000
committerDavid Robillard <d@drobilla.net>2012-11-21 03:49:32 +0000
commit0583e0b72b6bf7064c2e8af498b18f0bc168485f (patch)
tree817903922138a6a697c4b22b5238318da15dbc70 /ingen
parentd358cae57b7233bf6b781686979fc4dea4d090b3 (diff)
downloadingen-0583e0b72b6bf7064c2e8af498b18f0bc168485f.tar.gz
ingen-0583e0b72b6bf7064c2e8af498b18f0bc168485f.tar.bz2
ingen-0583e0b72b6bf7064c2e8af498b18f0bc168485f.zip
Move Configuration from Raul to Ingen.
git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@4836 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'ingen')
-rw-r--r--ingen/Configuration.hpp159
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