aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-04-28 09:04:14 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-04-28 09:04:14 +0200
commitc27b069ab3049e566738bc7a63e9b8fa57657553 (patch)
tree7161f16d995f956aca75c66cd0ff3881f73956de
parent593fd960891027b97567b2622ed4b6c16070ab36 (diff)
Use standard_version for module versioning checks
-rw-r--r--build2/parser.cxx27
-rw-r--r--build2/types6
-rw-r--r--build2/utility41
-rw-r--r--build2/utility.cxx92
-rw-r--r--build2/version/init.cxx7
-rw-r--r--build2/version/module2
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 <butl/vector-view>
#include <butl/small-vector>
#include <butl/target-triplet>
+#include <butl/standard-version>
namespace build2
{
@@ -209,6 +210,11 @@ namespace build2
//
using butl::target_triplet;
+ // <butl/standard-version>
+ //
+ 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 <butl/ft/lang>
#include <butl/utility> // combine_hash(), reverse_iterate(), case*(), etc
-#include <butl/standard-version>
#include <unordered_set>
@@ -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<unsigned int> (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 <build2/types>
#include <build2/utility>
-#include <butl/standard-version>
-
#include <build2/module>
namespace build2