Skip to content

Commit

Permalink
core: add options for config parser
Browse files Browse the repository at this point in the history
  • Loading branch information
vaxerski committed Dec 30, 2023
1 parent c69c286 commit 70145fd
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 8 deletions.
11 changes: 10 additions & 1 deletion include/hyprlang.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,15 @@ namespace Hyprlang {
friend class CConfig;
};

/* Generic struct for options for the config parser */
struct SConfigOptions {
/* Don't throw errors on missing values. */
bool verifyOnly = false;

/* Return all errors instead of the first */
bool throwAllErrors = false;
};

/* Generic struct for options for handlers */
struct SHandlerOptions {
bool allowFlags = false;
Expand Down Expand Up @@ -142,7 +151,7 @@ namespace Hyprlang {
/* Base class for a config file */
class CConfig {
public:
CConfig(const char* configPath);
CConfig(const char* configPath, const SConfigOptions& options);
~CConfig();

/* Add a config value, for example myCategory:myValue.
Expand Down
22 changes: 16 additions & 6 deletions src/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ static std::string removeBeginEndSpacesTabs(std::string str) {
return str;
}

CConfig::CConfig(const char* path) {
CConfig::CConfig(const char* path, const Hyprlang::SConfigOptions& options) {
impl = new CConfigImpl;
try {
impl->path = std::filesystem::canonical(path);
Expand All @@ -46,6 +46,8 @@ CConfig::CConfig(const char* path) {
}

std::sort(impl->envVariables.begin(), impl->envVariables.end(), [&](const auto& a, const auto& b) { return a.name.length() > b.name.length(); });

impl->configOptions = options;
}

CConfig::~CConfig() {
Expand Down Expand Up @@ -444,7 +446,7 @@ CParseResult CConfig::parseLine(std::string line, bool dynamic) {
found = true;
}

if (!found)
if (!found && !impl->configOptions.verifyOnly)
ret = configSetValueSafe(LHS, RHS);

if (ret.error)
Expand Down Expand Up @@ -515,9 +517,11 @@ CParseResult CConfig::parseFile(std::string file) {

const auto RET = parseLine(line);

if (RET.error && impl->parseError.empty()) {
impl->parseError = RET.getError();
result.setError(std::format("Config error in file {} at line {}: {}", file, linenum, RET.errorStdString));
if (RET.error && (impl->parseError.empty() || impl->configOptions.throwAllErrors)) {
if (!impl->parseError.empty())
impl->parseError += "\n";
impl->parseError += std::format("Config error in file {} at line {}: {}", file, linenum, RET.errorStdString);
result.setError(impl->parseError);
}

++linenum;
Expand All @@ -526,7 +530,13 @@ CParseResult CConfig::parseFile(std::string file) {
iffile.close();

if (!impl->categories.empty()) {
result.setError("Unclosed category at EOF");
if (impl->parseError.empty() || impl->configOptions.throwAllErrors) {
if (!impl->parseError.empty())
impl->parseError += "\n";
impl->parseError += std::format("Config error in file {}: Unclosed category at EOF", file);
result.setError(impl->parseError);
}

impl->categories.clear();
}

Expand Down
2 changes: 2 additions & 0 deletions src/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,6 @@ class CConfigImpl {
std::string currentSpecialKey = "";

std::string parseError = "";

Hyprlang::SConfigOptions configOptions;
};
6 changes: 6 additions & 0 deletions tests/config/error.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# This config houses two errors

someValue = 123

category {
invalid_line
13 changes: 12 additions & 1 deletion tests/main.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <iostream>
#include <filesystem>
#include <algorithm>

#include <hyprlang.hpp>

Expand Down Expand Up @@ -75,7 +76,7 @@ int main(int argc, char** argv, char** envp) {

std::cout << "Starting test\n";

Hyprlang::CConfig config("./config/config.conf");
Hyprlang::CConfig config("./config/config.conf", {});
pConfig = &config;
currentPath = std::filesystem::canonical("./config/");

Expand Down Expand Up @@ -182,6 +183,16 @@ int main(int argc, char** argv, char** envp) {
std::cout << " → Testing custom types\n";
EXPECT(*reinterpret_cast<int64_t*>(std::any_cast<void*>(config.getConfigValue("customType"))), 1L);

std::cout << " → Testing error.conf\n";
Hyprlang::CConfig errorConfig("./config/error.conf", {.verifyOnly = true, .throwAllErrors = true});

errorConfig.commence();
const auto ERRORS = errorConfig.parse();

EXPECT(ERRORS.error, true);
const auto ERRORSTR = std::string{ERRORS.getError()};
EXPECT(std::count(ERRORSTR.begin(), ERRORSTR.end(), '\n'), 1);

} catch (const char* e) {
std::cout << Colors::RED << "Error: " << Colors::RESET << e << "\n";
return 1;
Expand Down

0 comments on commit 70145fd

Please sign in to comment.