From 4f7ccabba3d2297371241ef628263605e34468cf Mon Sep 17 00:00:00 2001 From: Gaurav Harsha Date: Wed, 25 Feb 2026 15:36:37 -0500 Subject: [PATCH 1/9] refactor grid version checks --- c++/common_defs.cpp | 30 ++++++++++++++ c++/green/grids/common_defs.h | 75 +++++++++++++++++++++-------------- c++/green/grids/except.h | 5 +++ c++/transformer.cpp | 2 +- test/grids_test.cpp | 21 +++++++++- 5 files changed, 100 insertions(+), 33 deletions(-) diff --git a/c++/common_defs.cpp b/c++/common_defs.cpp index 6548637..b203de5 100644 --- a/c++/common_defs.cpp +++ b/c++/common_defs.cpp @@ -16,4 +16,34 @@ namespace green::grids { } return std::filesystem::exists(path) ? path : (std::filesystem::exists(src_path) ? src_path : install_path); } + + void check_grids_version_in_hdf5(const std::string& results_file, const std::string& grid_file_version) { + // If results file does not exist, nothing to check + if (!std::filesystem::exists(results_file)) return; + + h5pp::archive ar(results_file, "r"); + if (ar.has_attribute("__grids_version__")) { + std::string grids_version_in_results; + grids_version_in_results = ar.get_attribute("__grids_version__"); + ar.close(); // safely close before throwing + if (compare_version_strings(grid_file_version, grids_version_in_results) < 0) { + throw outdated_grids_file_error("The current green-grids version (" + grid_file_version + + ") is older than the green-grids version used to create the original results file (" + + grids_version_in_results + + "). Please update green-grids to version " + grids_version_in_results); + } else if (compare_version_strings(grid_file_version, grids_version_in_results) > 0) { + throw outdated_results_file_error("The green-grids version used to create the results file (" + grids_version_in_results + + ") is older than the current specified grid file (" + grid_file_version + + "). Please download the appropriate version from: " + + "https://github.com/Green-Phys/green-grids/releases/ or https://github.com/Green-Phys/green-grids/tags"); + } + } else if (compare_version_strings(grid_file_version, GRIDS_MIN_VERSION) > 0) { + ar.close(); // safely close before throwing + throw outdated_results_file_error("The results file was created using un-versioned grid file (equiv. to " + GRIDS_MIN_VERSION + + ") and the current green-grids version (" + grid_file_version + ") is newer.\n" + + "Please use old grid files from: https://github.com/Green-Phys/green-grids/releases/tag/v0.2.4."); + } else { + ar.close(); + } + } } // namespace green::grids \ No newline at end of file diff --git a/c++/green/grids/common_defs.h b/c++/green/grids/common_defs.h index 7fcc5b6..8423a62 100644 --- a/c++/green/grids/common_defs.h +++ b/c++/green/grids/common_defs.h @@ -8,6 +8,7 @@ #include #include #include +#include #include "except.h" #include @@ -54,39 +55,53 @@ namespace green::grids { std::string grid_path(const std::string& path); - /** - * @brief Check whether a version string satisfies the minimum required GRIDS version. - * - * Compares the given version string against the library's minimum supported - * GRIDS version specified by `GRIDS_MIN_VERSION`. - * - * @param v Version string to check (e.g. "0.2.4"). - * @return true if v is greater than or equal to GRIDS_MIN_VERSION. - * @return false if v is less than GRIDS_MIN_VERSION. - * @throws outdated_grids_file_error if the format of v or GRIDS_MIN_VERSION is incorrect. - */ - inline bool CheckVersion(const std::string& v) { - int major_Vin = 0, minor_Vin = 0, patch_Vin = 0; - int major_Vref = 0, minor_Vref = 0, patch_Vref = 0; - - char suffixV[32] = ""; - char suffixM[32] = ""; - - int parsed_in = std::sscanf(v.c_str(), "%d.%d.%d%30s", &major_Vin, &minor_Vin, &patch_Vin, suffixV); - int parsed_ref = std::sscanf(GRIDS_MIN_VERSION.c_str(), "%d.%d.%d%30s", &major_Vref, &minor_Vref, &patch_Vref, suffixM); + inline int compare_version_strings(const std::string& v1, const std::string& v2) { + int major_V1 = 0, minor_V1 = 0, patch_V1 = 0; + int major_V2 = 0, minor_V2 = 0, patch_V2 = 0; + + char suffix_V1[32] = ""; + char suffix_V2[32] = ""; + + int parsed_1 = std::sscanf(v1.c_str(), "%d.%d.%d%30s", &major_V1, &minor_V1, &patch_V1, suffix_V1); + int parsed_2 = std::sscanf(v2.c_str(), "%d.%d.%d%30s", &major_V2, &minor_V2, &patch_V2, suffix_V2); + + if (parsed_1 < 3) { + throw std::runtime_error("First version string (v1) failed to parse: '" + v1 + "'. Expected format: major.minor.patch[suffix]"); + } + if (parsed_2 < 3) { + throw std::runtime_error("Second version string (v2) failed to parse: '" + v2 + "'. Expected format: major.minor.patch[suffix]"); + } - if (parsed_in < 3 || parsed_ref < 3) { - throw outdated_grids_file_error("Version string format is incorrect. Expected format: major.minor.patch[suffix]"); + if (major_V1 != major_V2) { + return major_V1 > major_V2 ? 1 : -1; } - - if (major_Vin != major_Vref) return major_Vin > major_Vref; - if (minor_Vin != minor_Vref) return minor_Vin > minor_Vref; - if (patch_Vin != patch_Vref) return patch_Vin > patch_Vref; - - // If numeric parts in version are all equal, do not worry about suffix - // e.g., 0.2.4b10 has same integral format as 0.2.4 - return true; + if (minor_V1 != minor_V2) { + return minor_V1 > minor_V2 ? 1 : -1; + } + if (patch_V1 != patch_V2) { + return patch_V1 > patch_V2 ? 1 : -1; + } + + return 0; } + /** + * @brief Checks consistency between grid-file version used in current run vs. the version + * used to generate the results file that is being (re-)started from. + * This is to prevent users from accidentally restarting from a results file that was generated with + * an older version of green-grids, which can lead to silent errors in the results. + * + * 1. If the results file does not have a green-grids version attribute, treat it as having been + * generated with the baseline grids version (GRIDS_MIN_VERSION, currently 0.2.4) and check + * that the current grid-file version is not newer; otherwise an error is raised. + * 2. If the results file has a green-grids version attribute, compare that version with the current + * grid-file version and distinguish older, equal, and newer cases, allowing only compatible + * combinations and throwing specific errors when there is a mismatch. + * + * @param results_file - path to the results file that is being restarted from + * @param grid_file_version - version of green-grids used in the current run (can be obtained from DysonSolver::get_grids_version()) + */ + void check_grids_version_in_hdf5(const std::string& results_file, const std::string& grid_file_version); + } // namespace green::grids #endif // GRIDS_COMMON_DEFS_H diff --git a/c++/green/grids/except.h b/c++/green/grids/except.h index 9fc35ca..32cfc80 100644 --- a/c++/green/grids/except.h +++ b/c++/green/grids/except.h @@ -21,6 +21,11 @@ namespace green::grids { public: explicit outdated_grids_file_error(const std::string& string) : runtime_error(string) {} }; + + class outdated_results_file_error : public std::runtime_error { + public: + explicit outdated_results_file_error(const std::string& what) : std::runtime_error(what) {} + }; } // namespace green::grids #endif // GRIDS_EXCEPT_H diff --git a/c++/transformer.cpp b/c++/transformer.cpp index a2f73e2..91c76a3 100644 --- a/c++/transformer.cpp +++ b/c++/transformer.cpp @@ -51,7 +51,7 @@ namespace green::grids { if (tnl_file.has_attribute("__grids_version__")) { std::string v_str = tnl_file.get_attribute("__grids_version__"); set_version(v_str); - if (!CheckVersion(v_str)) { + if (compare_version_strings(v_str, GRIDS_MIN_VERSION) < 0) { throw outdated_grids_file_error("The grids file version " + v_str + " is outdated. Minimum required version is " + GRIDS_MIN_VERSION + "."); } diff --git a/test/grids_test.cpp b/test/grids_test.cpp index 1beba4f..70a695e 100644 --- a/test/grids_test.cpp +++ b/test/grids_test.cpp @@ -162,8 +162,25 @@ void check_transformer(green::grids::transformer_t& tr) { SECTION("Check Version Info") { std::string v = tr.get_version(); std::string v2 = "0.2.0"; // Older version - REQUIRE(green::grids::CheckVersion(v)); - REQUIRE_FALSE(green::grids::CheckVersion(v2)); + REQUIRE(green::grids::compare_version_strings(v, green::grids::GRIDS_MIN_VERSION) >= 0); + REQUIRE(green::grids::compare_version_strings(v2, green::grids::GRIDS_MIN_VERSION) < 0); + } + SECTION("Check Version Consistency in HDF5 File") { + // 1. Starting with new file (does not exist). + // Version check should pass because there's nothing to check / no inconsistency + std::string res_file = "grids_version_check_file.h5"; + REQUIRE_NOTHROW(green::grids::check_grids_version_in_hdf5(res_file, "0.2.4")); + + // 2. Open the file and add __grids_version__ attribute + green::h5pp::archive ar_res_1(res_file, "w"); + ar_res_1.set_attribute("__grids_version__", "0.2.4"); + ar_res_1.close(); + REQUIRE_NOTHROW(green::grids::check_grids_version_in_hdf5(res_file, green::grids::GRIDS_MIN_VERSION)); + REQUIRE_THROWS_AS(green::grids::check_grids_version_in_hdf5(res_file, "0.2.3"), + green::grids::outdated_grids_file_error); + REQUIRE_THROWS_AS(green::grids::check_grids_version_in_hdf5(res_file, "0.2.5"), + green::grids::outdated_results_file_error); + std::filesystem::remove(res_file); } } From 18a7f3b9ae1e3ed714b8d0f6f0b671f8d70ed4e3 Mon Sep 17 00:00:00 2001 From: Gaurav Harsha Date: Wed, 25 Feb 2026 16:03:13 -0500 Subject: [PATCH 2/9] copilot reviews --- c++/common_defs.cpp | 3 ++- c++/green/grids/common_defs.h | 5 ++--- test/grids_test.cpp | 27 ++++++++++++++++++++++----- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/c++/common_defs.cpp b/c++/common_defs.cpp index b203de5..ded6503 100644 --- a/c++/common_defs.cpp +++ b/c++/common_defs.cpp @@ -3,6 +3,7 @@ * */ +#include #include "green/grids/common_defs.h" #include "green/grids/except.h" @@ -33,7 +34,7 @@ namespace green::grids { "). Please update green-grids to version " + grids_version_in_results); } else if (compare_version_strings(grid_file_version, grids_version_in_results) > 0) { throw outdated_results_file_error("The green-grids version used to create the results file (" + grids_version_in_results + - ") is older than the current specified grid file (" + grid_file_version + + ") is older than the current grid-grids version (" + grid_file_version + "). Please download the appropriate version from: " + "https://github.com/Green-Phys/green-grids/releases/ or https://github.com/Green-Phys/green-grids/tags"); } diff --git a/c++/green/grids/common_defs.h b/c++/green/grids/common_defs.h index 8423a62..0290ba8 100644 --- a/c++/green/grids/common_defs.h +++ b/c++/green/grids/common_defs.h @@ -8,7 +8,6 @@ #include #include #include -#include #include "except.h" #include @@ -66,10 +65,10 @@ namespace green::grids { int parsed_2 = std::sscanf(v2.c_str(), "%d.%d.%d%30s", &major_V2, &minor_V2, &patch_V2, suffix_V2); if (parsed_1 < 3) { - throw std::runtime_error("First version string (v1) failed to parse: '" + v1 + "'. Expected format: major.minor.patch[suffix]"); + throw outdated_grids_file_error("First version string (v1) failed to parse: '" + v1 + "'. Expected format: major.minor.patch[suffix]"); } if (parsed_2 < 3) { - throw std::runtime_error("Second version string (v2) failed to parse: '" + v2 + "'. Expected format: major.minor.patch[suffix]"); + throw outdated_grids_file_error("Second version string (v2) failed to parse: '" + v2 + "'. Expected format: major.minor.patch[suffix]"); } if (major_V1 != major_V2) { diff --git a/test/grids_test.cpp b/test/grids_test.cpp index 70a695e..fdff40d 100644 --- a/test/grids_test.cpp +++ b/test/grids_test.cpp @@ -7,13 +7,26 @@ #include #include -#include -#include +#include #include "tensor_test.h" using namespace std::string_literals; +std::filesystem::path make_temp_h5_path() { + return std::filesystem::temp_directory_path() / std::filesystem::unique_path("grids_version_check_%%%%-%%%%-%%%%.h5"); +} + +struct file_cleanup_guard { + explicit file_cleanup_guard(std::filesystem::path file_path) : path(std::move(file_path)) {} + ~file_cleanup_guard() { + std::error_code ec; + std::filesystem::remove(path, ec); + } + + std::filesystem::path path; +}; + inline std::pair get_argc_argv(std::string& str) { std::string key; std::vector splits = {(char*)str.c_str()}; @@ -168,10 +181,15 @@ void check_transformer(green::grids::transformer_t& tr) { SECTION("Check Version Consistency in HDF5 File") { // 1. Starting with new file (does not exist). // Version check should pass because there's nothing to check / no inconsistency - std::string res_file = "grids_version_check_file.h5"; + std::filesystem::path res_file_path = make_temp_h5_path(); + file_cleanup_guard cleanup(res_file_path); + std::string res_file = res_file_path.string(); REQUIRE_NOTHROW(green::grids::check_grids_version_in_hdf5(res_file, "0.2.4")); - // 2. Open the file and add __grids_version__ attribute + // 2. Open the file and set the __grids_version__ attribute to 0.2.4 + // Then comparing with 0.2.4 should pass; + // comparing with older version should throw outdated_grids_file_error; + // comparing with newer version should throw outdated_results_file_error green::h5pp::archive ar_res_1(res_file, "w"); ar_res_1.set_attribute("__grids_version__", "0.2.4"); ar_res_1.close(); @@ -180,7 +198,6 @@ void check_transformer(green::grids::transformer_t& tr) { green::grids::outdated_grids_file_error); REQUIRE_THROWS_AS(green::grids::check_grids_version_in_hdf5(res_file, "0.2.5"), green::grids::outdated_results_file_error); - std::filesystem::remove(res_file); } } From d2f735a31bbb8689e7a50bba45169b77d83b54dd Mon Sep 17 00:00:00 2001 From: Gaurav Harsha Date: Wed, 25 Feb 2026 16:07:05 -0500 Subject: [PATCH 3/9] safely close hdf5 file in version compare --- c++/common_defs.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/c++/common_defs.cpp b/c++/common_defs.cpp index ded6503..70d44de 100644 --- a/c++/common_defs.cpp +++ b/c++/common_defs.cpp @@ -38,13 +38,13 @@ namespace green::grids { "). Please download the appropriate version from: " + "https://github.com/Green-Phys/green-grids/releases/ or https://github.com/Green-Phys/green-grids/tags"); } - } else if (compare_version_strings(grid_file_version, GRIDS_MIN_VERSION) > 0) { - ar.close(); // safely close before throwing - throw outdated_results_file_error("The results file was created using un-versioned grid file (equiv. to " + GRIDS_MIN_VERSION + - ") and the current green-grids version (" + grid_file_version + ") is newer.\n" + - "Please use old grid files from: https://github.com/Green-Phys/green-grids/releases/tag/v0.2.4."); } else { - ar.close(); + ar.close(); // safely close comparing version strings + if (compare_version_strings(grid_file_version, GRIDS_MIN_VERSION) > 0) { + throw outdated_results_file_error("The results file was created using un-versioned grid file (equiv. to " + GRIDS_MIN_VERSION + + ") and the current green-grids version (" + grid_file_version + ") is newer.\n" + + "Please use old grid files from: https://github.com/Green-Phys/green-grids/releases/tag/v0.2.4."); + } } } } // namespace green::grids \ No newline at end of file From c0deb605654c4ced0b6ad0f0678143d51d57326f Mon Sep 17 00:00:00 2001 From: Gaurav Harsha Date: Wed, 25 Feb 2026 16:13:20 -0500 Subject: [PATCH 4/9] fix filename issue for grid tests --- test/grids_test.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/grids_test.cpp b/test/grids_test.cpp index fdff40d..3e85c44 100644 --- a/test/grids_test.cpp +++ b/test/grids_test.cpp @@ -14,7 +14,8 @@ using namespace std::string_literals; std::filesystem::path make_temp_h5_path() { - return std::filesystem::temp_directory_path() / std::filesystem::unique_path("grids_version_check_%%%%-%%%%-%%%%.h5"); + static int counter = 0; + return std::filesystem::temp_directory_path() / ("grids_version_check_" + std::to_string(counter++) + ".h5"); } struct file_cleanup_guard { From 416a57f8016e18ac900b044b71fc319e94b3d63b Mon Sep 17 00:00:00 2001 From: Gaurav Harsha Date: Wed, 25 Feb 2026 17:18:31 -0500 Subject: [PATCH 5/9] add more test cases for better coverage --- test/grids_test.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/test/grids_test.cpp b/test/grids_test.cpp index 3e85c44..f11abd5 100644 --- a/test/grids_test.cpp +++ b/test/grids_test.cpp @@ -173,11 +173,15 @@ void check_transformer(green::grids::transformer_t& tr) { double leakage = tr.check_chebyshev(X1t, 1); REQUIRE(leakage < 1e-10); } - SECTION("Check Version Info") { + SECTION("Check Comparison of Version Strings") { std::string v = tr.get_version(); std::string v2 = "0.2.0"; // Older version REQUIRE(green::grids::compare_version_strings(v, green::grids::GRIDS_MIN_VERSION) >= 0); REQUIRE(green::grids::compare_version_strings(v2, green::grids::GRIDS_MIN_VERSION) < 0); + REQUIRE(green::grids::compare_version_strings(green::grids::GRIDS_MIN_VERSION, v2) > 0); + REQUIRE_THROWS_AS(green::grids::compare_version_strings("0.1", "0.2.4"), green::grids::outdated_grids_file_error); + REQUIRE_THROWS_AS(green::grids::compare_version_strings("0.2.4", "0.1"), green::grids::outdated_grids_file_error); + REQUIRE_NOTHROW(green::grids::compare_version_strings("0.2.4abce", "0.2.4.xyz")); } SECTION("Check Version Consistency in HDF5 File") { // 1. Starting with new file (does not exist). @@ -186,12 +190,22 @@ void check_transformer(green::grids::transformer_t& tr) { file_cleanup_guard cleanup(res_file_path); std::string res_file = res_file_path.string(); REQUIRE_NOTHROW(green::grids::check_grids_version_in_hdf5(res_file, "0.2.4")); + + // 2. Open file add some data but don't add __grids_version__ + // This mimics the case when results file was created using old grids + // Checking consistency of grids versions should pass if old grids are used, + // otherwise throw an error for new grids + green::h5pp::archive ar_res_0(res_file, "w"); + ar_res_0["One"] << 1.0; + ar_res_0.close(); + REQUIRE_NOTHROW(green::grids::check_grids_version_in_hdf5(res_file, green::grids::GRIDS_MIN_VERSION)); + REQUIRE_THROWS_AS(green::grids::check_grids_version_in_hdf5(res_file, "0.3.0"), green::grids::outdated_results_file_error); - // 2. Open the file and set the __grids_version__ attribute to 0.2.4 + // 3. Open the file and set the __grids_version__ attribute to 0.2.4 // Then comparing with 0.2.4 should pass; // comparing with older version should throw outdated_grids_file_error; // comparing with newer version should throw outdated_results_file_error - green::h5pp::archive ar_res_1(res_file, "w"); + green::h5pp::archive ar_res_1(res_file, "a"); ar_res_1.set_attribute("__grids_version__", "0.2.4"); ar_res_1.close(); REQUIRE_NOTHROW(green::grids::check_grids_version_in_hdf5(res_file, green::grids::GRIDS_MIN_VERSION)); From 4b9b6dfbd4da72b21fc3baccc1a1f2371aaeabe1 Mon Sep 17 00:00:00 2001 From: Gaurav Harsha Date: Wed, 25 Feb 2026 17:31:51 -0500 Subject: [PATCH 6/9] Update c++/common_defs.cpp Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- c++/common_defs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c++/common_defs.cpp b/c++/common_defs.cpp index 70d44de..73132d0 100644 --- a/c++/common_defs.cpp +++ b/c++/common_defs.cpp @@ -34,7 +34,7 @@ namespace green::grids { "). Please update green-grids to version " + grids_version_in_results); } else if (compare_version_strings(grid_file_version, grids_version_in_results) > 0) { throw outdated_results_file_error("The green-grids version used to create the results file (" + grids_version_in_results + - ") is older than the current grid-grids version (" + grid_file_version + + ") is older than the current green-grids version (" + grid_file_version + "). Please download the appropriate version from: " + "https://github.com/Green-Phys/green-grids/releases/ or https://github.com/Green-Phys/green-grids/tags"); } From d2361e26550f3ec879b250432fc6834a53f908e8 Mon Sep 17 00:00:00 2001 From: Gaurav Harsha Date: Wed, 25 Feb 2026 17:32:26 -0500 Subject: [PATCH 7/9] Update c++/common_defs.cpp Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- c++/common_defs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c++/common_defs.cpp b/c++/common_defs.cpp index 73132d0..8fc6d8d 100644 --- a/c++/common_defs.cpp +++ b/c++/common_defs.cpp @@ -43,7 +43,7 @@ namespace green::grids { if (compare_version_strings(grid_file_version, GRIDS_MIN_VERSION) > 0) { throw outdated_results_file_error("The results file was created using un-versioned grid file (equiv. to " + GRIDS_MIN_VERSION + ") and the current green-grids version (" + grid_file_version + ") is newer.\n" + - "Please use old grid files from: https://github.com/Green-Phys/green-grids/releases/tag/v0.2.4."); + "Please use old grid files from: https://github.com/Green-Phys/green-grids/releases/tag/v" GRIDS_MIN_VERSION "."); } } } From 5bacc13ff999265368e24bbf9c4b106d0c9c2218 Mon Sep 17 00:00:00 2001 From: Gaurav Harsha Date: Wed, 25 Feb 2026 17:49:49 -0500 Subject: [PATCH 8/9] modify random file name in testing --- test/grids_test.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/test/grids_test.cpp b/test/grids_test.cpp index f11abd5..99c3dc9 100644 --- a/test/grids_test.cpp +++ b/test/grids_test.cpp @@ -8,14 +8,23 @@ #include #include #include +#include +#include #include "tensor_test.h" using namespace std::string_literals; std::filesystem::path make_temp_h5_path() { - static int counter = 0; - return std::filesystem::temp_directory_path() / ("grids_version_check_" + std::to_string(counter++) + ".h5"); + const auto temp_dir = std::filesystem::temp_directory_path(); + // Use high-resolution timestamp and randomness to avoid filename collisions + const auto now = std::chrono::high_resolution_clock::now().time_since_epoch().count(); + std::random_device rd; + std::mt19937_64 gen(rd()); + std::uniform_int_distribution dist; + const auto rand_val = dist(gen); + const auto filename = "grids_version_check_" + std::to_string(now) + "_" + std::to_string(rand_val) + ".h5"; + return temp_dir / filename; } struct file_cleanup_guard { From a3f6025681396e328915bcf9fe02c6ccf7b3d2fb Mon Sep 17 00:00:00 2001 From: Gaurav Harsha Date: Wed, 25 Feb 2026 18:15:22 -0500 Subject: [PATCH 9/9] fix typo in error message --- c++/common_defs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c++/common_defs.cpp b/c++/common_defs.cpp index 8fc6d8d..5bef6b7 100644 --- a/c++/common_defs.cpp +++ b/c++/common_defs.cpp @@ -43,7 +43,7 @@ namespace green::grids { if (compare_version_strings(grid_file_version, GRIDS_MIN_VERSION) > 0) { throw outdated_results_file_error("The results file was created using un-versioned grid file (equiv. to " + GRIDS_MIN_VERSION + ") and the current green-grids version (" + grid_file_version + ") is newer.\n" + - "Please use old grid files from: https://github.com/Green-Phys/green-grids/releases/tag/v" GRIDS_MIN_VERSION "."); + "Please use old grid files from: https://github.com/Green-Phys/green-grids/releases/tag/v" + GRIDS_MIN_VERSION + "."); } } }