summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ingen/Configuration.hpp37
-rw-r--r--src/Configuration.cpp118
-rw-r--r--src/World.cpp10
-rw-r--r--src/server/JackDriver.cpp5
-rw-r--r--src/server/ingen_jack.cpp2
-rw-r--r--src/socket/SocketListener.cpp2
6 files changed, 135 insertions, 39 deletions
diff --git a/ingen/Configuration.hpp b/ingen/Configuration.hpp
index bc04ecba..0ede7059 100644
--- a/ingen/Configuration.hpp
+++ b/ingen/Configuration.hpp
@@ -112,10 +112,20 @@ public:
} _val;
};
- Configuration& add(const std::string& name,
+ /** Add a configuration option.
+ *
+ * @param key URI local name, in camelCase
+ * @param name Long option name (without leading "--")
+ * @param letter Short option name (without leading "-")
+ * @param desc Description
+ * @param type Type
+ * @param value Default value
+ */
+ Configuration& add(const std::string& key,
+ const std::string& name,
char letter,
const std::string& desc,
- OptionType type,
+ const OptionType type,
const Value& value);
void print_usage(const std::string& program, std::ostream& os);
@@ -126,6 +136,18 @@ public:
void parse(int argc, char** argv) throw (CommandLineError);
+ /** Load a specific file. */
+ bool load(const std::string& path);
+
+ /** Load files from the standard configuration directories for the app.
+ *
+ * The system configuration file(s), e.g. /etc/xdg/appname/filename,
+ * will be loaded before the user's, e.g. ~/.config/appname/filename,
+ * so the user options will override the system options.
+ */
+ std::list<std::string> load_default(const std::string& app,
+ const std::string& file);
+
void print(std::ostream& os, const std::string mime_type="text/plain") const;
const Value& option(const std::string& long_name) const;
@@ -138,14 +160,13 @@ private:
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)
+ : name(n), letter(l), desc(d), type(type), value(def)
{}
std::string name;
char letter;
std::string desc;
OptionType type;
- Value default_value;
Value value;
};
@@ -155,9 +176,10 @@ private:
}
};
- typedef std::map<std::string, Option> Options;
- typedef std::map<char, std::string> ShortNames;
- typedef std::list<std::string> Files;
+ typedef std::map<std::string, Option> Options;
+ typedef std::map<char, std::string> ShortNames;
+ typedef std::map<std::string, std::string> Keys;
+ typedef std::list<std::string> Files;
int set_value_from_string(Configuration::Option& option, const std::string& value)
throw (Configuration::CommandLineError);
@@ -165,6 +187,7 @@ private:
const std::string _shortdesc;
const std::string _desc;
Options _options;
+ Keys _keys;
ShortNames _short_names;
Files _files;
size_t _max_name_length;
diff --git a/src/Configuration.cpp b/src/Configuration.cpp
index a7f45e7f..d453d43b 100644
--- a/src/Configuration.cpp
+++ b/src/Configuration.cpp
@@ -16,8 +16,14 @@
#include <iostream>
+#include <glibmm/fileutils.h>
+#include <glibmm/miscutils.h>
+
#include "ingen/Configuration.hpp"
#include "raul/fmt.hpp"
+#include "sord/sordmm.hpp"
+
+#define NS_INGEN "http://drobilla.net/ns/ingen#"
namespace Ingen {
@@ -37,42 +43,36 @@ Configuration::Configuration()
" ingen -egl foo.ingen # Run an engine and a GUI and load a graph")
, _max_name_length(0)
{
- add("client-port", 'C', "Client port", INT, Value());
- add("connect", 'c', "Connect to engine URI", STRING, Value("unix:///tmp/ingen.sock"));
- add("engine", 'e', "Run (JACK) engine", BOOL, Value(false));
- add("engine-port", 'E', "Engine listen port", INT, Value(16180));
- add("socket", 'S', "Engine socket path", STRING, Value("/tmp/ingen.sock"));
- add("gui", 'g', "Launch the GTK graphical interface", BOOL, Value(false));
- add("help", 'h', "Print this help message", BOOL, Value(false));
- add("jack-client", 'n', "JACK client name", STRING, Value("ingen"));
- add("jack-server", 's', "JACK server name", STRING, Value(""));
- add("uuid", 'u', "JACK session UUID", STRING, Value());
- add("load", 'l', "Load graph", STRING, Value());
- add("packet-size", 'k', "Maximum UDP packet size", INT, Value(4096));
- add("path", 'L', "Target path for loaded graph", STRING, Value());
- add("queue-size", 'q', "Event queue size", INT, Value(4096));
- add("run", 'r', "Run script", STRING, Value());
+ add("clientPort", "client-port", 'C', "Client port", INT, Value());
+ add("connect", "connect", 'c', "Connect to engine URI", STRING, Value("unix:///tmp/ingen.sock"));
+ add("engine", "engine", 'e', "Run (JACK) engine", BOOL, Value(false));
+ add("enginePort", "engine-port", 'E', "Engine listen port", INT, Value(16180));
+ add("socket", "socket", 'S', "Engine socket path", STRING, Value("/tmp/ingen.sock"));
+ add("gui", "gui", 'g', "Launch the GTK graphical interface", BOOL, Value(false));
+ add("", "help", 'h', "Print this help message", BOOL, Value(false));
+ add("jackName", "jack-name", 'n', "JACK name", STRING, Value("ingen"));
+ add("jackServer", "jack-server", 's', "JACK server name", STRING, Value(""));
+ add("uuid", "uuid", 'u', "JACK session UUID", STRING, Value());
+ add("load", "load", 'l', "Load graph", STRING, Value());
+ add("path", "path", 'L', "Target path for loaded graph", STRING, Value());
+ add("queueSize", "queue-size", 'q', "Event queue size", INT, Value(4096));
+ add("run", "run", 'r', "Run script", STRING, Value());
}
-/** Add a configuration option.
- *
- * @param name Long name (without leading "--")
- * @param letter Short name (without leading "-")
- * @param desc Description
- * @param type Type
- * @param value Default value
- */
Configuration&
-Configuration::add(
- const std::string& name,
- char letter,
- const std::string& desc,
- const OptionType type,
- const Value& value)
+Configuration::add(const std::string& key,
+ const std::string& name,
+ char letter,
+ const std::string& desc,
+ const OptionType type,
+ const Value& value)
{
assert(value.type() == type || value.type() == 0);
_max_name_length = std::max(_max_name_length, name.length());
_options.insert(make_pair(name, Option(name, letter, desc, type, value)));
+ if (!key.empty()) {
+ _keys.insert(make_pair(key, name));
+ }
if (letter != '\0') {
_short_names.insert(make_pair(letter, name));
}
@@ -179,6 +179,66 @@ Configuration::parse(int argc, char** argv) throw (Configuration::CommandLineErr
}
}
+bool
+Configuration::load(const std::string& path)
+{
+ if (!Glib::file_test(path, Glib::FILE_TEST_EXISTS)) {
+ return false;
+ }
+
+ SerdNode node = serd_node_new_file_uri(
+ (const uint8_t*)path.c_str(), NULL, NULL, true);
+ const std::string uri((const char*)node.buf);
+
+ Sord::World world;
+ Sord::Model model(world, uri, SORD_SPO, false);
+ SerdEnv* env = serd_env_new(&node);
+ model.load_file(env, SERD_TURTLE, uri, uri);
+
+ Sord::Node nodemm(world, Sord::Node::URI, (const char*)node.buf);
+ Sord::Node nil;
+ for (Sord::Iter i = model.find(nodemm, nil, nil); !i.end(); ++i) {
+ const Sord::Node& pred = i.get_predicate();
+ const Sord::Node& obj = i.get_object();
+ if (pred.to_string().substr(0, sizeof(NS_INGEN) - 1) == NS_INGEN) {
+ const std::string key = pred.to_string().substr(sizeof(NS_INGEN) - 1);
+ const Keys::iterator k = _keys.find(key);
+ if (k != _keys.end() && obj.type() == Sord::Node::LITERAL) {
+ set_value_from_string(_options.find(k->second)->second,
+ obj.to_string());
+ }
+ }
+ }
+
+ serd_node_free(&node);
+ serd_env_free(env);
+ return true;
+}
+
+std::list<std::string>
+Configuration::load_default(const std::string& app, const std::string& file)
+{
+ std::list<std::string> loaded;
+
+ const std::vector<std::string> dirs = Glib::get_system_config_dirs();
+ for (std::vector<std::string>::const_iterator i = dirs.begin();
+ i != dirs.end();
+ ++i) {
+ const std::string path = Glib::build_filename(*i, app, file);
+ if (load(path)) {
+ loaded.push_back(path);
+ }
+ }
+
+ const std::string path = Glib::build_filename(
+ Glib::get_user_config_dir(), app, file);
+ if (load(path)) {
+ loaded.push_back(path);
+ }
+
+ return loaded;
+}
+
void
Configuration::print(std::ostream& os, const std::string mime_type) const
{
diff --git a/src/World.cpp b/src/World.cpp
index fa2ae1ed..f5421579 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -108,7 +108,17 @@ public:
, log(lv2_log, *uris)
, lilv_world(lilv_world_new())
{
+ // Parse default configuration files
+ std::list<std::string> files = conf.load_default("ingen", "options.ttl");
+ for (std::list<std::string>::const_iterator f = files.begin();
+ f != files.end();
+ ++f) {
+ log.info(Raul::fmt("Loaded configuration %1%\n") % *f);
+ }
+
+ // Parse command line options, overriding configuration file values
conf.parse(argc, argv);
+
lv2_features = new LV2Features();
lv2_features->add_feature(uri_map->urid_map_feature());
lv2_features->add_feature(uri_map->urid_unmap_feature());
diff --git a/src/server/JackDriver.cpp b/src/server/JackDriver.cpp
index eb1c0894..ac3393a2 100644
--- a/src/server/JackDriver.cpp
+++ b/src/server/JackDriver.cpp
@@ -148,7 +148,7 @@ JackDriver::activate()
if (!_client)
attach(world->conf().option("jack-server").get_string(),
- world->conf().option("jack-client").get_string(), NULL);
+ world->conf().option("jack-name").get_string(), NULL);
jack_set_process_callback(_client, process_cb, this);
@@ -158,7 +158,8 @@ JackDriver::activate()
_engine.log().error("Could not activate Jack client, aborting\n");
exit(EXIT_FAILURE);
} else {
- _engine.log().info("Activated Jack client\n");
+ _engine.log().info(Raul::fmt("Activated Jack client `%1%'\n") %
+ world->conf().option("jack-name").get_string());
}
}
diff --git a/src/server/ingen_jack.cpp b/src/server/ingen_jack.cpp
index dd713385..c6c5e005 100644
--- a/src/server/ingen_jack.cpp
+++ b/src/server/ingen_jack.cpp
@@ -40,7 +40,7 @@ struct IngenJackModule : public Ingen::Module {
const Configuration::Value& s = world->conf().option("jack-server");
const std::string server_name = s.is_valid() ? s.get_string() : "";
driver->attach(server_name,
- world->conf().option("jack-client").get_string(),
+ world->conf().option("jack-name").get_string(),
NULL);
((Server::Engine*)world->engine().get())->set_driver(
SharedPtr<Server::Driver>(driver));
diff --git a/src/socket/SocketListener.cpp b/src/socket/SocketListener.cpp
index 76afb4fd..351dbcab 100644
--- a/src/socket/SocketListener.cpp
+++ b/src/socket/SocketListener.cpp
@@ -48,6 +48,7 @@ SocketListener::SocketListener(Ingen::World& world)
_world.log().error("Failed to create UNIX socket\n");
_unix_sock.close();
}
+ _world.log().info(Raul::fmt("Listening on socket %1%\n") % unix_uri);
// Create TCP socket
int port = world.conf().option("engine-port").get_int();
@@ -58,6 +59,7 @@ SocketListener::SocketListener(Ingen::World& world)
_world.log().error("Failed to create TCP socket\n");
_net_sock.close();
}
+ _world.log().info(Raul::fmt("Listening on TCP port %1%\n") % port);
start();
}