From ffc65e0f06826ebda94d18f7947f02f6a1954969 Mon Sep 17 00:00:00 2001 From: Robert Bendun Date: Fri, 16 Dec 2022 11:38:05 +0100 Subject: [PATCH] Musique configuration file --- musique/config.cc | 56 ++++++++++++++++++++++++++++++++++++++++ musique/config.hh | 19 ++++++++++++++ musique/main.cc | 28 ++++++++++++++++++-- musique/platform.hh | 19 ++++++++++++++ server/musique-bridge.go | 5 +++- 5 files changed, 124 insertions(+), 3 deletions(-) create mode 100644 musique/config.cc create mode 100644 musique/config.hh create mode 100644 musique/platform.hh diff --git a/musique/config.cc b/musique/config.cc new file mode 100644 index 0000000..55d86d0 --- /dev/null +++ b/musique/config.cc @@ -0,0 +1,56 @@ +#include +#include +#include +#include +#include + +// FIXME Move trim to some header +extern void trim(std::string_view &s); + +// FIXME Report errors when parsing fails +config::Sections config::from_file(std::string const& path) +{ + Sections sections; + Key_Value *kv = §ions[""]; + + std::ifstream in(path); + for (std::string linebuf; std::getline(in, linebuf); ) { + std::string_view line = linebuf; + trim(line); + + if (auto comment = line.find('#'); comment != std::string_view::npos) { + line = line.substr(0, comment); + } + + if (line.starts_with('[') && line.ends_with(']')) { + kv = §ions[std::string(line.begin()+1, line.end()-1)]; + continue; + } + + if (auto split = line.find('='); split != std::string_view::npos) { + auto key = line.substr(0, split); + auto val = line.substr(split+1); + trim(key); + trim(val); + (*kv)[std::string(key)] = std::string(val); + } + } + + return sections; +} + + +std::string config::location() +{ + if constexpr (Current_Platform == Platform::Linux) { + if (auto config_dir = getenv("XDG_CONFIG_HOME")) { + return config_dir + std::string("/musique.conf"); + } else if (auto home_dir = getenv("HOME")) { + return std::string(home_dir) + "/.config/musique.conf"; + } else { + unimplemented("Neither XDG_CONFIG_HOME nor HOME enviroment variable are defined"); + } + } else { + unimplemented(); + } +} diff --git a/musique/config.hh b/musique/config.hh new file mode 100644 index 0000000..7d8a8cb --- /dev/null +++ b/musique/config.hh @@ -0,0 +1,19 @@ +#ifndef MUSIQUE_CONFIG_HH +#define MUSIQUE_CONFIG_HH + +#include +#include +#include + +// Parses INI files +namespace config +{ + using Key_Value = std::unordered_map; + using Sections = std::unordered_map; + + Sections from_file(std::string const& path); + + std::string location(); +} + +#endif // MUSIQUE_CONFIG_HH diff --git a/musique/main.cc b/musique/main.cc index 9a70f87..30784e8 100644 --- a/musique/main.cc +++ b/musique/main.cc @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -37,6 +38,8 @@ static bool quiet_mode = false; static bool ast_only_mode = false; static bool enable_repl = false; static unsigned repl_line_number = 1; +static std::string nick; +static int port; #define Ignore(Call) do { auto const ignore_ ## __LINE__ = (Call); (void) ignore_ ## __LINE__; } while(0) @@ -107,7 +110,7 @@ void print_repl_help() } /// Trim spaces from left an right -static void trim(std::string_view &s) +void trim(std::string_view &s) { // left trim if (auto const i = std::find_if_not(s.begin(), s.end(), unicode::is_space); i != s.begin()) { @@ -173,7 +176,10 @@ struct Runner ensure(the == nullptr, "Only one instance of runner is supported"); the = this; - ServerInit(); + + GoInt goport = port; + GoString gonick { .p = nick.data(), .n = ptrdiff_t(nick.size()) }; + ServerInit(gonick, goport); interpreter.midi_connection = &midi; if (output_port) { @@ -452,6 +458,24 @@ static std::optional Main(std::span args) std::exit(1); } + // TODO Write configuration + // TODO Nicer configuration interface (maybe paths?) + auto config = config::from_file(config::location()); + if (config.contains("net") && config["net"].contains("nick")) { + nick = config["net"]["nick"]; + } else { + std::cout << "Please enter your nick: "; + std::getline(std::cin, nick); + } + + if (config.contains("net") && config["net"].contains("port")) { + auto const& port_str = config["net"]["port"]; + // FIXME Handle port number parsing errors + std::from_chars(port_str.data(), port_str.data() + port_str.size(), port); + } else { + port = 8081; + } + Runner runner{output_port}; for (auto const& [type, argument] : runnables) { diff --git a/musique/platform.hh b/musique/platform.hh new file mode 100644 index 0000000..5eddbf9 --- /dev/null +++ b/musique/platform.hh @@ -0,0 +1,19 @@ +#ifndef MUSIQUE_PLATFORM_HH +#define MUSIQUE_PLATFORM_HH + +enum class Platform +{ + Darwin, + Linux, + Windows, +}; + +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) + static constexpr Platform Current_Platform = Platform::Windows; +#elif __APPLE__ + static constexpr Platform Current_Platform = Platform::Darwin; +#else + static constexpr Platform Current_Platform = Platform::Linux; +#endif + +#endif // MUSIQUE_PLATFORM_HH diff --git a/server/musique-bridge.go b/server/musique-bridge.go index 2e44747..55d7cdf 100644 --- a/server/musique-bridge.go +++ b/server/musique-bridge.go @@ -10,7 +10,10 @@ import ( ) //export ServerInit -func ServerInit() { +func ServerInit(inputNick string, inputPort int) { + nick = inputNick + port = inputPort + r := router.Router{} registerRoutes(&r) _, err := r.Run(baseIP, uint16(port))