aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bpkg/manifest49
-rw-r--r--bpkg/manifest.cxx31
-rw-r--r--build/export.build2
-rw-r--r--tests/manifest-parser/driver.cxx4
-rw-r--r--tests/manifest-roundtrip/driver.cxx2
-rw-r--r--tests/package-version/driver.cxx36
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"));