Refactor to reduce duplicated code

This commit is contained in:
Joshua Baker 2024-12-16 13:13:24 -06:00
parent 2c5093321f
commit c5d9805379
2 changed files with 63 additions and 65 deletions

View file

@ -8,6 +8,7 @@
#include <string> #include <string>
#include <fstream> #include <fstream>
#include <vector> #include <vector>
#include <expected>
class CConfigImpl; class CConfigImpl;
struct SConfigDefaultValue; struct SConfigDefaultValue;
@ -444,6 +445,12 @@ namespace Hyprlang {
CConfigImpl* impl; CConfigImpl* impl;
enum eGetNextLineFailure {
GETNEXTLINEFAILURE_EOF,
GETNEXTLINEFAILURE_BACKSLASH,
};
std::expected<std::string, eGetNextLineFailure> getNextLine(std::istream& str, int &rawLineNum, int &lineNum);
CParseResult parseLine(std::string line, bool dynamic = false); CParseResult parseLine(std::string line, bool dynamic = false);
CParseResult configSetValueSafe(const std::string& command, const std::string& value); CParseResult configSetValueSafe(const std::string& command, const std::string& value);
CParseResult parseVariable(const std::string& lhs, const std::string& rhs, bool dynamic = false); CParseResult parseVariable(const std::string& lhs, const std::string& rhs, bool dynamic = false);

View file

@ -695,42 +695,29 @@ CParseResult CConfig::parse() {
CParseResult CConfig::parseRawStream(const std::string& stream) { CParseResult CConfig::parseRawStream(const std::string& stream) {
CParseResult result; CParseResult result;
std::string rawLine = ""; int rawLineNum = 0;
int rawLineNum = 0; int lineNum = 0;
std::string line = "";
int lineNum = 0;
std::stringstream str(stream); std::stringstream str(stream);
while (std::getline(str, rawLine)) { while (true) {
line = rawLine; const auto line = getNextLine(str, rawLineNum, lineNum);
lineNum = ++rawLineNum;
bool mergeWithNextLine = rawLine.length() > 0 && rawLine.at(rawLine.length() - 1) == '\\'; if (!line) {
bool gotWholeLine = true; switch (line.error()) {
case GETNEXTLINEFAILURE_EOF:
while (mergeWithNextLine) { break;
const auto lastNonSpace = line.length() < 2 ? -1 : line.find_last_not_of(MULTILINE_SPACE_CHARSET, line.length() - 2); case GETNEXTLINEFAILURE_BACKSLASH:
line = line.substr(0, lastNonSpace + 1); if (!impl->parseError.empty())
impl->parseError += "\n";
if (!std::getline(str, rawLine)) { impl->parseError += std::format("Config error: Last line ends with backslash");
if (!impl->parseError.empty()) result.setError(impl->parseError);
impl->parseError += "\n"; break;
impl->parseError += "Config error: Last line ends with backslash";
result.setError(impl->parseError);
gotWholeLine = false;
break;
} }
break;
++rawLineNum;
line += rawLine;
mergeWithNextLine = line.length() > 0 && line.at(line.length() - 1) == '\\';
} }
if (!gotWholeLine) const auto RET = parseLine(line.value());
break;
const auto RET = parseLine(line);
if (RET.error && (impl->parseError.empty() || impl->configOptions.throwAllErrors)) { if (RET.error && (impl->parseError.empty() || impl->configOptions.throwAllErrors)) {
if (!impl->parseError.empty()) if (!impl->parseError.empty())
@ -738,9 +725,6 @@ CParseResult CConfig::parseRawStream(const std::string& stream) {
impl->parseError += std::format("Config error at line {}: {}", lineNum, RET.errorStdString); impl->parseError += std::format("Config error at line {}: {}", lineNum, RET.errorStdString);
result.setError(impl->parseError); result.setError(impl->parseError);
} }
lineNum = rawLineNum + 1;
line = "";
} }
if (!impl->categories.empty()) { if (!impl->categories.empty()) {
@ -766,40 +750,27 @@ CParseResult CConfig::parseFile(const char* file) {
return result; return result;
} }
std::string rawLine = ""; int rawLineNum = 0;
int rawLineNum = 0; int lineNum = 0;
std::string line = "";
int lineNum = 0;
while (std::getline(iffile, rawLine)) { while (true) {
line = rawLine; const auto line = getNextLine(iffile, rawLineNum, lineNum);
lineNum = ++rawLineNum;
bool mergeWithNextLine = rawLine.length() > 0 && rawLine.at(rawLine.length() - 1) == '\\'; if (!line) {
bool gotWholeLine = true; switch (line.error()) {
case GETNEXTLINEFAILURE_EOF:
while (mergeWithNextLine) { break;
const auto lastNonSpace = line.length() < 2 ? -1 : line.find_last_not_of(MULTILINE_SPACE_CHARSET, line.length() - 2); case GETNEXTLINEFAILURE_BACKSLASH:
line = line.substr(0, lastNonSpace + 1); if (!impl->parseError.empty())
impl->parseError += "\n";
if (!std::getline(iffile, rawLine)) { impl->parseError += std::format("Config error in file {}: Last line ends with backslash", file);
if (!impl->parseError.empty()) result.setError(impl->parseError);
impl->parseError += "\n"; break;
impl->parseError += std::format("Config error in file {}: Last line ends with backslash", file);
result.setError(impl->parseError);
gotWholeLine = false;
break;
} }
break;
++rawLineNum;
line += rawLine;
mergeWithNextLine = line.length() > 0 && line.at(line.length() - 1) == '\\';
} }
if (!gotWholeLine) const auto RET = parseLine(line.value());
break;
const auto RET = parseLine(line);
if (!impl->currentFlags.noError && RET.error && (impl->parseError.empty() || impl->configOptions.throwAllErrors)) { if (!impl->currentFlags.noError && RET.error && (impl->parseError.empty() || impl->configOptions.throwAllErrors)) {
if (!impl->parseError.empty()) if (!impl->parseError.empty())
@ -807,9 +778,6 @@ CParseResult CConfig::parseFile(const char* file) {
impl->parseError += std::format("Config error in file {} at line {}: {}", file, lineNum, RET.errorStdString); impl->parseError += std::format("Config error in file {} at line {}: {}", file, lineNum, RET.errorStdString);
result.setError(impl->parseError); result.setError(impl->parseError);
} }
lineNum = rawLineNum + 1;
line = "";
} }
iffile.close(); iffile.close();
@ -828,6 +796,29 @@ CParseResult CConfig::parseFile(const char* file) {
return result; return result;
} }
std::expected<std::string, CConfig::eGetNextLineFailure> CConfig::getNextLine(std::istream& str, int &rawLineNum, int &lineNum) {
std::string line = "";
std::string nextLine = "";
if (!std::getline(str, line))
return std::unexpected(GETNEXTLINEFAILURE_EOF);
lineNum = ++rawLineNum;
while (line.length() > 0 && line.at(line.length() - 1) == '\\') {
const auto lastNonSpace = line.length() < 2 ? -1 : line.find_last_not_of(MULTILINE_SPACE_CHARSET, line.length() - 2);
line = line.substr(0, lastNonSpace + 1);
if (!std::getline(str, nextLine))
return std::unexpected(GETNEXTLINEFAILURE_BACKSLASH);
++rawLineNum;
line += nextLine;
}
return line;
}
CParseResult CConfig::parseDynamic(const char* line) { CParseResult CConfig::parseDynamic(const char* line) {
return parseLine(line, true); return parseLine(line, true);
} }