mirror of
https://github.com/hyprwm/hyprlock.git
synced 2024-12-22 13:29:48 +01:00
config: add source parsing (#28)
* config: add source parsing * config: add nested source parsing * config: streamlined absolutePath impl
This commit is contained in:
parent
59997a7c38
commit
2fc23cbfc8
4 changed files with 95 additions and 1 deletions
|
@ -1,5 +1,20 @@
|
|||
#include "ConfigManager.hpp"
|
||||
#include "../helpers/MiscFunctions.hpp"
|
||||
#include <filesystem>
|
||||
#include <glob.h>
|
||||
#include <cstring>
|
||||
|
||||
static Hyprlang::CParseResult handleSource(const char* c, const char* v) {
|
||||
const std::string VALUE = v;
|
||||
const std::string COMMAND = c;
|
||||
|
||||
const auto RESULT = g_pConfigManager->handleSource(COMMAND, VALUE);
|
||||
|
||||
Hyprlang::CParseResult result;
|
||||
if (RESULT.has_value())
|
||||
result.setError(RESULT.value().c_str());
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::string getConfigDir() {
|
||||
static const char* xdgConfigHome = getenv("XDG_CONFIG_HOME");
|
||||
|
@ -15,7 +30,7 @@ static std::string getMainConfigPath() {
|
|||
}
|
||||
|
||||
CConfigManager::CConfigManager() : m_config(getMainConfigPath().c_str(), Hyprlang::SConfigOptions{.throwAllErrors = true, .allowMissingConfig = true}) {
|
||||
;
|
||||
configCurrentPath = getMainConfigPath();
|
||||
}
|
||||
|
||||
void CConfigManager::init() {
|
||||
|
@ -62,6 +77,8 @@ void CConfigManager::init() {
|
|||
m_config.addSpecialConfigValue("label", "halign", Hyprlang::STRING{"none"});
|
||||
m_config.addSpecialConfigValue("label", "valign", Hyprlang::STRING{"none"});
|
||||
|
||||
m_config.registerHandler(&::handleSource, "source", {false});
|
||||
|
||||
m_config.commence();
|
||||
|
||||
auto result = m_config.parse();
|
||||
|
@ -149,3 +166,48 @@ std::vector<CConfigManager::SWidgetConfig> CConfigManager::getWidgetConfigs() {
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::optional<std::string> CConfigManager::handleSource(const std::string& command, const std::string& rawpath) {
|
||||
if (rawpath.length() < 2) {
|
||||
Debug::log(ERR, "source= path garbage");
|
||||
return "source path " + rawpath + " bogus!";
|
||||
}
|
||||
std::unique_ptr<glob_t, void (*)(glob_t*)> glob_buf{new glob_t, [](glob_t* g) { globfree(g); }};
|
||||
memset(glob_buf.get(), 0, sizeof(glob_t));
|
||||
|
||||
if (auto r = glob(absolutePath(rawpath, configCurrentPath)->c_str(), GLOB_TILDE, nullptr, glob_buf.get()); r != 0) {
|
||||
std::string err = std::format("source= globbing error: {}", r == GLOB_NOMATCH ? "found no match" : GLOB_ABORTED ? "read error" : "out of memory");
|
||||
Debug::log(ERR, "{}", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < glob_buf->gl_pathc; i++) {
|
||||
auto pathValueOpt = absolutePath(glob_buf->gl_pathv[i], configCurrentPath);
|
||||
if (pathValueOpt->empty()) {
|
||||
Debug::log(WARN, "source= skipping invalid path");
|
||||
continue;
|
||||
}
|
||||
|
||||
auto pathValue = pathValueOpt.value();
|
||||
|
||||
if (!std::filesystem::is_regular_file(pathValue)) {
|
||||
if (std::filesystem::exists(pathValue)) {
|
||||
Debug::log(WARN, "source= skipping non-file {}", pathValue);
|
||||
continue;
|
||||
}
|
||||
|
||||
Debug::log(ERR, "source= file doesnt exist");
|
||||
return "source file " + pathValue + " doesn't exist!";
|
||||
}
|
||||
|
||||
// allow for nested config parsing
|
||||
auto backupConfigPath = configCurrentPath;
|
||||
configCurrentPath = pathValue;
|
||||
|
||||
m_config.parseFile(pathValue.c_str());
|
||||
|
||||
configCurrentPath = backupConfigPath;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
|
@ -22,6 +22,9 @@ class CConfigManager {
|
|||
};
|
||||
|
||||
std::vector<SWidgetConfig> getWidgetConfigs();
|
||||
std::optional<std::string> handleSource(const std::string&, const std::string&);
|
||||
|
||||
std::string configCurrentPath;
|
||||
|
||||
private:
|
||||
Hyprlang::CConfig m_config;
|
||||
|
|
23
src/helpers/MiscFunctions.cpp
Normal file
23
src/helpers/MiscFunctions.cpp
Normal file
|
@ -0,0 +1,23 @@
|
|||
#include <filesystem>
|
||||
#include "MiscFunctions.hpp"
|
||||
|
||||
std::optional<std::string> absolutePath(const std::string& rawpath, const std::string& rawcurrentpath) {
|
||||
std::filesystem::path path(rawpath);
|
||||
|
||||
// Handling where rawpath starts with '~'
|
||||
if (!rawpath.empty() && rawpath[0] == '~') {
|
||||
static const char* const ENVHOME = getenv("HOME");
|
||||
return std::filesystem::path(ENVHOME) / path.relative_path().string().substr(2);
|
||||
}
|
||||
// Handling e.g. ./, ../
|
||||
else if (path.is_relative()) {
|
||||
const std::filesystem::path currentDir = std::filesystem::path(rawcurrentpath).parent_path();
|
||||
|
||||
auto finalPath = currentDir / path;
|
||||
if (exists(finalPath))
|
||||
return std::filesystem::canonical(currentDir / path);
|
||||
return {};
|
||||
} else {
|
||||
return std::filesystem::canonical(path);
|
||||
}
|
||||
}
|
6
src/helpers/MiscFunctions.hpp
Normal file
6
src/helpers/MiscFunctions.hpp
Normal file
|
@ -0,0 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <optional>
|
||||
|
||||
std::optional<std::string> absolutePath(const std::string&, const std::string&);
|
Loading…
Reference in a new issue