Musique configuration file

This commit is contained in:
Robert Bendun 2022-12-16 11:38:05 +01:00
parent 40ef949dbe
commit ffc65e0f06
5 changed files with 124 additions and 3 deletions

56
musique/config.cc Normal file
View File

@ -0,0 +1,56 @@
#include <fstream>
#include <iterator>
#include <musique/config.hh>
#include <musique/errors.hh>
#include <musique/platform.hh>
// 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 = &sections[""];
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 = &sections[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();
}
}

19
musique/config.hh Normal file
View File

@ -0,0 +1,19 @@
#ifndef MUSIQUE_CONFIG_HH
#define MUSIQUE_CONFIG_HH
#include <optional>
#include <string>
#include <unordered_map>
// Parses INI files
namespace config
{
using Key_Value = std::unordered_map<std::string, std::string>;
using Sections = std::unordered_map<std::string, Key_Value>;
Sections from_file(std::string const& path);
std::string location();
}
#endif // MUSIQUE_CONFIG_HH

View File

@ -17,6 +17,7 @@
#include <musique/try.hh> #include <musique/try.hh>
#include <musique/unicode.hh> #include <musique/unicode.hh>
#include <musique/value/block.hh> #include <musique/value/block.hh>
#include <musique/config.hh>
#include <server.h> #include <server.h>
@ -37,6 +38,8 @@ static bool quiet_mode = false;
static bool ast_only_mode = false; static bool ast_only_mode = false;
static bool enable_repl = false; static bool enable_repl = false;
static unsigned repl_line_number = 1; 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) #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 /// Trim spaces from left an right
static void trim(std::string_view &s) void trim(std::string_view &s)
{ {
// left trim // left trim
if (auto const i = std::find_if_not(s.begin(), s.end(), unicode::is_space); i != s.begin()) { 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"); ensure(the == nullptr, "Only one instance of runner is supported");
the = this; the = this;
ServerInit();
GoInt goport = port;
GoString gonick { .p = nick.data(), .n = ptrdiff_t(nick.size()) };
ServerInit(gonick, goport);
interpreter.midi_connection = &midi; interpreter.midi_connection = &midi;
if (output_port) { if (output_port) {
@ -452,6 +458,24 @@ static std::optional<Error> Main(std::span<char const*> args)
std::exit(1); 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}; Runner runner{output_port};
for (auto const& [type, argument] : runnables) { for (auto const& [type, argument] : runnables) {

19
musique/platform.hh Normal file
View File

@ -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

View File

@ -10,7 +10,10 @@ import (
) )
//export ServerInit //export ServerInit
func ServerInit() { func ServerInit(inputNick string, inputPort int) {
nick = inputNick
port = inputPort
r := router.Router{} r := router.Router{}
registerRoutes(&r) registerRoutes(&r)
_, err := r.Run(baseIP, uint16(port)) _, err := r.Run(baseIP, uint16(port))