diff --git a/src/makefile b/src/makefile index e7a8320..323e0c4 100644 --- a/src/makefile +++ b/src/makefile @@ -1,10 +1,12 @@ CXX = g++ CXXFLAGS = -std=c++17 -Wall +TEST_LIBS = -lmd4c-html -lCatch2Main -lCatch2 +LIBS = -lmd4c-html all: blog -blog: main.o config.o - $(CXX) $(CXXFLAGS) main.o config.o -o blog +blog: main.o config.o utils.o + $(CXX) $(CXXFLAGS) main.o config.o -o blog $(LIBS) main.o: main.cpp config.hpp $(CXX) $(CXXFLAGS) -c main.cpp @@ -12,8 +14,11 @@ main.o: main.cpp config.hpp config.o: config.cpp config.hpp $(CXX) $(CXXFLAGS) -c config.cpp -tests: tests.o config.o - g++ -std=c++17 -Wall tests.o config.o -o tests -lCatch2Main -lCatch2 +utils.o: utils.cpp utils.hpp + $(CXX) $(CXXFLAGS) -c utils.cpp + +tests: tests.o config.o utils.o + g++ -std=c++17 -Wall tests.o config.o utils.o -o tests $(TEST_LIBS) tests.o: tests.cpp config.hpp $(CXX) $(CXXFLAGS) -c tests.cpp diff --git a/src/tests.cpp b/src/tests.cpp index bf7e992..2778254 100644 --- a/src/tests.cpp +++ b/src/tests.cpp @@ -1,4 +1,5 @@ #include "config.hpp" +#include "utils.hpp" #include #include #include @@ -14,3 +15,9 @@ TEST_CASE("Checking config file read", "[config]") { REQUIRE(config.general.lang == "en"); REQUIRE(config.general.title == "Blog"); } + +TEST_CASE("convert_string_to_set parses inline YAML string list") { + const std::string input = "[\"haha\", \"dupa\", \"xdd\"]"; + const std::set output = {"haha", "dupa", "xdd"}; + REQUIRE(convert_string_to_set(input) == output); +} diff --git a/src/utils.cpp b/src/utils.cpp new file mode 100644 index 0000000..fd6977f --- /dev/null +++ b/src/utils.cpp @@ -0,0 +1,37 @@ +#include +#include +#include + +void trim(std::string &str) { + str.erase(str.find_last_not_of(' ') + 1); + str.erase(0, str.find_first_not_of(' ')); +} + +std::set convert_string_to_set(std::string input) { + std::set result; + std::string buffer; + size_t left, right; + left = input.find_first_of('['); + right = input.find_last_of(']'); + + if (left == std::string::npos || right == std::string::npos || + right <= left) { + return result; + } + + input = input.substr(left + 1, right - left - 1); + + std::stringstream ss(input); + + while (getline(ss, buffer, ',')) { + buffer.erase(0, buffer.find_first_not_of(" \t")); + buffer.erase(buffer.find_last_not_of(" \t") + 1); + + if (buffer.size() >= 2 && buffer.front() == '"' && buffer.back() == '"') { + buffer = buffer.substr(1, buffer.size() - 2); + result.insert(buffer); + } + } + + return result; +} diff --git a/src/utils.hpp b/src/utils.hpp new file mode 100644 index 0000000..30c1aba --- /dev/null +++ b/src/utils.hpp @@ -0,0 +1,21 @@ +#include +#include + +// trim string in-place, removing all whitespaces +void trim(std::string &str); + +// Convert a string containing an inline YAML/JSON-style list of strings +// into a std::set. +// +// Supported format (single line): +// ["haha", "dupa", "xdd"] +// +// Limitations: +// - no nested structures +// - no escaping inside strings +// - elements must be quoted +// +// Example: +// Input: ["haha", "dupa", "xdd"] +// Output: {"dupa", "haha", "xdd"} // sorted, unique +std::set convert_string_to_set(std::string input);