diff options
-rw-r--r-- | bpkg/manifest | 49 | ||||
-rw-r--r-- | bpkg/manifest.cxx | 31 | ||||
-rw-r--r-- | build/export.build | 2 | ||||
-rw-r--r-- | tests/manifest-parser/driver.cxx | 4 | ||||
-rw-r--r-- | tests/manifest-roundtrip/driver.cxx | 2 | ||||
-rw-r--r-- | tests/package-version/driver.cxx | 36 |
6 files changed, 101 insertions, 23 deletions
diff --git a/bpkg/manifest b/bpkg/manifest index 6f3dc13..a4bf6f2 100644 --- a/bpkg/manifest +++ b/bpkg/manifest @@ -27,10 +27,26 @@ namespace bpkg version (): epoch_ (0), revision_ (0) {} explicit - version (const char*); + version (const std::string& v): version (v.c_str ()) /* Delegate */ {} explicit - version (const std::string& v): version (v.c_str ()) /* Delegate */ {} + version (const char* v): version (v, false) /* Delegate */ {} + + // Create the version object from separate epoch, upstream, and + // revision parts. + // + version (std::uint16_t epoch, + std::string upstream, + std::uint16_t revision) + : version (upstream.c_str (), true) // Delegate + + { + // Can't initialize in member initializer list due to construction + // delegation. + // + epoch_ = epoch; + revision_ = revision; + } std::uint16_t epoch () const noexcept {return epoch_;} @@ -42,7 +58,7 @@ namespace bpkg upstream () const noexcept {return upstream_;} const std::string& - canonical_upstream () const noexcept {return canonical_;} + canonical_upstream () const noexcept {return canonical_upstream_;} std::string string () const @@ -77,7 +93,7 @@ namespace bpkg if (epoch_ != v.epoch_) return epoch_ < v.epoch_ ? -1 : 1; - if (int c = canonical_.compare (v.canonical_)) + if (int c = canonical_upstream_.compare (v.canonical_upstream_)) return c; if (!ignore_revision && revision_ != v.revision_) @@ -89,8 +105,8 @@ namespace bpkg bool empty () const noexcept { - // No sense to test epoch_ and revision_ for 0 as properly constructed - // version object can not have them different from 0 if upstream_ is + // No sense to test epoch and revision for 0 as properly constructed + // version object can not have them different from 0 if upstream is // empty. Returns true only for objects constructed with the default // constructor. // @@ -98,10 +114,16 @@ namespace bpkg } private: + version (const char*, bool upstream_only); + + private: + // Let's keep the members in the order they appear in the string + // representation. + // std::uint16_t epoch_; - std::uint16_t revision_; std::string upstream_; - std::string canonical_; // Upstream part canonical representation. + std::uint16_t revision_; + std::string canonical_upstream_; // Upstream part canonical representation. }; // priority @@ -205,7 +227,7 @@ namespace bpkg struct dependency { - std::string name; + std::string package; butl::optional<version_comparison> version; }; @@ -263,6 +285,15 @@ namespace bpkg serialize (manifest_serializer&) const; }; + class repository_location + { + // @@ Move all the location verification/canonical name calculation + // here. + // + + // ... + }; + class repository_manifest { public: diff --git a/bpkg/manifest.cxx b/bpkg/manifest.cxx index 149c743..2576bea 100644 --- a/bpkg/manifest.cxx +++ b/bpkg/manifest.cxx @@ -52,7 +52,7 @@ namespace bpkg static ostream& operator<< (ostream& o, const dependency& d) { - o << d.name; + o << d.package; if (d.version) { @@ -173,7 +173,7 @@ namespace bpkg // version // version:: - version (const char* v): version () // Delegate + version (const char* v, bool upstream_only): version () // Delegate { using std::string; // Otherwise compiler get confused with string() member. @@ -195,18 +195,18 @@ namespace bpkg auto add_canonical_component ( [this, &bad_arg](const char* b, const char* e, bool numeric) -> bool { - if (!canonical_.empty ()) - canonical_.append (1, '.'); + if (!canonical_upstream_.empty ()) + canonical_upstream_.append (1, '.'); if (numeric) { if (e - b > 8) bad_arg ("8 digits maximum allowed in a component"); - canonical_.append (8 - (e - b), '0'); // Add padding spaces. + canonical_upstream_.append (8 - (e - b), '0'); // Add padding spaces. string c (b, e); - canonical_.append (c); + canonical_upstream_.append (c); return stoul (c) != 0; } else @@ -218,7 +218,8 @@ namespace bpkg for (const char* i (b); i != e; ++i) { char c (*i); - canonical_.append (1, c >= 'A' && c <='Z' ? c + shift : c); + canonical_upstream_.append ( + 1, c >= 'A' && c <='Z' ? c + shift : c); } return true; @@ -244,6 +245,9 @@ namespace bpkg { case '+': { + if (upstream_only) + bad_arg ("unexpected '+' character"); + if (mode != epoch || p == v) bad_arg ("unexpected '+' character position"); @@ -258,13 +262,20 @@ namespace bpkg } case '-': + { + if (upstream_only) + bad_arg ("unexpected '-' character"); + + // No break, go to the next case. + } + case '.': { if (mode != epoch && mode != upstream || p == cb) bad_arg (string ("unexpected '") + c + "' character position"); if (add_canonical_component (cb, p, lnn < cb)) - cl = canonical_.size (); + cl = canonical_upstream_.size (); ue = p; mode = c == '-' ? revision : upstream; @@ -295,14 +306,14 @@ namespace bpkg else { if (add_canonical_component (cb, p, lnn < cb)) - cl = canonical_.size (); + cl = canonical_upstream_.size (); ue = p; } assert (ub != ue); // Can't happen if through all previous checks. upstream_.assign (ub, ue); - canonical_.resize (cl); + canonical_upstream_.resize (cl); } // package_manifest diff --git a/build/export.build b/build/export.build index 622d286..18ac1f6 100644 --- a/build/export.build +++ b/build/export.build @@ -3,4 +3,4 @@ $out_root/: include bpkg/ } -export $out_root/butl/lib{bpkg} +export $out_root/bpkg/lib{bpkg} diff --git a/tests/manifest-parser/driver.cxx b/tests/manifest-parser/driver.cxx index c54e2f0..0fd64f4 100644 --- a/tests/manifest-parser/driver.cxx +++ b/tests/manifest-parser/driver.cxx @@ -132,8 +132,8 @@ main () {{"","1"},{"a","x\\\\"},{"b",""},{"",""},{"",""}})); } -static std::ostream& -operator<< (std::ostream& os, const pairs& ps) +static ostream& +operator<< (ostream& os, const pairs& ps) { os << '{'; diff --git a/tests/manifest-roundtrip/driver.cxx b/tests/manifest-roundtrip/driver.cxx index f8a95bd..d7c7707 100644 --- a/tests/manifest-roundtrip/driver.cxx +++ b/tests/manifest-roundtrip/driver.cxx @@ -49,7 +49,7 @@ main (int argc, char* argv[]) cerr << "io failure" << endl; return 1; } - catch (const std::exception& e) + catch (const exception& e) { cerr << e.what () << endl; return 1; diff --git a/tests/package-version/driver.cxx b/tests/package-version/driver.cxx index 5508c20..d9a54d0 100644 --- a/tests/package-version/driver.cxx +++ b/tests/package-version/driver.cxx @@ -4,6 +4,7 @@ #include <string> #include <cassert> +#include <cstdint> // uint16 #include <iostream> #include <exception> #include <stdexcept> // invalid_argument @@ -27,6 +28,26 @@ bad_version (const string& v) } } +static bool +bad_version (uint16_t e, const string& u, uint16_t r) +{ + try + { + version bv (e, u, r); + return false; + } + catch (const invalid_argument&) + { + return true; + } +} + +static bool +test_constructor (const version& v) +{ + return v == version (v.epoch (), v.upstream (), v.revision ()); +} + int main (int argc, char* argv[]) { @@ -62,83 +83,98 @@ main (int argc, char* argv[]) assert (bad_version ("a-3s")); // Same. assert (bad_version ("a.")); // Not completed upstream. assert (bad_version ("a..b")); // Empty upstream component. + assert (bad_version (1, "1+1.1", 2)); // Epoch in upstream. + assert (bad_version (1, "1.1-1", 2)); // Revision in upstream. { version v ("a"); assert (v.string () == "a"); assert (v.canonical_upstream () == "a"); + assert (test_constructor (v)); } { version v ("65535+ab-65535"); assert (v.string () == "65535+ab-65535"); assert (v.canonical_upstream () == "ab"); + assert (test_constructor (v)); } { version v ("1"); assert (v.string () == "1"); assert (v.canonical_upstream () == "00000001"); + assert (test_constructor (v)); } { version v ("0"); assert (v.string () == "0"); assert (v.canonical_upstream ().empty ()); + assert (test_constructor (v)); } { version v ("0.0.0"); assert (v.string () == "0.0.0"); assert (v.canonical_upstream ().empty ()); + assert (test_constructor (v)); } { version v ("1.0.0"); assert (v.string () == "1.0.0"); assert (v.canonical_upstream () == "00000001"); + assert (test_constructor (v)); } { version v ("0.1.00"); assert (v.string () == "0.1.00"); assert (v.canonical_upstream () == "00000000.00000001"); + assert (test_constructor (v)); } { version v ("0.0a.00"); assert (v.string () == "0.0a.00"); assert (v.canonical_upstream () == "00000000.0a"); + assert (test_constructor (v)); } { version v ("0.a00.00"); assert (v.string () == "0.a00.00"); assert (v.canonical_upstream () == "00000000.a00"); + assert (test_constructor (v)); } { version v ("1+0"); assert (v.string () == "1+0"); assert (v.canonical_upstream ().empty ()); + assert (test_constructor (v)); } { version v ("0+A-1"); assert (v.string () == "A-1"); assert (v.canonical_upstream () == "a"); + assert (test_constructor (v)); } { version v ("10+B-0"); assert (v.string () == "10+B"); assert (v.canonical_upstream () == "b"); + assert (test_constructor (v)); } { version v ("3+1A.31.0.4.0-7"); assert (v.string () == "3+1A.31.0.4.0-7"); assert (v.canonical_upstream () == "1a.00000031.00000000.00000004"); + assert (test_constructor (v)); } assert (version ("a") == version ("a")); |