aboutsummaryrefslogtreecommitdiff
path: root/bpkg
diff options
context:
space:
mode:
Diffstat (limited to 'bpkg')
-rw-r--r--bpkg/manifest-utility.cxx75
-rw-r--r--bpkg/manifest-utility.hxx11
-rw-r--r--bpkg/package.cxx34
-rw-r--r--bpkg/package.hxx33
-rw-r--r--bpkg/pkg-build.cli43
-rw-r--r--bpkg/pkg-build.cxx384
-rw-r--r--bpkg/pkg-status.cxx10
-rw-r--r--bpkg/satisfaction.cxx6
-rw-r--r--bpkg/satisfaction.hxx12
-rw-r--r--bpkg/satisfaction.test.cxx62
10 files changed, 426 insertions, 244 deletions
diff --git a/bpkg/manifest-utility.cxx b/bpkg/manifest-utility.cxx
index 29025d3..0771df8 100644
--- a/bpkg/manifest-utility.cxx
+++ b/bpkg/manifest-utility.cxx
@@ -4,6 +4,8 @@
#include <bpkg/manifest-utility.hxx>
+#include <cstring> // strcspn()
+
#include <libbutl/b.mxx>
#include <libbutl/url.mxx>
#include <libbutl/sha256.mxx>
@@ -40,8 +42,6 @@ namespace bpkg
package_name
parse_package_name (const char* s, bool allow_version)
{
- using traits = string::traits_type;
-
if (!allow_version)
try
{
@@ -52,10 +52,11 @@ namespace bpkg
fail << "invalid package name '" << s << "': " << e;
}
- size_t n (traits::length (s));
-
- if (const char* p = traits::find (s, n, '/'))
- n = static_cast<size_t> (p - s);
+ // Calculate the package name length as a length of the prefix that
+ // doesn't contain spaces, slashes and the version constraint starting
+ // characters. Note that none of them are valid package name characters.
+ //
+ size_t n (strcspn (s, " /=<>([~^"));
try
{
@@ -104,6 +105,68 @@ namespace bpkg
return version ();
}
+ optional<version_constraint>
+ parse_package_version_constraint (const char* s,
+ bool allow_wildcard,
+ bool fold_zero_revision,
+ bool version_only)
+ {
+ // Calculate the version specification position as a length of the prefix
+ // that doesn't contain slashes and the version constraint starting
+ // characters.
+ //
+ size_t n (strcspn (s, "/=<>([~^"));
+
+ if (s[n] == '\0') // No version (constraint) is specified?
+ return nullopt;
+
+ const char* v (s + n); // Constraint or version including '/'.
+
+ // If only the version is allowed or the package name is followed by '/'
+ // then fallback to the version parsing.
+ //
+ if (version_only || v[0] == '/')
+ try
+ {
+ return version_constraint (
+ parse_package_version (s, allow_wildcard, fold_zero_revision));
+ }
+ catch (const invalid_argument& e)
+ {
+ fail << "invalid package version '" << v + 1 << "' in '" << s << "': "
+ << e;
+ }
+
+ try
+ {
+ version_constraint r (v);
+
+ if (!r.complete ())
+ throw invalid_argument ("incomplete");
+
+ // There doesn't seem to be any good reason to allow specifying a stub
+ // version in the version constraint. Note that the constraint having
+ // both endpoints set to the wildcard version (which is a stub) denotes
+ // the system package wildcard version and may result only from the '/*'
+ // string representation.
+ //
+ auto stub = [] (const optional<version>& v)
+ {
+ return v && v->compare (wildcard_version, true) == 0;
+ };
+
+ if (stub (r.min_version) || stub (r.max_version))
+ throw invalid_argument ("endpoint is a stub");
+
+ return r;
+ }
+ catch (const invalid_argument& e)
+ {
+ fail << "invalid package version constraint '" << v << "' in '" << s
+ << "': " << e << endf;
+ }
+ }
+
repository_location
parse_location (const string& s, optional<repository_type> ot)
try
diff --git a/bpkg/manifest-utility.hxx b/bpkg/manifest-utility.hxx
index 9f690b4..16546bd 100644
--- a/bpkg/manifest-utility.hxx
+++ b/bpkg/manifest-utility.hxx
@@ -61,6 +61,17 @@ namespace bpkg
fold_zero_revision);
}
+ // Extract the package constraint from either <name>[/<version>] or
+ // <name><version-constraint> forms, unless version_only is true. For the
+ // former case return the `== <version>` constraint. Return nullopt if only
+ // the package name is specified.
+ //
+ optional<version_constraint>
+ parse_package_version_constraint (const char*,
+ bool allow_wildcard = false,
+ bool fold_zero_revision = true,
+ bool version_only = false);
+
// If the passed location is a relative local path, then assume this is a
// relative path to the repository directory and complete it based on the
// current working directory. Diagnose invalid locations and throw failed.
diff --git a/bpkg/package.cxx b/bpkg/package.cxx
index 563fc93..e45718e 100644
--- a/bpkg/package.cxx
+++ b/bpkg/package.cxx
@@ -262,6 +262,40 @@ namespace bpkg
return system ? "sys:" + n.string () + vs : n.string () + vs;
}
+ string
+ package_string (const package_name& name,
+ const optional<version_constraint>& constraint,
+ bool system)
+ {
+ // Fallback to the version type-based overload if the constraint is not
+ // specified.
+ //
+ if (!constraint)
+ return package_string (name, version (), system);
+
+ // There are no scenarios where the version constrain is present but is
+ // empty (both endpoints are nullopt).
+ //
+ assert (!constraint->empty ());
+
+ // If the endpoint versions are equal then represent the constraint as the
+ // "<name>/<version>" string rather than "<name> == <version>", using the
+ // version type-based overload.
+ //
+ const optional<version>& min_ver (constraint->min_version);
+ bool eq (min_ver == constraint->max_version);
+
+ if (eq)
+ return package_string (name, *min_ver, system);
+
+ if (system)
+ return package_string (name, version (), system) + "/...";
+
+ // Quote the result as it contains the space character.
+ //
+ return "'" + name.string () + ' ' + constraint->string () + "'";
+ }
+
// selected_package
//
string selected_package::
diff --git a/bpkg/package.hxx b/bpkg/package.hxx
index 4f40939..a3a6bab 100644
--- a/bpkg/package.hxx
+++ b/bpkg/package.hxx
@@ -442,15 +442,15 @@ namespace bpkg
// package" to refer to the "effective" dependency that has been resolved to
// the actual package object.
//
- #pragma db value(dependency_constraint) definition
+ #pragma db value(version_constraint) definition
#pragma db value(dependency) definition
#pragma db member(dependency::constraint) column("")
#pragma db value(dependency_alternatives) definition
using dependencies = vector<dependency_alternatives>;
- // Wildcard version. Satisfies any dependency constraint and is represented
- // as 0+0 (which is also the "stub version"; since a real version is always
+ // Wildcard version. Satisfies any version constraint and is represented as
+ // 0+0 (which is also the "stub version"; since a real version is always
// greater than the stub version, we reuse it to signify a special case).
//
extern const version wildcard_version;
@@ -515,7 +515,7 @@ namespace bpkg
mutable optional<version_type> system_version_;
public:
- // Note: dependency constraints must be complete.
+ // Note: version constraints must be complete.
//
available_package (package_manifest&& m)
: id (move (m.name), m.version),
@@ -722,15 +722,32 @@ namespace bpkg
const version&,
bool system = false);
+ // Return the package name in the [sys:]<name>[<version-constraint>] form.
+ // The version constraint component is represented with the "/<version>"
+ // string for the `== <version>` constraint, "/*" string for the wildcard
+ // version, and is omitted for nullopt.
+ //
+ // If the version constraint other than the equality operator is specified
+ // for a system package, return the "sys:<name>/..." string (with "..."
+ // literally). This, in particular, is used for issuing diagnostics that
+ // advises the user to configure a system package. Note that in this case
+ // the user can only specify a specific version/wildcard on the command
+ // line.
+ //
+ string
+ package_string (const package_name& name,
+ const optional<version_constraint>&,
+ bool system = false);
+
// A map of "effective" prerequisites (i.e., pointers to other selected
- // packages) to optional dependency constraint. Note that because it is a
+ // packages) to optional version constraint. Note that because it is a
// single constraint, we don't support multiple dependencies on the same
// package (e.g., two ranges of versions). See pkg_configure().
//
class selected_package;
using package_prerequisites = std::map<lazy_shared_ptr<selected_package>,
- optional<dependency_constraint>,
+ optional<version_constraint>,
compare_lazy_ptr>;
#pragma db object pointer(shared_ptr) session
@@ -1048,7 +1065,7 @@ namespace bpkg
string name;
#pragma db column(pp.value)
- optional<dependency_constraint> constraint;
+ optional<version_constraint> constraint;
};
*/
@@ -1064,7 +1081,7 @@ namespace bpkg
package_name name;
#pragma db column("pp.")
- optional<dependency_constraint> constraint;
+ optional<version_constraint> constraint;
};
// Return a count of repositories that contain this repository fragment.
diff --git a/bpkg/pkg-build.cli b/bpkg/pkg-build.cli
index e247f47..0ac8dcb 100644
--- a/bpkg/pkg-build.cli
+++ b/bpkg/pkg-build.cli
@@ -13,7 +13,8 @@ namespace bpkg
{
"<options>
<cfg-var>
- <pkg-spec> <flags> <scheme> <pkg> <ver>
+ <pkg-spec> <flags> <scheme> <pkg> <ver-spec>
+ <version> <version-constraint>
<file>
<dir>
<rep-loc>",
@@ -25,12 +26,13 @@ namespace bpkg
\b{bpkg pkg-build}|\b{build} [<options>] \ \b{--upgrade}|\b{-u} | \b{--patch}|\b{-p}\n
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ [<cfg-var>... \b{--}]}
- \c{<pkg-spec> = [<flags>](([<scheme>\b{:}]<pkg>[\b{/}<ver>])\b{,}...[\b{@}<rep-loc>] | \n
- \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ [\b{@}]<rep-loc> \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | \n
- \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ <file> \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | \n
+ \c{<pkg-spec> = [<flags>](([<scheme>\b{:}]<pkg>[<ver-spec>])\b{,}...[\b{@}<rep-loc>] | \n
+ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ [\b{@}]<rep-loc> \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | \n
+ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ <file> \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | \n
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ <dir>\b{/})\n
- <flags>\ \ \ \ = \b{?}\n
- <scheme> \ \ = \b{sys}}
+ <flags>\ \ \ \ \ \ = \b{?}\n
+ <scheme> \ \ \ \ = \b{sys}\n
+ <ver-spec>\ \ \ = \b{/}<version> | <version-constraint>}
\h|DESCRIPTION|
@@ -56,21 +58,25 @@ namespace bpkg
or \cb{--patch}.
Each package can be specified as just the name (<pkg>) with optional
- package version (<ver>) in which case the source code for the package
- will be automatically fetched from one of the configured
+ version specification (<ver-spec>), in which case the source code for the
+ package will be automatically fetched from one of the configured
repositories. See the \l{bpkg-rep-add(1)} and \l{bpkg-rep-fetch(1)}
- commands for more information on package repositories. If <ver> is not
- specified, then the latest available version will be built. To downgrade,
- the desired version must be specified explicitly. For example:
+ commands for more information on package repositories. The version
+ specification (<ver-spec>) can be either the exact version in the
+ \c{\b{/}\i{version}} form or the version constraint as described in
+ \l{bpkg#package-version-constraint Package Version Constraint}. If
+ <ver-spec> is not specified, then the latest available version will be
+ built. To downgrade, the desired version must be specified
+ explicitly. For example:
\
- bpkg build foo libfoo/1.2.3
+ bpkg build foo libfoo/1.2.3 \"bar < 2.0.0\"
\
Alternatively, the package repository location (<rep-loc>) can be
- specified as part of the build command. In this case, if <ver> is not
- specified, then the latest available from this repository version will be
- built. For example:
+ specified as part of the build command. In this case, if <ver-spec> is
+ not specified, then the latest available from this repository version
+ will be built. For example:
\
bpkg build foo,libfoo/1.2.3@https://git.example.org/foo.git#master
@@ -91,8 +97,9 @@ namespace bpkg
(<scheme>). Currently the only recognized scheme is \cb{sys} which
instructs \cb{pkg-build} to configure the package as available from the
system rather than building it from source. If the system package version
- (<ver>) is not specified or is '\cb{*}', then it is considered to be
- unknown but satisfying any dependency constraint. If the version is not
+ (<ver-spec>) is not specified or is '\cb{/*}', then it is considered to
+ be unknown but satisfying any version constraint. If specified,
+ <ver-spec> may not be a version constraint. If the version is not
explicitly specified, then at least a stub package must be available from
one of the repositories.
@@ -125,7 +132,7 @@ namespace bpkg
available for build as a dependency.
Packages (both built to hold and as dependencies) that are specified with
- an explicit package version (<ver>) or as an archive or directory,
+ an explicit package version (<ver-spec>) or as an archive or directory,
will have their versions held, that is, they will not be automatically
upgraded.
diff --git a/bpkg/pkg-build.cxx b/bpkg/pkg-build.cxx
index 5a5eaa1..6c218d5 100644
--- a/bpkg/pkg-build.cxx
+++ b/bpkg/pkg-build.cxx
@@ -53,7 +53,7 @@ namespace bpkg
static odb::result<available_package>
query_available (database& db,
const package_name& name,
- const optional<dependency_constraint>& c)
+ const optional<version_constraint>& c)
{
using query = query<available_package>;
@@ -164,7 +164,7 @@ namespace bpkg
vector<pair<shared_ptr<available_package>, shared_ptr<repository_fragment>>>
find_available (database& db,
const package_name& name,
- const optional<dependency_constraint>& c)
+ const optional<version_constraint>& c)
{
vector<pair<shared_ptr<available_package>,
shared_ptr<repository_fragment>>> r;
@@ -208,7 +208,7 @@ namespace bpkg
vector<pair<shared_ptr<available_package>, shared_ptr<repository_fragment>>>
find_available (database& db,
const package_name& name,
- const optional<dependency_constraint>& c,
+ const optional<version_constraint>& c,
const vector<shared_ptr<repository_fragment>>& rfs,
bool prereq = true)
{
@@ -239,7 +239,7 @@ namespace bpkg
static pair<shared_ptr<available_package>, shared_ptr<repository_fragment>>
find_available_one (database& db,
const package_name& name,
- const optional<dependency_constraint>& c,
+ const optional<version_constraint>& c,
const shared_ptr<repository_fragment>& rf,
bool prereq = true)
{
@@ -260,7 +260,7 @@ namespace bpkg
static pair<shared_ptr<available_package>, shared_ptr<repository_fragment>>
find_available_one (database& db,
const package_name& name,
- const optional<dependency_constraint>& c,
+ const optional<version_constraint>& c,
const vector<shared_ptr<repository_fragment>>& rfs,
bool prereq = true)
{
@@ -328,6 +328,19 @@ namespace bpkg
return make_pair (make_shared<available_package> (move (m)), move (af));
}
+ // Return true if the version constraint represents the wildcard version.
+ //
+ static inline bool
+ wildcard (const version_constraint& vc)
+ {
+ bool r (vc.min_version && *vc.min_version == wildcard_version);
+
+ if (r)
+ assert (vc.max_version == vc.min_version);
+
+ return r;
+ }
+
// A "dependency-ordered" list of packages and their prerequisites.
// That is, every package on the list only possibly depending on the
// ones after it. In a nutshell, the usage is as follows: we first
@@ -344,7 +357,7 @@ namespace bpkg
//
// During the satisfaction phase, we collect all the packages, their
// prerequisites (and so on, recursively) in a map trying to satisfy
- // any dependency constraints. Specifically, during this step, we may
+ // any version constraints. Specifically, during this step, we may
// "upgrade" or "downgrade" a package that is already in a map as a
// result of another package depending on it and, for example, requiring
// a different version. One notable side-effect of this process is that
@@ -415,10 +428,10 @@ namespace bpkg
struct constraint_type
{
string dependent;
- dependency_constraint value;
+ version_constraint value;
constraint_type () = default;
- constraint_type (string d, dependency_constraint v)
+ constraint_type (string d, version_constraint v)
: dependent (move (d)), value (move (v)) {}
};
@@ -868,9 +881,9 @@ namespace bpkg
bool system (false);
bool dep_optional (false);
- // If the user specified the desired dependency version, then we will
- // use it to overwrite the constraint imposed by the dependent
- // package, checking that it is still satisfied.
+ // If the user specified the desired dependency version constraint,
+ // then we will use it to overwrite the constraint imposed by the
+ // dependent package, checking that it is still satisfied.
//
// Note that we can't just rely on the execution plan refinement that
// will pick up the proper dependency version at the end of the day.
@@ -880,17 +893,10 @@ namespace bpkg
// pkg-build/dependency/apply-constraints/resolve-conflict{1,2}
// tests).
- // Points to the version constraint created from the desired
- // dependency version, if specified. Is NULL otherwise. Can be used as
- // boolean flag.
+ // Points to the desired dependency version constraint, if specified,
+ // and is NULL otherwise. Can be used as boolean flag.
//
- const dependency_constraint* dep_constr (nullptr);
-
- auto dep_version = [&dep_constr] () -> const version&
- {
- assert (dep_constr && dep_constr->min_version);
- return *dep_constr->min_version;
- };
+ const version_constraint* dep_constr (nullptr);
auto i (map_.find (dn));
if (i != map_.end ())
@@ -900,19 +906,23 @@ namespace bpkg
dep_optional = !bp.action; // Is pre-entered.
if (dep_optional &&
- bp.hold_version && *bp.hold_version) // The version is specified,
+ //
+ // The version constraint is specified,
+ //
+ bp.hold_version && *bp.hold_version)
{
assert (bp.constraints.size () == 1);
const build_package::constraint_type& c (bp.constraints[0]);
- dep_constr = &c.value; // Assign before dep_version() usage.
+ dep_constr = &c.value;
system = bp.system;
// If the user-specified dependency constraint is the wildcard
// version, then it satisfies any dependency constraint.
//
- if (!satisfies (dep_version (), dp.constraint))
+ if (!wildcard (*dep_constr) &&
+ !satisfies (*dep_constr, dp.constraint))
fail << "unable to satisfy constraints on package " << dn <<
info << name << " depends on (" << dn << " "
<< *dp.constraint << ")" <<
@@ -928,9 +938,9 @@ namespace bpkg
: dependency {dn, *dep_constr});
// First see if this package is already selected. If we already have
- // it in the configuraion and it satisfies our dependency constraint,
- // then we don't want to be forcing its upgrade (or, worse,
- // downgrade).
+ // it in the configuraion and it satisfies our dependency version
+ // constraint, then we don't want to be forcing its upgrade (or,
+ // worse, downgrade).
//
shared_ptr<selected_package> dsp (db.find<selected_package> (dn));
@@ -968,10 +978,10 @@ namespace bpkg
? find_available_one (db, dn, nullopt, root)
: find_available_one (db,
dn,
- dependency_constraint (dsp->version),
+ version_constraint (dsp->version),
root);
- // A stub satisfies any dependency constraint so we weed them out
+ // A stub satisfies any version constraint so we weed them out
// (returning stub as an available package feels wrong).
//
if (dap == nullptr || dap->stub ())
@@ -1013,17 +1023,18 @@ namespace bpkg
// Note that this logic (naturally) does not apply if the package is
// already selected by the user (see above).
//
- // Also note that for the user-specified dependency version we rely
- // on its presence in repositories of the first dependent met. As
- // a result, we may fail too early if the version doesn't belong to
- // its repositories, but belongs to the ones of some dependent that
+ // Also note that for the user-specified dependency version
+ // constraint we rely on the satisfying package version be present
+ // in repositories of the first dependent met. As a result, we may
+ // fail too early if such package version doesn't belong to its
+ // repositories, but belongs to the ones of some dependent that
// we haven't met yet. Can we just search all repositories for an
- // available package of this version and just take it, if present?
- // We could, but then which repository should we pick? The wrong
- // choice can introduce some unwanted repositories and package
- // versions into play. So instead, we will postpone collecting the
- // problematic dependent, expecting that some other one will find
- // the version in its repositories.
+ // available package of the appropriate version and just take it,
+ // if present? We could, but then which repository should we pick?
+ // The wrong choice can introduce some unwanted repositories and
+ // package versions into play. So instead, we will postpone
+ // collecting the problematic dependent, expecting that some other
+ // one will find the appropriate version in its repositories.
//
// For a system package we pick the latest version just to make sure
// the package is recognized. An unrecognized package means the
@@ -1048,8 +1059,7 @@ namespace bpkg
// We need to be careful not to print the wildcard-based
// constraint.
//
- if (d.constraint &&
- (!dep_constr || dep_version () != wildcard_version))
+ if (d.constraint && (!dep_constr || !wildcard (*dep_constr)))
dr << ' ' << *d.constraint;
dr << " of package " << name;
@@ -1075,8 +1085,8 @@ namespace bpkg
{
// Note that the constraint can safely be printed as it can't
// be a wildcard (produced from the user-specified dependency
- // version). If it were, then the system version wouldn't be NULL
- // and would satisfy itself.
+ // version constraint). If it were, then the system version
+ // wouldn't be NULL and would satisfy itself.
//
if (dap->system_version () == nullptr)
fail << "dependency " << d << " of package " << name << " is "
@@ -1087,7 +1097,9 @@ namespace bpkg
if (!satisfies (*dap->system_version (), d.constraint))
fail << "dependency " << d << " of package " << name << " is "
<< "not available in source" <<
- info << package_string (dn, *dap->system_version (), true)
+ info << package_string (dn,
+ *dap->system_version (),
+ true /* system */)
<< " does not satisfy the constrains";
system = true;
@@ -1403,7 +1415,7 @@ namespace bpkg
if (check)
{
const version& av (p.available_version ());
- const dependency_constraint& c (*pd.constraint);
+ const version_constraint& c (*pd.constraint);
if (!satisfies (av, c))
{
@@ -1756,7 +1768,7 @@ namespace bpkg
// selected package minor version reached the limit (see
// standard-version.cxx for details).
//
- static optional<dependency_constraint>
+ static optional<version_constraint>
patch_constraint (const shared_ptr<selected_package>& sp, bool quiet = false)
{
const package_name& nm (sp->name);
@@ -1779,7 +1791,7 @@ namespace bpkg
try
{
- return dependency_constraint ("~" + vs);
+ return version_constraint ("~" + vs);
}
// Note that the only possible reason for invalid_argument exception to
// be thrown is that minor version reached the 99999 limit (see
@@ -1800,12 +1812,12 @@ namespace bpkg
struct dependency_package
{
package_name name;
- bpkg::version version; // Empty if unspecified.
- shared_ptr<selected_package> selected; // NULL if not present.
+ optional<version_constraint> constraint; // nullopt if unspecified.
+ shared_ptr<selected_package> selected; // NULL if not present.
bool system;
- bool patch; // Only for an empty version.
+ bool patch; // Only for an empty version.
bool keep_out;
- strings config_vars; // Only if not system.
+ strings config_vars; // Only if not system.
};
using dependency_packages = vector<dependency_package>;
@@ -1817,12 +1829,12 @@ namespace bpkg
// upgrade/downgrade to as well as the repository fragment it must come
// from, and the system flag.
//
- // If the explicitly specified dependency version can not be found in the
- // dependents repositories, then return the "no changes are necessary"
- // result if ignore_unsatisfiable argument is true and fail otherwise. The
- // common approach is to pass true for this argument until the execution
- // plan is finalized, assuming that the problematic dependency might be
- // dropped.
+ // If the package version that satisfies explicitly specified dependency
+ // version constraint can not be found in the dependents repositories, then
+ // return the "no changes are necessary" result if ignore_unsatisfiable
+ // argument is true and fail otherwise. The common approach is to pass true
+ // for this argument until the execution plan is finalized, assuming that
+ // the problematic dependency might be dropped.
//
struct evaluate_result
{
@@ -1833,12 +1845,12 @@ namespace bpkg
};
using package_dependents = vector<pair<shared_ptr<selected_package>,
- optional<dependency_constraint>>>;
+ optional<version_constraint>>>;
static optional<evaluate_result>
evaluate_dependency (database&,
const shared_ptr<selected_package>&,
- const version& desired,
+ const optional<version_constraint>& desired,
bool desired_sys,
bool patch,
bool explicitly,
@@ -1883,18 +1895,20 @@ namespace bpkg
if (i == deps.end ())
return nullopt;
- // If the user expectation is exactly what the selected package is then
- // no package change is required.
+ // If the selected package matches the user expectations then no package
+ // change is required.
//
const version& sv (sp->version);
bool ssys (sp->system ());
- // The requested dependency version and system flag.
+ // The requested dependency version constraint and system flag.
//
- const version& dv (i->version); // May be empty.
+ const optional<version_constraint>& dvc (i->constraint); // May be nullopt.
bool dsys (i->system);
- if (dv == sv && ssys == dsys)
+ if (ssys == dsys &&
+ dvc &&
+ (ssys ? sv == *dvc->min_version : satisfies (sv, dvc)))
{
l5 ([&]{trace << *sp << ": unchanged";});
@@ -1932,7 +1946,7 @@ namespace bpkg
return evaluate_dependency (db,
sp,
- dv,
+ dvc,
dsys,
i->patch,
true /* explicitly */,
@@ -1944,7 +1958,7 @@ namespace bpkg
static optional<evaluate_result>
evaluate_dependency (database& db,
const shared_ptr<selected_package>& sp,
- const version& dv,
+ const optional<version_constraint>& dvc,
bool dsys,
bool patch,
bool explicitly,
@@ -1971,9 +1985,9 @@ namespace bpkg
// upgrading. For a system package we also put no constraints just to make
// sure that the package is recognized.
//
- optional<dependency_constraint> c;
+ optional<version_constraint> c;
- if (dv.empty ())
+ if (!dvc)
{
assert (!dsys); // The version can't be empty for the system package.
@@ -1989,7 +2003,7 @@ namespace bpkg
}
}
else if (!dsys)
- c = dependency_constraint (dv);
+ c = dvc;
vector<pair<shared_ptr<available_package>,
shared_ptr<repository_fragment>>> afs (
@@ -2034,7 +2048,7 @@ namespace bpkg
//
// Note that we also handle a package stub here.
//
- if (dv.empty () && av < sv)
+ if (!dvc && av < sv)
{
assert (!dsys); // Version can't be empty for the system package.
@@ -2115,7 +2129,7 @@ namespace bpkg
// is the only thing that we can get, and so returning the "no change"
// result, unless we need to upgrade a package configured as system.
//
- if (dv.empty () && !ssys)
+ if (!dvc && !ssys)
{
assert (!dsys); // Version cannot be empty for the system package.
@@ -2123,13 +2137,14 @@ namespace bpkg
return no_change ();
}
- // If the desired dependency version is unavailable or unsatisfiable for
- // some dependents then we fail, unless requested not to do so. In the
- // later case we return the "no change" result.
+ // If the version satisfying the desired dependency version constraint is
+ // unavailable or unsatisfiable for some dependents then we fail, unless
+ // requested not to do so. In the later case we return the "no change"
+ // result.
//
if (ignore_unsatisfiable)
{
- l5 ([&]{trace << package_string (nm, dv, dsys)
+ l5 ([&]{trace << package_string (nm, dvc, dsys)
<< (unsatisfiable.empty ()
? ": no source"
: ": unsatisfiable");});
@@ -2144,7 +2159,7 @@ namespace bpkg
{
diag_record dr (fail);
- if (dv.empty () && patch)
+ if (!dvc && patch)
{
assert (ssys); // Otherwise, we would bail out earlier (see above).
@@ -2157,16 +2172,16 @@ namespace bpkg
<< "from its dependents' repositories";
}
else if (!stub)
- fail << package_string (nm, dsys ? version () : dv)
+ fail << package_string (nm, dsys ? nullopt : dvc)
<< " is not available from its dependents' repositories";
else // The only available package is a stub.
{
// Note that we don't advise to "build" the package as a system one as
// it is already as such (see above).
//
- assert (dv.empty () && !dsys && ssys);
+ assert (!dvc && !dsys && ssys);
- fail << package_string (nm, dv) << " is not available in source "
+ fail << package_string (nm, dvc) << " is not available in source "
<< "from its dependents' repositories";
}
}
@@ -2344,7 +2359,7 @@ namespace bpkg
optional<evaluate_result> r (
evaluate_dependency (db,
sp,
- version () /* desired */,
+ nullopt /* desired */,
false /*desired_sys */,
!*upgrade /* patch */,
false /* explicitly */,
@@ -2706,8 +2721,8 @@ namespace bpkg
}
// Expand the package specs into individual package args, parsing them
- // into the package scheme, name, and version components, and also saving
- // associated options and configuration variables.
+ // into the package scheme, name, and version constraint components, and
+ // also saving associated options and configuration variables.
//
// Note that the package specs that have no scheme and location cannot be
// unambiguously distinguished from the package archive and directory
@@ -2716,30 +2731,37 @@ namespace bpkg
//
struct pkg_arg
{
- package_scheme scheme;
- package_name name;
- bpkg::version version;
- string value;
- pkg_options options;
- strings config_vars;
+ package_scheme scheme;
+ package_name name;
+ optional<version_constraint> constraint;
+ string value;
+ pkg_options options;
+ strings config_vars;
};
// Create the parsed package argument.
//
auto arg_package = [] (package_scheme sc,
package_name nm,
- version vr,
+ optional<version_constraint> vc,
pkg_options os,
strings vs) -> pkg_arg
{
- pkg_arg r {sc, move (nm), move (vr), string (), move (os), move (vs)};
+ assert (!vc || !vc->empty ()); // May not be empty if present.
+
+ pkg_arg r {sc, move (nm), move (vc), string (), move (os), move (vs)};
switch (sc)
{
case package_scheme::sys:
{
- if (r.version.empty ())
- r.version = wildcard_version;
+ if (!r.constraint)
+ r.constraint = version_constraint (wildcard_version);
+
+ // The system package may only have an exact/wildcard version
+ // specified.
+ //
+ assert (r.constraint->min_version == r.constraint->max_version);
const system_package* sp (system_repository.find (r.name));
@@ -2747,7 +2769,7 @@ namespace bpkg
//
if (sp == nullptr || !sp->authoritative)
system_repository.insert (r.name,
- r.version,
+ *r.constraint->min_version,
true /* authoritative */);
break;
@@ -2764,7 +2786,7 @@ namespace bpkg
{
return pkg_arg {package_scheme::none,
package_name (),
- version (),
+ nullopt /* constraint */,
move (v),
move (os),
move (vs)};
@@ -2785,10 +2807,11 @@ namespace bpkg
string r (options && a.options.dependency () ? "?" : string ());
- r += package_string (
- a.name,
- a.version != wildcard_version ? a.version : version (),
- arg_sys (a));
+ r += package_string (a.name,
+ (a.constraint && !wildcard (*a.constraint)
+ ? a.constraint
+ : nullopt),
+ arg_sys (a));
if (options)
{
@@ -2837,6 +2860,20 @@ namespace bpkg
return r;
};
+ // The system package may only be constrained with an exact/wildcard
+ // version.
+ //
+ auto version_only = [] (package_scheme sc)
+ {
+ bool r (false);
+ switch (sc)
+ {
+ case package_scheme::none: r = false; break;
+ case package_scheme::sys: r = true; break;
+ }
+ return r;
+ };
+
for (pkg_spec& ps: specs)
{
if (ps.location.empty ())
@@ -2852,18 +2889,21 @@ namespace bpkg
bool sys (sc == package_scheme::sys);
package_name n (parse_package_name (s));
- version v (parse_package_version (s, sys, fold_zero_rev (sc)));
+
+ optional<version_constraint> vc (
+ parse_package_version_constraint (
+ s, sys, fold_zero_rev (sc), version_only (sc)));
// For system packages not associated with a specific repository
// location add the stub package to the imaginary system
// repository (see above for details).
//
- if (sys && !v.empty ())
+ if (sys && vc)
stubs.push_back (make_shared<available_package> (n));
pkg_args.push_back (arg_package (sc,
move (n),
- move (v),
+ move (vc),
move (ps.options),
move (ps.config_vars)));
}
@@ -2940,7 +2980,7 @@ namespace bpkg
continue;
}
- optional<dependency_constraint> c (patch_constraint (sp));
+ optional<version_constraint> c (patch_constraint (sp));
// Skip the non-patchable selected package. Note that the
// warning have already been issued in this case.
@@ -2971,7 +3011,7 @@ namespace bpkg
else
pkg_args.push_back (arg_package (package_scheme::none,
pv.first,
- move (pv.second),
+ version_constraint (pv.second),
ps.options,
ps.config_vars));
}
@@ -2993,7 +3033,10 @@ namespace bpkg
bool sys (sc == package_scheme::sys);
package_name n (parse_package_name (s));
- version v (parse_package_version (s, sys, fold_zero_rev (sc)));
+
+ optional<version_constraint> vc (
+ parse_package_version_constraint (
+ s, sys, fold_zero_rev (sc), version_only (sc)));
// Check if the package is present in the repository and its
// complements, recursively. If the version is not specified then
@@ -3019,12 +3062,12 @@ namespace bpkg
rfs.push_back (move (fr));
}
- optional<dependency_constraint> c;
+ optional<version_constraint> c;
shared_ptr<selected_package> sp;
if (!sys)
{
- if (v.empty ())
+ if (!vc)
{
if (ps.options.patch () &&
(sp = db.find<selected_package> (n)) != nullptr)
@@ -3039,7 +3082,7 @@ namespace bpkg
}
}
else
- c = dependency_constraint (v);
+ c = vc;
}
shared_ptr<available_package> ap (
@@ -3067,21 +3110,22 @@ namespace bpkg
dr << " or its complements";
if (sp == nullptr && ap != nullptr) // Is a stub.
- info << "specify sys:" << pkg << " if it is available "
- << "from the system";
+ dr << info << "specify "
+ << package_string (n, vc, true /* system */)
+ << " if it is available from the system";
}
// Note that for a system package the wildcard version will be set
// (see arg_package() for details).
//
- if (v.empty () && !sys)
- v = ap->version;
+ if (!vc && !sys)
+ vc = version_constraint (ap->version);
// Don't move options and variables as they may be reused.
//
pkg_args.push_back (arg_package (sc,
move (n),
- move (v),
+ move (vc),
ps.options,
ps.config_vars));
}
@@ -3119,10 +3163,15 @@ namespace bpkg
// Note that the variable order may matter.
//
+ // @@ Later we may relax this and replace one package argument with
+ // another if they only differ with the version constraint and one
+ // constraint satisfies the other. We will also need to carefully
+ // maintain the above *_pkgs lists.
+ //
if (!r.second &&
- (a.scheme != pa.scheme ||
- a.name != pa.name ||
- a.version != pa.version ||
+ (a.scheme != pa.scheme ||
+ a.name != pa.name ||
+ a.constraint != pa.constraint ||
!compare_options (a.options, pa.options) ||
a.config_vars != pa.config_vars))
fail << "duplicate package " << pa.name <<
@@ -3198,7 +3247,7 @@ namespace bpkg
pa = arg_package (package_scheme::none,
m.name,
- m.version,
+ version_constraint (m.version),
move (pa.options),
move (pa.config_vars));
@@ -3284,7 +3333,7 @@ namespace bpkg
pa = arg_package (package_scheme::none,
m.name,
- m.version,
+ version_constraint (m.version),
move (pa.options),
move (pa.config_vars));
@@ -3334,14 +3383,15 @@ namespace bpkg
// Don't fold the zero revision so that we build the exact X+0
// package revision, if it is specified.
//
- version v (
- parse_package_version (package,
- false /* allow_wildcard */,
- false /* fold_zero_revision */));
+ optional<version_constraint> vc (
+ parse_package_version_constraint (
+ package,
+ false /* allow_wildcard */,
+ false /* fold_zero_revision */));
pa = arg_package (package_scheme::none,
move (n),
- move (v),
+ move (vc),
move (pa.options),
move (pa.config_vars));
}
@@ -3354,9 +3404,9 @@ namespace bpkg
// for a source code package. For a system package we pick the
// latest one just to make sure the package is recognized.
//
- optional<dependency_constraint> c;
+ optional<version_constraint> c;
- if (pa.version.empty ())
+ if (!pa.constraint)
{
assert (!arg_sys (pa));
@@ -3378,7 +3428,7 @@ namespace bpkg
}
}
else if (!arg_sys (pa))
- c = dependency_constraint (pa.version);
+ c = pa.constraint;
auto rp (find_available_one (db, pa.name, c, root));
ap = move (rp.first);
@@ -3433,11 +3483,9 @@ namespace bpkg
// Make sure that the package is known.
//
- auto apr (pa.version.empty () || sys
+ auto apr (!pa.constraint || sys
? find_available (db, pa.name, nullopt)
- : find_available (db,
- pa.name,
- dependency_constraint (pa.version)));
+ : find_available (db, pa.name, *pa.constraint));
if (apr.empty ())
{
@@ -3452,7 +3500,7 @@ namespace bpkg
sp = db.find<selected_package> (pa.name);
dep_pkgs.push_back (dependency_package {move (pa.name),
- move (pa.version),
+ move (pa.constraint),
move (sp),
sys,
pa.options.patch (),
@@ -3496,7 +3544,7 @@ namespace bpkg
//
if (ap == nullptr)
{
- if (!pa.version.empty () &&
+ if (pa.constraint &&
find_available_one (db,
pa.name,
nullopt,
@@ -3509,10 +3557,10 @@ namespace bpkg
ap = nullptr;
}
- // If the user asked for a specific version, then that's what we
- // ought to be building.
+ // If the user constrained the version, then that's what we ought to
+ // be building.
//
- if (!pa.version.empty ())
+ if (pa.constraint)
{
for (;;)
{
@@ -3520,9 +3568,11 @@ namespace bpkg
break;
// Otherwise, our only chance is that the already selected object
- // is that exact version.
+ // satisfies the version constraint.
//
- if (sp != nullptr && !sp->system () && sp->version == pa.version)
+ if (sp != nullptr &&
+ !sp->system () &&
+ satisfies (sp->version, pa.constraint))
break; // Derive ap from sp below.
found = false;
@@ -3584,9 +3634,12 @@ namespace bpkg
assert (!arg_sys (pa));
dr << arg_string (pa, false /* options */)
- << " is not available in source" <<
- info << "specify sys:" << arg_string (pa, false /* options */)
- << " if it is available from the system";
+ << " is not available in source";
+
+ pa.scheme = package_scheme::sys;
+
+ dr << info << "specify " << arg_string (pa, false /* options */)
+ << " if it is available from the system";
}
}
@@ -3618,27 +3671,25 @@ namespace bpkg
move (sp),
move (ap),
move (af),
- true, // Hold package.
- !pa.version.empty (), // Hold version.
- {}, // Constraints.
+ true, // Hold package.
+ pa.constraint.has_value (), // Hold version.
+ {}, // Constraints.
arg_sys (pa),
keep_out,
move (pa.config_vars),
- {package_name ()}, // Required by (command line).
- 0}; // Adjustments.
+ {package_name ()}, // Required by (command line).
+ 0}; // Adjustments.
l4 ([&]{trace << "stashing held package "
<< p.available_name_version ();});
- // "Fix" the version the user asked for by adding the '==' constraint.
+ // "Fix" the version the user asked for by adding the constraint.
//
// Note: for a system package this must always be present (so that
// this build_package instance is never replaced).
//
- if (!pa.version.empty ())
- p.constraints.emplace_back (
- "command line",
- dependency_constraint (pa.version));
+ if (pa.constraint)
+ p.constraints.emplace_back ("command line", move (*pa.constraint));
hold_pkgs.push_back (move (p));
}
@@ -3664,7 +3715,7 @@ namespace bpkg
const package_name& name (sp->name);
- optional<dependency_constraint> pc;
+ optional<version_constraint> pc;
if (o.patch ())
{
@@ -3825,23 +3876,21 @@ namespace bpkg
for (const dependency_package& p: dep_pkgs)
{
build_package bp {
- nullopt, // Action.
- nullptr, // Selected package.
- nullptr, // Available package/repository fragment.
+ nullopt, // Action.
+ nullptr, // Selected package.
+ nullptr, // Available package/repository frag.
nullptr,
- false, // Hold package.
- !p.version.empty (), // Hold version.
- {}, // Constraints.
+ false, // Hold package.
+ p.constraint.has_value (), // Hold version.
+ {}, // Constraints.
p.system,
p.keep_out,
p.config_vars,
- {package_name ()}, // Required by (command line).
- 0}; // Adjustments.
+ {package_name ()}, // Required by (command line).
+ 0}; // Adjustments.
- if (!p.version.empty ())
- bp.constraints.emplace_back (
- "command line",
- dependency_constraint (p.version));
+ if (p.constraint)
+ bp.constraints.emplace_back ("command line", *p.constraint);
pkgs.enter (p.name, move (bp));
}
@@ -4066,11 +4115,12 @@ namespace bpkg
if (!scratch)
{
// First, we check if the refinement is required, ignoring the
- // unsatisfiable dependency versions. If we end up refining the
- // execution plan, such dependencies might be dropped, and then
- // there will be nothing to complain about. When no more refinements
- // are necessary we will run the diagnostics check, to make sure
- // that the unsatisfiable dependency, if left, is reported.
+ // unsatisfiable dependency version constraints. If we end up
+ // refining the execution plan, such dependencies might be dropped,
+ // and then there will be nothing to complain about. When no more
+ // refinements are necessary we will run the diagnostics check, to
+ // make sure that the unsatisfiable dependency, if left, is
+ // reported.
//
auto need_refinement = [&eval_dep, &deps, rec_pkgs, &db, &o] (
bool diag = false) -> bool
diff --git a/bpkg/pkg-status.cxx b/bpkg/pkg-status.cxx
index bfba21f..b4b8de6 100644
--- a/bpkg/pkg-status.cxx
+++ b/bpkg/pkg-status.cxx
@@ -19,10 +19,10 @@ namespace bpkg
{
struct package
{
- package_name name;
- bpkg::version version; // Empty if unspecified.
- shared_ptr<selected_package> selected; // NULL if none selected.
- optional<dependency_constraint> constraint; // Version constraint, if any.
+ package_name name;
+ bpkg::version version; // Empty if unspecified.
+ shared_ptr<selected_package> selected; // NULL if none selected.
+ optional<version_constraint> constraint; // Version constraint, if any.
};
using packages = vector<package>;
@@ -236,7 +236,7 @@ namespace bpkg
for (const auto& pair: s->prerequisites)
{
shared_ptr<selected_package> d (pair.first.load ());
- const optional<dependency_constraint>& c (pair.second);
+ const optional<version_constraint>& c (pair.second);
dpkgs.push_back (package {d->name, version (), move (d), c});
}
}
diff --git a/bpkg/satisfaction.cxx b/bpkg/satisfaction.cxx
index 53fd3b8..c3c4995 100644
--- a/bpkg/satisfaction.cxx
+++ b/bpkg/satisfaction.cxx
@@ -15,7 +15,7 @@ using namespace butl;
namespace bpkg
{
bool
- satisfies (const version& v, const dependency_constraint& c)
+ satisfies (const version& v, const version_constraint& c)
{
assert (!c.empty () && c.complete ());
@@ -25,7 +25,7 @@ namespace bpkg
bool s (true);
// Here an absent revision means zero revision and version X must satisfy
- // the [X+0 ...) dependency constraint. Note that technically X < X+0.
+ // the [X+0 ...) version constraint. Note that technically X < X+0.
//
version ev (v.epoch,
v.upstream,
@@ -52,7 +52,7 @@ namespace bpkg
}
bool
- satisfies (const dependency_constraint& l, const dependency_constraint& r)
+ satisfies (const version_constraint& l, const version_constraint& r)
{
assert (!l.empty () && l.complete () && !r.empty () && r.complete ());
diff --git a/bpkg/satisfaction.hxx b/bpkg/satisfaction.hxx
index 31a3e49..5ab32a1 100644
--- a/bpkg/satisfaction.hxx
+++ b/bpkg/satisfaction.hxx
@@ -13,16 +13,16 @@
namespace bpkg
{
- // Note: all of the following functions expect the package dependency
+ // Note: all of the following functions expect the package version
// constraints to be complete.
// Return true if version satisfies the constraint.
//
bool
- satisfies (const version&, const dependency_constraint&);
+ satisfies (const version&, const version_constraint&);
inline bool
- satisfies (const version& v, const optional<dependency_constraint>& c)
+ satisfies (const version& v, const optional<version_constraint>& c)
{
return !c || satisfies (v, *c);
}
@@ -32,11 +32,11 @@ namespace bpkg
// l is a subset of r.
//
bool
- satisfies (const dependency_constraint& l, const dependency_constraint& r);
+ satisfies (const version_constraint& l, const version_constraint& r);
inline bool
- satisfies (const optional<dependency_constraint>& l,
- const optional<dependency_constraint>& r)
+ satisfies (const optional<version_constraint>& l,
+ const optional<version_constraint>& r)
{
return l ? (!r || satisfies (*l, *r)) : !r;
}
diff --git a/bpkg/satisfaction.test.cxx b/bpkg/satisfaction.test.cxx
index fef30e1..4857e0d 100644
--- a/bpkg/satisfaction.test.cxx
+++ b/bpkg/satisfaction.test.cxx
@@ -9,43 +9,43 @@ namespace bpkg
static int
main (int, char*[])
{
- using dc = dependency_constraint;
+ using vc = version_constraint;
- assert ( satisfies (dc ("[1.0 2.0]"), dc ("[1.0+0 2.0]")));
- assert (!satisfies (dc ("[1.0 2.0]"), dc ("[1.0+1 2.0]")));
- assert ( satisfies (dc ("[1.0+0 2.0]"), dc ("[1.0 2.0]")));
- assert ( satisfies (dc ("[1.0+1 2.0]"), dc ("[1.0 2.0]")));
+ assert ( satisfies (vc ("[1.0 2.0]"), vc ("[1.0+0 2.0]")));
+ assert (!satisfies (vc ("[1.0 2.0]"), vc ("[1.0+1 2.0]")));
+ assert ( satisfies (vc ("[1.0+0 2.0]"), vc ("[1.0 2.0]")));
+ assert ( satisfies (vc ("[1.0+1 2.0]"), vc ("[1.0 2.0]")));
- assert (!satisfies (dc ("[1.0+0 2.0]"), dc ("(1.0 2.0]")));
- assert (!satisfies (dc ("[1.0+1 2.0]"), dc ("(1.0 2.0]")));
- assert (!satisfies (dc ("(1.0+0 2.0]"), dc ("(1.0 2.0]")));
- assert (!satisfies (dc ("(1.0+1 2.0]"), dc ("(1.0 2.0]")));
- assert ( satisfies (dc ("(1.0+0 2.0]"), dc ("[1.0 2.0]")));
- assert ( satisfies (dc ("(1.0+1 2.0]"), dc ("[1.0 2.0]")));
+ assert (!satisfies (vc ("[1.0+0 2.0]"), vc ("(1.0 2.0]")));
+ assert (!satisfies (vc ("[1.0+1 2.0]"), vc ("(1.0 2.0]")));
+ assert (!satisfies (vc ("(1.0+0 2.0]"), vc ("(1.0 2.0]")));
+ assert (!satisfies (vc ("(1.0+1 2.0]"), vc ("(1.0 2.0]")));
+ assert ( satisfies (vc ("(1.0+0 2.0]"), vc ("[1.0 2.0]")));
+ assert ( satisfies (vc ("(1.0+1 2.0]"), vc ("[1.0 2.0]")));
- assert (!satisfies (dc ("[1.0 2.0+0]"), dc ("[1.0 2.0)")));
- assert (!satisfies (dc ("[1.0 2.0+1]"), dc ("[1.0 2.0)")));
- assert ( satisfies (dc ("[1.0 2.0+0)"), dc ("[1.0 2.0)")));
- assert (!satisfies (dc ("[1.0 2.0+1)"), dc ("[1.0 2.0)")));
+ assert (!satisfies (vc ("[1.0 2.0+0]"), vc ("[1.0 2.0)")));
+ assert (!satisfies (vc ("[1.0 2.0+1]"), vc ("[1.0 2.0)")));
+ assert ( satisfies (vc ("[1.0 2.0+0)"), vc ("[1.0 2.0)")));
+ assert (!satisfies (vc ("[1.0 2.0+1)"), vc ("[1.0 2.0)")));
// Swap the above constraints.
//
- assert (!satisfies (dc ("[1.0 2.0]"), dc ("[1.0 2.0+0]")));
- assert (!satisfies (dc ("[1.0 2.0]"), dc ("[1.0 2.0+1]")));
- assert ( satisfies (dc ("[1.0 2.0+0]"), dc ("[1.0 2.0]")));
- assert ( satisfies (dc ("[1.0 2.0+1]"), dc ("[1.0 2.0]")));
-
- assert ( satisfies (dc ("(1.0 2.0]"), dc ("[1.0+0 2.0]")));
- assert ( satisfies (dc ("(1.0 2.0]"), dc ("[1.0+1 2.0]")));
- assert ( satisfies (dc ("(1.0 2.0]"), dc ("(1.0+0 2.0]")));
- assert ( satisfies (dc ("(1.0 2.0]"), dc ("(1.0+1 2.0]")));
- assert (!satisfies (dc ("[1.0 2.0]"), dc ("(1.0+0 2.0]")));
- assert (!satisfies (dc ("[1.0 2.0]"), dc ("(1.0+1 2.0]")));
-
- assert ( satisfies (dc ("[1.0 2.0)"), dc ("[1.0 2.0+0)")));
- assert ( satisfies (dc ("[1.0 2.0)"), dc ("[1.0 2.0+1)")));
- assert (!satisfies (dc ("[1.0 2.0]"), dc ("[1.0 2.0+0)")));
- assert (!satisfies (dc ("[1.0 2.0]"), dc ("[1.0 2.0+1)")));
+ assert (!satisfies (vc ("[1.0 2.0]"), vc ("[1.0 2.0+0]")));
+ assert (!satisfies (vc ("[1.0 2.0]"), vc ("[1.0 2.0+1]")));
+ assert ( satisfies (vc ("[1.0 2.0+0]"), vc ("[1.0 2.0]")));
+ assert ( satisfies (vc ("[1.0 2.0+1]"), vc ("[1.0 2.0]")));
+
+ assert ( satisfies (vc ("(1.0 2.0]"), vc ("[1.0+0 2.0]")));
+ assert ( satisfies (vc ("(1.0 2.0]"), vc ("[1.0+1 2.0]")));
+ assert ( satisfies (vc ("(1.0 2.0]"), vc ("(1.0+0 2.0]")));
+ assert ( satisfies (vc ("(1.0 2.0]"), vc ("(1.0+1 2.0]")));
+ assert (!satisfies (vc ("[1.0 2.0]"), vc ("(1.0+0 2.0]")));
+ assert (!satisfies (vc ("[1.0 2.0]"), vc ("(1.0+1 2.0]")));
+
+ assert ( satisfies (vc ("[1.0 2.0)"), vc ("[1.0 2.0+0)")));
+ assert ( satisfies (vc ("[1.0 2.0)"), vc ("[1.0 2.0+1)")));
+ assert (!satisfies (vc ("[1.0 2.0]"), vc ("[1.0 2.0+0)")));
+ assert (!satisfies (vc ("[1.0 2.0]"), vc ("[1.0 2.0+1)")));
return 0;
}