diff --git a/ecell4/core/extras.cpp b/ecell4/core/extras.cpp index 0ce361376..d2c4fb939 100644 --- a/ecell4/core/extras.cpp +++ b/ecell4/core/extras.cpp @@ -91,15 +91,45 @@ std::string load_version_information(const std::string& filename) #endif } -int mystoi(const std::string& s) +template +T mystoi(const std::string& s) { std::stringstream ss; ss << s; - int retval; + T retval; ss >> retval; return retval; } +std::pair parse_prerelease(const std::string& prestr) +{ + if (prestr.size() == 0) + { + return std::make_pair(VersionInformation::FINAL, 0); + } + else if (prestr[0] == 'a') + { + return std::make_pair(VersionInformation::ALPHA, mystoi(prestr.substr(1))); + } + else if (prestr[0] == 'b') + { + return std::make_pair(VersionInformation::BETA, mystoi(prestr.substr(1))); + } + else if (prestr[0] == 'c') + { + return std::make_pair(VersionInformation::RC, mystoi(prestr.substr(1))); + } + else if (prestr.size() >= 2 && prestr[0] == 'r' && prestr[1] == 'c') + { + return std::make_pair(VersionInformation::RC, mystoi(prestr.substr(2))); + } + else + { + throw NotSupported("Unknown pre-release was given."); + return std::make_pair(VersionInformation::NONE, 0); + } +} + VersionInformation parse_version_information(const std::string& version) { #if defined(HAVE_BOOST_REGEX) || defined(WIN32_MSC) @@ -108,7 +138,7 @@ VersionInformation parse_version_information(const std::string& version) #else /* WIN32_MSC */ using namespace std::tr1; #endif /* HAVE_BOOST_REGEX */ - regex reg("^([^-\\.]+-[^-\\.]+-)([0123456789]+)\\.([0123456789]+)(\\.[0123456789]+|)(\\.dev[0123456789]+|)$"); + regex reg("^([^-\\.]+-[^-\\.]+-)([0123456789]+)\\.([0123456789]+)(\\.[0123456789]+|)(a[0123456789]+|b[0123456789]+|rc[0123456789]+|c[0123456789]+|)(\\.dev[0123456789]+|)$"); smatch result; if (!regex_match(version, result, reg)) { @@ -117,16 +147,17 @@ VersionInformation parse_version_information(const std::string& version) } const std::string header = result.str(1); - const int majorno = mystoi(result.str(2)); - const int minorno = mystoi(result.str(3)); - const int patchno = (result.str(4).size() > 1 ? mystoi(result.str(4).substr(1)) : -1); - const int devno = (result.str(5).size() > 4 ? mystoi(result.str(5).substr(4)) : -1); + const unsigned int majorno = mystoi(result.str(2)); + const unsigned int minorno = mystoi(result.str(3)); + const unsigned int patchno = (result.str(4).size() > 1 ? mystoi(result.str(4).substr(1)) : 0); + const std::pair pre = parse_prerelease(result.str(5)); + const int devno = (result.str(6).size() > 4 ? mystoi(result.str(6).substr(4)) : -1); - return VersionInformation(header, majorno, minorno, patchno, devno); + return VersionInformation(header, majorno, minorno, patchno, pre.first, pre.second, devno); #else /* regex.h */ regex_t reg; int errcode = regcomp( - ®, "^([^-\\.]+-[^-\\.]+-)([0123456789]+)\\.([0123456789]+)(\\.[0123456789]+|)(\\.dev[0123456789]+|)$", + ®, "^([^-\\.]+-[^-\\.]+-)([0123456789]+)\\.([0123456789]+)(\\.[0123456789]+|)(a[0123456789]+|b[0123456789]+|rc[0123456789]+|c[0123456789]+|)(\\.dev[0123456789]+|)$", REG_EXTENDED); if (errcode != 0) { @@ -137,8 +168,8 @@ VersionInformation parse_version_information(const std::string& version) throw IllegalState("regcompile error."); } - regmatch_t match[6]; - errcode = regexec(®, version.c_str(), 6, match, 0); + regmatch_t match[7]; + errcode = regexec(®, version.c_str(), 7, match, 0); if (errcode != 0) { char errbuf[100]; @@ -149,13 +180,18 @@ VersionInformation parse_version_information(const std::string& version) } const std::string header = version.substr(match[1].rm_so, match[1].rm_eo - match[1].rm_so); - const int majorno = mystoi(version.substr(match[2].rm_so, match[2].rm_eo - match[2].rm_so)); - const int minorno = mystoi(version.substr(match[3].rm_so, match[3].rm_eo - match[3].rm_so)); - const int patchno = (match[4].rm_eo - match[4].rm_so > 0 ? mystoi(version.substr(match[4].rm_so + 1)) : -1); - const int devno = (match[5].rm_eo - match[5].rm_so > 0 ? mystoi(version.substr(match[5].rm_so + 4)) : -1); + const unsigned int majorno = mystoi(version.substr(match[2].rm_so, match[2].rm_eo - match[2].rm_so)); + const unsigned int minorno = mystoi(version.substr(match[3].rm_so, match[3].rm_eo - match[3].rm_so)); + const unsigned int patchno = (match[4].rm_eo - match[4].rm_so > 0 ? + mystoi(version.substr(match[4].rm_so + 1, match[4].rm_eo - (match[4].rm_so + 1))) : 0); + const std::pair pre = parse_prerelease( + version.substr(match[5].rm_so, match[5].rm_eo - match[5].rm_so)); + const int devno = (match[6].rm_eo - match[6].rm_so > 0 ? + mystoi(version.substr(match[6].rm_so + 4, match[6].rm_eo - (match[6].rm_so + 4))) : -1); regfree(®); - return VersionInformation(header, majorno, minorno, patchno, devno); + + return VersionInformation(header, majorno, minorno, patchno, pre.first, pre.second, devno); #endif /* HAVE_BOOST_REGEX */ } @@ -170,15 +206,23 @@ bool check_version_information(const std::string& version, const std::string& re } else if (vinfo1.majorno != vinfo2.majorno) { - return (vinfo1.majorno >= vinfo2.majorno); + return (vinfo1.majorno > vinfo2.majorno); } else if (vinfo1.minorno != vinfo2.minorno) { - return (vinfo1.minorno >= vinfo2.minorno); + return (vinfo1.minorno > vinfo2.minorno); } else if (vinfo1.patchno != vinfo2.patchno) { - return (vinfo1.patchno == -1 || (vinfo2.patchno != -1 && vinfo1.patchno >= vinfo2.patchno)); + return (vinfo1.patchno > vinfo2.patchno); + } + else if (vinfo1.pre != vinfo2.pre) + { + return (vinfo1.pre > vinfo2.pre); + } + else if (vinfo1.preno != vinfo2.preno) + { + return (vinfo1.preno > vinfo2.preno); } return (vinfo1.devno == -1 || (vinfo2.devno != -1 && vinfo1.devno >= vinfo2.devno)); } diff --git a/ecell4/core/extras.hpp b/ecell4/core/extras.hpp index 000307075..09f83f96e 100644 --- a/ecell4/core/extras.hpp +++ b/ecell4/core/extras.hpp @@ -89,12 +89,26 @@ get_dimension_from_model(const Species& species, const boost::shared_ptr& struct VersionInformation { + typedef enum PreRelease + { + NONE = 0, + ALPHA = 1, + BETA = 2, + RC = 3, + FINAL = 4 + } prerelease_type; + std::string header; - int majorno, minorno, patchno, devno; + unsigned int majorno, minorno, patchno; + prerelease_type pre; + unsigned int preno; + int devno; VersionInformation( - const std::string& header, const int majorno, const int minorno, const int patchno, const int devno) - : header(header), majorno(majorno), minorno(minorno), patchno(patchno), devno(devno) + const std::string& header, const unsigned int majorno, const unsigned int minorno, const unsigned int patchno, + const prerelease_type pre, const unsigned int preno, const int devno) + : header(header), majorno(majorno), minorno(minorno), patchno(patchno), + pre(pre), preno(preno), devno(devno) { ; } diff --git a/ecell4/core/tests/extras_test.cpp b/ecell4/core/tests/extras_test.cpp index ab20ed3ab..e4c5c36f2 100644 --- a/ecell4/core/tests/extras_test.cpp +++ b/ecell4/core/tests/extras_test.cpp @@ -53,7 +53,7 @@ BOOST_AUTO_TEST_CASE(VersionInformationTest) BOOST_CHECK_EQUAL(vinfo1.header, "ecell4-test-"); BOOST_CHECK_EQUAL(vinfo1.majorno, 1); BOOST_CHECK_EQUAL(vinfo1.minorno, 2); - BOOST_CHECK_EQUAL(vinfo1.patchno, -1); + BOOST_CHECK_EQUAL(vinfo1.patchno, 0); BOOST_CHECK_EQUAL(vinfo1.devno, -1); } { @@ -61,15 +61,24 @@ BOOST_AUTO_TEST_CASE(VersionInformationTest) BOOST_CHECK_EQUAL(vinfo1.header, "ecell4-test-"); BOOST_CHECK_EQUAL(vinfo1.majorno, 1); BOOST_CHECK_EQUAL(vinfo1.minorno, 2); - BOOST_CHECK_EQUAL(vinfo1.patchno, -1); + BOOST_CHECK_EQUAL(vinfo1.patchno, 0); BOOST_CHECK_EQUAL(vinfo1.devno, 4); } - + { + const extras::VersionInformation vinfo1 = extras::parse_version_information("ecell4-test-1.2.3c4.dev5"); + BOOST_CHECK_EQUAL(vinfo1.header, "ecell4-test-"); + BOOST_CHECK_EQUAL(vinfo1.majorno, 1); + BOOST_CHECK_EQUAL(vinfo1.minorno, 2); + BOOST_CHECK_EQUAL(vinfo1.patchno, 3); + BOOST_CHECK_EQUAL(vinfo1.pre, extras::VersionInformation::RC); + BOOST_CHECK_EQUAL(vinfo1.preno, 4); + BOOST_CHECK_EQUAL(vinfo1.devno, 5); + } { BOOST_CHECK(extras::check_version_information("ecell4-test-1.0", "ecell4-test-1.0")); BOOST_CHECK(extras::check_version_information("ecell4-test-1.1", "ecell4-test-1.0")); BOOST_CHECK(extras::check_version_information("ecell4-test-2.0.0", "ecell4-test-1.0")); - BOOST_CHECK(!extras::check_version_information("ecell4-test-1.0.0", "ecell4-test-1.0")); + BOOST_CHECK(extras::check_version_information("ecell4-test-1.0.0", "ecell4-test-1.0")); BOOST_CHECK(extras::check_version_information("ecell4-test-1.0.0", "ecell4-test-1.0.0")); BOOST_CHECK(extras::check_version_information("ecell4-test-1.0.1", "ecell4-test-1.0.0")); BOOST_CHECK(extras::check_version_information("ecell4-test-1.0", "ecell4-test-1.0.0")); @@ -77,5 +86,11 @@ BOOST_AUTO_TEST_CASE(VersionInformationTest) BOOST_CHECK(extras::check_version_information("ecell4-test-1.1.dev1", "ecell4-test-1.0")); BOOST_CHECK(extras::check_version_information("ecell4-test-1.0.dev1", "ecell4-test-1.0.dev1")); BOOST_CHECK(extras::check_version_information("ecell4-test-1.0.dev2", "ecell4-test-1.0.dev1")); + BOOST_CHECK(extras::check_version_information("ecell4-test-1.0.0.dev1", "ecell4-test-1.0.dev1")); + BOOST_CHECK(!extras::check_version_information("ecell4-test-1.0a1", "ecell4-test-1.0")); + BOOST_CHECK(extras::check_version_information("ecell4-test-1.1a2", "ecell4-test-1.0")); + BOOST_CHECK(extras::check_version_information("ecell4-test-1.0rc1", "ecell4-test-1.0a5")); + BOOST_CHECK(extras::check_version_information("ecell4-test-1.0.1a1", "ecell4-test-1.0")); + BOOST_CHECK(extras::check_version_information("ecell4-test-1.0.1c1", "ecell4-test-1.0.1rc1")); } }