From c27b069ab3049e566738bc7a63e9b8fa57657553 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 28 Apr 2017 09:04:14 +0200 Subject: Use standard_version for module versioning checks --- build2/parser.cxx | 27 +++++++-------- build2/types | 6 ++++ build2/utility | 41 ++++------------------ build2/utility.cxx | 92 ++++++------------------------------------------- build2/version/init.cxx | 7 +--- build2/version/module | 2 -- 6 files changed, 37 insertions(+), 138 deletions(-) diff --git a/build2/parser.cxx b/build2/parser.cxx index cfd18c6..47eca4b 100644 --- a/build2/parser.cxx +++ b/build2/parser.cxx @@ -1233,7 +1233,8 @@ namespace build2 for (auto i (ns.begin ()); i != ns.end (); ++i) { - string n, v; + string n; + standard_version v; if (!i->simple ()) fail (l) << "module name expected instead of " << *i; @@ -1241,34 +1242,30 @@ namespace build2 n = move (i->value); if (i->pair) + try { if (i->pair != '@') - fail << "unexpected pair style in using directive"; + fail (l) << "unexpected pair style in using directive"; ++i; if (!i->simple ()) fail (l) << "module version expected instead of " << *i; - v = move (i->value); + v = standard_version (i->value, true); // Allow earliest. + } + catch (const invalid_argument& e) + { + fail (l) << "invalid module version '" << i->value << "': " << e; } // Handle the special 'build' module. // if (n == "build") { - if (!v.empty ()) - { - unsigned int iv; - try {iv = to_version (v);} - catch (const invalid_argument& e) - { - fail (l) << "invalid version '" << v << "': " << e << endf; - } + standard_version_constraint c (move (v), false, nullopt, true); // >= - if (iv > BUILD2_VERSION) - fail (l) << "build2 " << v << " required" << - info << "running build2 " << BUILD2_VERSION_STR; - } + if (!v.empty ()) + check_build_version (c, l); } else { diff --git a/build2/types b/build2/types index c795213..c189f4d 100644 --- a/build2/types +++ b/build2/types @@ -43,6 +43,7 @@ #include #include #include +#include namespace build2 { @@ -209,6 +210,11 @@ namespace build2 // using butl::target_triplet; + // + // + using butl::standard_version; + using butl::standard_version_constraint; + // See context. // enum class run_phase {load, match, execute}; diff --git a/build2/utility b/build2/utility index 95766a4..860c841 100644 --- a/build2/utility +++ b/build2/utility @@ -17,7 +17,6 @@ #include #include // combine_hash(), reverse_iterate(), case*(), etc -#include #include @@ -104,9 +103,14 @@ namespace build2 // extern process_path argv0; - // Build system driver version. + // Build system driver version and check. // - extern butl::standard_version build_version; + extern standard_version build_version; + + class location; + + void + check_build_version (const standard_version_constraint&, const location&); // Work/home directories (must be initialized in main()) and relative path // calculation. @@ -418,37 +422,6 @@ namespace build2 string apply_pattern (const char* stem, const string* pattern); - // Parse version string in the X.Y.Z[-{a|b}N] to a version integer in the - // AABBCCDD form, where: - // - // AA - major version number - // BB - minor version number - // CC - bugfix version number - // DD - alpha / beta (DD + 50) version number - // - // When DD is not 00, 1 is subtracted from AABBCC. For example: - // - // Version AABBCCDD - // 2.0.0 02000000 - // 2.1.0 02010000 - // 2.1.1 02010100 - // 2.2.0-a1 02019901 - // 3.0.0-b2 02999952 - // - // For a version in the 1.2.3- form, it returns (AABBCC-1)01, which is the - // lowest possible version in the 1.2.3 release set. For example: - // - // Version AABBCCDD - // 2.2.0- 02019901 - // 1.2.3- 01020201 - // - // In fact versions 1.2.3- and 1.2.3-a1 are equivalent. - // - // Throw invalid_argument if the passed string is not a valid version. - // - unsigned int - to_version (const string&); - // Initialize build2 global state (verbosity, home/work directories, etc). // Should be called early in main() once. // diff --git a/build2/utility.cxx b/build2/utility.cxx index 46b3811..7fd2a42 100644 --- a/build2/utility.cxx +++ b/build2/utility.cxx @@ -109,7 +109,18 @@ namespace build2 options ops; process_path argv0; + standard_version build_version (BUILD2_VERSION_STR); + + void + check_build_version (const standard_version_constraint& c, const location& l) + { + if (!c.satisfies (build_version)) + fail (l) << "incompatible build2 version" << + info << "running " << build_version.string () << + info << "required " << c.string (); + } + dir_path work; dir_path home; const dir_path* relative_base = &work; @@ -437,87 +448,6 @@ namespace build2 return r; } - unsigned int - to_version (const string& s) - { - // See tests/version. - // - - auto parse = [&s] (size_t& p, const char* m, long min = 0, long max = 99) - -> unsigned int - { - if (s[p] == '-' || s[p] == '+') // stoi() allows these. - throw invalid_argument (m); - - const char* b (s.c_str () + p); - char* e; - long r (strtol (b, &e, 10)); - - if (b == e || r < min || r > max) - throw invalid_argument (m); - - p = e - s.c_str (); - return static_cast (r); - }; - - auto bail = [] (const char* m) {throw invalid_argument (m);}; - - unsigned int ma, mi, bf, ab (0); - - size_t p (0), n (s.size ()); - ma = parse (p, "invalid major version"); - - if (p >= n || s[p] != '.') - bail ("'.' expected after major version"); - - mi = parse (++p, "invalid minor version"); - - if (p >= n || s[p] != '.') - bail ("'.' expected after minor version"); - - bf = parse (++p, "invalid bugfix version"); - - if (p < n) - { - if (s[p] != '-') - bail ("'-' expected after bugfix version"); - - char k (s[++p]); - - if (k != '\0') - { - if (k != 'a' && k != 'b') - bail ("'a' or 'b' expected in release component"); - - ab = parse (++p, "invalid release component", 1, 49); - - if (p != n) - bail ("junk after release component"); - - if (k == 'b') - ab += 50; - } - else - ab = 1; - } - - // AABBCCDD - unsigned int r (ma * 1000000U + - mi * 10000U + - bf * 100U); - - if (ab != 0) - { - if (r == 0) - bail ("0.0.0 version with release component"); - - r -= 100; - r += ab; - } - - return r; - } - void init (const char* a0, uint16_t v) { diff --git a/build2/version/init.cxx b/build2/version/init.cxx index d111af5..76c30da 100644 --- a/build2/version/init.cxx +++ b/build2/version/init.cxx @@ -119,12 +119,7 @@ namespace build2 if (n == "build2" && !c.empty ()) try { - standard_version_constraint vc (c); - - if (!vc.satisfies (build_version)) - fail (l) << "incompatible build2 version" << - info << "running " << build_version.string () << - info << "required " << vc.string (); + check_build_version (standard_version_constraint (c), l); } catch (const invalid_argument& e) { diff --git a/build2/version/module b/build2/version/module index 6f913b3..1e6fb7a 100644 --- a/build2/version/module +++ b/build2/version/module @@ -10,8 +10,6 @@ #include #include -#include - #include namespace build2 -- cgit v1.1