Skip to content
Snippets Groups Projects
Commit f6adcb24 authored by Nicolas Pope's avatar Nicolas Pope
Browse files

Improve config file search process and generalise

parent ac736fa0
No related branches found
No related tags found
No related merge requests found
......@@ -4,11 +4,18 @@
#include <nlohmann/json.hpp>
#include <string>
#include <vector>
#include <optional>
namespace ftl {
extern nlohmann::json config;
bool is_directory(const std::string &path);
bool is_file(const std::string &path);
bool create_directory(const std::string &path);
std::optional<std::string> locateFile(const std::string &name, const std::vector<std::string> &paths);
std::vector<std::string> configure(int argc, char **argv, const std::string &app);
};
......
#include <glog/logging.h>
#include <ftl/config.h>
#ifdef WIN32
#include <windows.h>
#else
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#endif
#include <nlohmann/json.hpp>
#include <ftl/configuration.hpp>
......@@ -14,6 +22,9 @@ using std::ifstream;
using std::string;
using std::map;
using std::vector;
using std::optional;
using ftl::is_file;
using ftl::is_directory;
// Store loaded configuration
namespace ftl {
......@@ -22,6 +33,67 @@ json config;
using ftl::config;
bool ftl::is_directory(const std::string &path) {
#ifdef WIN32
DWORD attrib = GetFileAttributesA(path.c_str());
if (attrib == INVALID_FILE_ATTRIBUTES) return false;
else return (attrib & FILE_ATTRIBUTE_DIRECTORY);
#else
struct stat s;
if (::stat(path.c_str(), &s) == 0) {
return S_ISDIR(s.st_mode);
} else {
return false;
}
#endif
}
bool ftl::is_file(const std::string &path) {
#ifdef WIN32
DWORD attrib = GetFileAttributesA(path.c_str());
if (attrib == INVALID_FILE_ATTRIBUTES) return false;
else return !(attrib & FILE_ATTRIBUTE_DIRECTORY);
#else
struct stat s;
if (::stat(path.c_str(), &s) == 0) {
return S_ISREG(s.st_mode);
} else {
return false;
}
#endif
}
bool ftl::create_directory(const std::string &path) {
#ifdef WIN32
// TODO(nick)
#else
if (!is_directory(path)) {
int err = ::mkdir(path.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
return err != -1;
}
return true;
#endif
}
optional<string> locateFile(const string &name, const vector<string> &paths) {
for (auto p : paths) {
if (is_directory(p)) {
if (is_file(p+"/"+name)) {
return p+"/"+name;
}
} else if (p.size() >= name.size() &&
p.compare(p.size() - name.size(), name.size(), name) == 0 &&
is_file(p)) {
return p;
}
}
if (is_file("./"+name)) return "./"+name;
if (is_file(string(FTL_LOCAL_CONFIG_ROOT) +"/"+ name)) return string(FTL_LOCAL_CONFIG_ROOT) +"/"+ name;
if (is_file(string(FTL_GLOBAL_CONFIG_ROOT) +"/"+ name)) return string(FTL_GLOBAL_CONFIG_ROOT) +"/"+ name;
return {};
}
/**
* Find and load a JSON configuration file
*/
......@@ -30,10 +102,15 @@ static bool findConfiguration(const string &file, const vector<string> &paths,
ifstream i;
if (file != "") i.open(file);
if (!i.is_open()) i.open("./config.json");
if (!i.is_open()) i.open(FTL_LOCAL_CONFIG_ROOT "/config.json");
if (!i.is_open()) i.open(FTL_GLOBAL_CONFIG_ROOT "/config.json");
if (!i.is_open()) {
auto f = locateFile("config.json", paths);
if (!f) return false;
i.open(*f);
}
if (!i.is_open()) return false;
i >> config;
config = config[app];
return true;
......@@ -53,7 +130,13 @@ static map<string, string> read_options(char ***argv, int *argc) {
if ((p = cmd.find("=")) == string::npos) {
opts[cmd.substr(2)] = "true";
} else {
opts[cmd.substr(2, p-2)] = cmd.substr(p+1);
auto val = cmd.substr(p+1);
if (std::isdigit(val[0]) || val == "true" || val == "false" || val == "null") {
opts[cmd.substr(2, p-2)] = val;
} else {
if (val[0] == '\\') opts[cmd.substr(2, p-2)] = val;
else opts[cmd.substr(2, p-2)] = "\""+val+"\"";
}
}
(*argc)--;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment