| @@ -5,4 +5,5 @@ Uses: Microsoft/wil | |||
| Uses: Niebler/range-v3 | |||
| Uses: nlohmann/json | |||
| Uses: neo/buffer | |||
| Uses: neo/sqlite3 | |||
| Uses: neo/sqlite3 | |||
| Uses: semver/semver | |||
| @@ -7,5 +7,6 @@ Depends: ms-wil 2019.11.10 | |||
| Depends: range-v3 0.9.1 | |||
| Depends: nlohmann-json 3.7.1 | |||
| Depends: neo-sqlite3 0.2.0 | |||
| Depends: semver 0.1.0 | |||
| Test-Driver: Catch-Main | |||
| @@ -9,4 +9,6 @@ Remote-Package: ms-wil 2019.11.10; git url=https://github.com/vector-of-bool/wil | |||
| # XXX: Don't depend on a moving revision! | |||
| Remote-Package: neo-buffer 0.1.0; git url=https://github.com/vector-of-bool/neo-buffer.git ref=develop | |||
| Remote-Package: neo-sqlite3 0.2.0; git url=https://github.com/vector-of-bool/neo-sqlite3.git ref=0.2.0 | |||
| Remote-Package: semver 0.1.0; git url=https://github.com/vector-of-bool/semver.git ref=0.1.0 | |||
| @@ -3,6 +3,7 @@ | |||
| #include <dds/util/fs.hpp> | |||
| #include <string> | |||
| #include <vector> | |||
| #include <string_view> | |||
| namespace dds { | |||
| @@ -1,76 +0,0 @@ | |||
| #include "./version.hpp" | |||
| #include <algorithm> | |||
| #include <array> | |||
| #include <cassert> | |||
| #include <charconv> | |||
| using namespace semver; | |||
| using siter = std::string_view::iterator; | |||
| namespace { | |||
| version parse(const char* ptr, std::size_t size) { | |||
| version ret; | |||
| // const auto str_begin = ptr; | |||
| const auto str_end = ptr + size; | |||
| std::from_chars_result fc_res; | |||
| auto did_error = [&](int elem) { return fc_res.ec == std::errc::invalid_argument || elem < 0; }; | |||
| // Parse major | |||
| fc_res = std::from_chars(ptr, str_end, ret.major); | |||
| if (did_error(ret.major) || fc_res.ptr == str_end || *fc_res.ptr != '.') { | |||
| throw invalid_version(0); | |||
| } | |||
| // Parse minor | |||
| ptr = fc_res.ptr + 1; | |||
| fc_res = std::from_chars(ptr, str_end, ret.minor); | |||
| if (did_error(ret.minor) || fc_res.ptr == str_end || *fc_res.ptr != '.') { | |||
| throw invalid_version(ptr - str_end); | |||
| } | |||
| // Parse patch | |||
| ptr = fc_res.ptr + 1; | |||
| fc_res = std::from_chars(ptr, str_end, ret.patch); | |||
| if (did_error(ret.patch)) { | |||
| throw invalid_version(ptr - str_end); | |||
| } | |||
| if (fc_res.ptr != str_end) { | |||
| assert(false && "More complex version numbers are not ready yet!"); | |||
| throw invalid_version(-42); | |||
| } | |||
| return ret; | |||
| } | |||
| } // namespace | |||
| version version::parse(std::string_view s) { return ::parse(s.data(), s.size()); } | |||
| std::string version::to_string() const noexcept { | |||
| std::array<char, 256> buffer; | |||
| const auto buf_begin = buffer.data(); | |||
| auto buf_ptr = buf_begin; | |||
| const auto buf_end = buf_ptr + buffer.size(); | |||
| auto conv_one = [&](auto n) { | |||
| auto tc_res = std::to_chars(buf_ptr, buf_end, n); | |||
| if (tc_res.ec == std::errc::value_too_large || tc_res.ptr == buf_end) { | |||
| assert(false && "Our buffers weren't big enough! This is a bug!"); | |||
| std::terminate(); | |||
| } | |||
| buf_ptr = tc_res.ptr; | |||
| }; | |||
| conv_one(major); | |||
| *buf_ptr++ = '.'; | |||
| conv_one(minor); | |||
| *buf_ptr++ = '.'; | |||
| conv_one(patch); | |||
| return std::string(buf_begin, (buf_ptr - buf_begin)); | |||
| } | |||
| @@ -1,45 +0,0 @@ | |||
| #pragma once | |||
| #include <stdexcept> | |||
| #include <string> | |||
| #include <string_view> | |||
| #include <tuple> | |||
| #include <vector> | |||
| namespace semver { | |||
| class invalid_version : public std::runtime_error { | |||
| std::ptrdiff_t _offset = 0; | |||
| public: | |||
| invalid_version(std::ptrdiff_t n) | |||
| : runtime_error("Invalid version number") | |||
| , _offset(n) {} | |||
| auto offset() const noexcept { return _offset; } | |||
| }; | |||
| struct version { | |||
| int major = 0; | |||
| int minor = 0; | |||
| int patch = 0; | |||
| static version parse(std::string_view s); | |||
| std::string to_string() const noexcept; | |||
| auto tie() const noexcept { return std::tie(major, minor, patch); } | |||
| auto tie() noexcept { return std::tie(major, minor, patch); } | |||
| }; | |||
| inline bool operator!=(const version& lhs, const version& rhs) noexcept { | |||
| return lhs.tie() != rhs.tie(); | |||
| } | |||
| inline bool operator<(const version& lhs, const version& rhs) noexcept { | |||
| return lhs.tie() < rhs.tie(); | |||
| } | |||
| inline std::string to_string(const version& ver) noexcept { return ver.to_string(); } | |||
| } // namespace semver | |||
| @@ -1,16 +0,0 @@ | |||
| #include "./version.hpp" | |||
| #include <catch2/catch.hpp> | |||
| TEST_CASE("Parsing") { | |||
| auto v1 = semver::version::parse("1.2.3"); | |||
| CHECK(v1.major == 1); | |||
| CHECK(v1.minor == 2); | |||
| CHECK(v1.patch == 3); | |||
| CHECK(v1.to_string() == "1.2.3"); | |||
| v1.patch = 55; | |||
| CHECK(v1.to_string() == "1.2.55"); | |||
| v1.major = 999999; | |||
| CHECK(v1.to_string() == "999999.2.55"); | |||
| } | |||
| @@ -1,9 +1,10 @@ | |||
| Compiler-ID: GNU | |||
| C++-Version: C++17 | |||
| C-Compiler: gcc-8 | |||
| C++-Compiler: g++-8 | |||
| C-Compiler: gcc-9 | |||
| C++-Compiler: g++-9 | |||
| Flags: -D SPDLOG_COMPILED_LIB -fconcepts -Werror=return-type | |||
| Optimize: True | |||
| # Debug: True | |||
| # Optimize: True | |||
| Debug: True | |||
| # Link-Flags: -fsanitize=address | |||
| Link-Flags: -fuse-ld=lld | |||
| Compiler-Launcher: ccache | |||