aboutsummaryrefslogtreecommitdiff
path: root/build2/utility.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-01-05 11:55:15 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-01-05 11:55:15 +0200
commit9fb791e9fad6c63fc1dac49f4d05ae63b8a3db9b (patch)
treed60322d4382ca5f97b676c5abe2e39524f35eab4 /build2/utility.cxx
parentf159b1dac68c8714f7ba71ca168e3b695891aad9 (diff)
Rename build directory/namespace to build2
Diffstat (limited to 'build2/utility.cxx')
-rw-r--r--build2/utility.cxx94
1 files changed, 94 insertions, 0 deletions
diff --git a/build2/utility.cxx b/build2/utility.cxx
new file mode 100644
index 0000000..fcecb5b
--- /dev/null
+++ b/build2/utility.cxx
@@ -0,0 +1,94 @@
+// file : build2/utility.cxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#include <build2/utility>
+
+#include <cstdlib> // strtol()
+
+using namespace std;
+
+namespace build2
+{
+ const string empty_string;
+ const path empty_path;
+ const dir_path empty_dir_path;
+
+ 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 != '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;
+ }
+
+ // 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;
+ }
+
+ bool exception_unwinding_dtor = false;
+}