aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbpkg/manifest.cxx366
-rw-r--r--libbpkg/manifest.hxx5
2 files changed, 181 insertions, 190 deletions
diff --git a/libbpkg/manifest.cxx b/libbpkg/manifest.cxx
index 26039c7..64dac1f 100644
--- a/libbpkg/manifest.cxx
+++ b/libbpkg/manifest.cxx
@@ -580,6 +580,176 @@ namespace bpkg
// depends
//
+ dependency_constraint::
+ dependency_constraint (const string& s)
+ {
+ auto bail = [] (const string& d) {throw invalid_argument (d);};
+
+ char c (s[0]);
+ if (c == '(' || c == '[') // The version range.
+ {
+ bool min_open (c == '(');
+
+ size_t p (s.find_first_not_of (spaces, 1));
+ if (p == string::npos)
+ bail ("no prerequisite package min version specified");
+
+ size_t e (s.find_first_of (spaces, p));
+
+ const char* no_max_version (
+ "no prerequisite package max version specified");
+
+ if (e == string::npos)
+ bail (no_max_version);
+
+ version min_version;
+
+ try
+ {
+ min_version = version (string (s, p, e - p));
+ }
+ catch (const invalid_argument& e)
+ {
+ bail (string ("invalid prerequisite package min version: ") +
+ e.what ());
+ }
+
+ p = s.find_first_not_of (spaces, e);
+ if (p == string::npos)
+ bail (no_max_version);
+
+ e = s.find_first_of (" \t])", p);
+
+ const char* invalid_range ("invalid prerequisite package version range");
+
+ if (e == string::npos)
+ bail (invalid_range);
+
+ version max_version;
+
+ try
+ {
+ max_version = version (string (s, p, e - p));
+ }
+ catch (const invalid_argument& e)
+ {
+ bail (string ("invalid prerequisite package max version: ") +
+ e.what ());
+ }
+
+ e = s.find_first_of ("])", e); // Might be a space.
+ if (e == string::npos)
+ bail (invalid_range);
+
+ if (e + 1 != s.size ())
+ bail ("unexpected text after prerequisite package version range");
+
+ try
+ {
+ *this = dependency_constraint (move (min_version),
+ min_open,
+ move (max_version),
+ s[e] == ')');
+ }
+ catch (const invalid_argument& e)
+ {
+ bail (string ("invalid dependency constraint: ") + e.what ());
+ }
+ }
+ else if (c == '~' || c == '^') // The shortcut operator.
+ {
+ // To be used in the shortcut operator the package version must
+ // be a standard version.
+ //
+ standard_version_constraint vc;
+
+ try
+ {
+ vc = standard_version_constraint (s);
+ }
+ catch (const invalid_argument& e)
+ {
+ bail (string ("invalid dependency constraint: ") + e.what ());
+ }
+
+ try
+ {
+ assert (vc.min_version && vc.max_version);
+
+ *this = dependency_constraint (
+ version (vc.min_version->string ()),
+ vc.min_open,
+ version (vc.max_version->string ()),
+ vc.max_open);
+ }
+ catch (const invalid_argument&)
+ {
+ // The standard version is a package version, so the conversion
+ // should never fail.
+ //
+ assert (false);
+ }
+ }
+ else // The version comparison notation.
+ {
+ enum comparison {eq, lt, gt, le, ge};
+ comparison operation (eq); // Uninitialized warning.
+ size_t p (2);
+
+ if (s.compare (0, 2, "==") == 0)
+ operation = eq;
+ else if (s.compare (0, 2, ">=") == 0)
+ operation = ge;
+ else if (s.compare (0, 2, "<=") == 0)
+ operation = le;
+ else if (c == '>')
+ {
+ operation = gt;
+ p = 1;
+ }
+ else if (c == '<')
+ {
+ operation = lt;
+ p = 1;
+ }
+ else
+ bail ("invalid prerequisite package version comparison");
+
+ p = s.find_first_not_of (spaces, p);
+
+ if (p == string::npos)
+ bail ("no prerequisite package version specified");
+
+ try
+ {
+ version v (string (s, p));
+
+ switch (operation)
+ {
+ case comparison::eq:
+ *this = dependency_constraint (v);
+ break;
+ case comparison::lt:
+ *this = dependency_constraint (nullopt, true, move (v), true);
+ break;
+ case comparison::le:
+ *this = dependency_constraint (nullopt, true, move (v), false);
+ break;
+ case comparison::gt:
+ *this = dependency_constraint (move (v), true, nullopt, true);
+ break;
+ case comparison::ge:
+ *this = dependency_constraint (move (v), false, nullopt, true);
+ break;
+ }
+ }
+ catch (const invalid_argument& e)
+ {
+ bail (string ("invalid prerequisite package version: ") + e.what ());
+ }
+
+ }
+ }
dependency_constraint::
dependency_constraint (optional<version> mnv, bool mno,
@@ -1045,7 +1215,7 @@ namespace bpkg
// Find end of name (ne).
//
- static const string cb ("=<>([~^");
+ const string cb ("=<>([~^");
for (char c; i != e && cb.find (c = *i) == string::npos; ++i)
{
if (!space (c))
@@ -1061,198 +1231,16 @@ namespace bpkg
if (nm.empty ())
bad_value ("prerequisite package name not specified");
- // Got to version range.
- //
- dependency_constraint dc;
- const char* op (&*i);
- char c (*op);
- if (c == '(' || c == '[')
+ try
{
- bool min_open (c == '(');
-
- string::size_type pos (lv.find_first_not_of (spaces, ++i - b));
- if (pos == string::npos)
- bad_value ("no prerequisite package min version specified");
-
- i = b + pos;
- pos = lv.find_first_of (spaces, pos);
-
- static const char* no_max_version (
- "no prerequisite package max version specified");
-
- if (pos == string::npos)
- bad_value (no_max_version);
-
- version min_version;
-
- try
- {
- min_version = version (string (i, b + pos));
- }
- catch (const invalid_argument& e)
- {
- bad_value (
- string ("invalid prerequisite package min version: ") +
- e.what ());
- }
-
- pos = lv.find_first_not_of (spaces, pos);
- if (pos == string::npos)
- bad_value (no_max_version);
-
- i = b + pos;
- static const string mve (spaces + "])");
- pos = lv.find_first_of (mve, pos);
-
- static const char* invalid_range (
- "invalid prerequisite package version range");
-
- if (pos == string::npos)
- bad_value (invalid_range);
-
- version max_version;
-
- try
- {
- max_version = version (string (i, b + pos));
- }
- catch (const invalid_argument& e)
- {
- bad_value (
- string ("invalid prerequisite package max version: ") +
- e.what ());
- }
-
- pos = lv.find_first_of ("])", pos); // Might be a space.
- if (pos == string::npos)
- bad_value (invalid_range);
-
- try
- {
- dc = dependency_constraint (move (min_version),
- min_open,
- move (max_version),
- lv[pos] == ')');
- }
- catch (const invalid_argument& e)
- {
- bad_value (
- string ("invalid dependency constraint: ") + e.what ());
- }
-
- if (lv[pos + 1] != '\0')
- bad_value (
- "unexpected text after prerequisite package version range");
+ da.push_back (
+ dependency {move (nm), dependency_constraint (string (i, e))});
}
- else if (c == '~' || c == '^') // The shortcut operator.
+ catch (const invalid_argument& e)
{
- // To be used in the shortcut operator the package version must
- // be a standard version.
- //
- standard_version_constraint vc;
-
- try
- {
- vc = standard_version_constraint (op);
- }
- catch (const invalid_argument& e)
- {
- bad_value (string ("invalid dependency constraint: ") +
- e.what ());
- }
-
- try
- {
- assert (vc.min_version && vc.max_version);
-
- dc = dependency_constraint (
- version (vc.min_version->string ()),
- vc.min_open,
- version (vc.max_version->string ()),
- vc.max_open);
- }
- catch (const invalid_argument&)
- {
- // The standard version is a package version, so the conversion
- // should never fail.
- //
- assert (false);
- }
+ bad_value (
+ string ("invalid dependency constraint: ") + e.what ());
}
- else
- {
- // Version comparison notation.
- //
- enum comparison {eq, lt, gt, le, ge};
- comparison operation (eq); // Uninitialized warning.
-
- if (strncmp (op, "==", 2) == 0)
- {
- operation = eq;
- i += 2;
- }
- else if (strncmp (op, ">=", 2) == 0)
- {
- operation = ge;
- i += 2;
- }
- else if (strncmp (op, "<=", 2) == 0)
- {
- operation = le;
- i += 2;
- }
- else if (*op == '>')
- {
- operation = gt;
- ++i;
- }
- else if (*op == '<')
- {
- operation = lt;
- ++i;
- }
- else
- bad_value ("invalid prerequisite package version comparison");
-
- string::size_type pos (lv.find_first_not_of (spaces, i - b));
-
- if (pos == string::npos)
- bad_value ("no prerequisite package version specified");
-
- version v;
-
- try
- {
- v = version (lv.c_str () + pos);
- }
- catch (const invalid_argument& e)
- {
- bad_value (string ("invalid prerequisite package version: ") +
- e.what ());
- }
-
- switch (operation)
- {
- case comparison::eq:
- dc = dependency_constraint (v);
- break;
- case comparison::lt:
- dc = dependency_constraint (nullopt, true, move (v), true);
- break;
- case comparison::le:
- dc = dependency_constraint (nullopt, true, move (v), false);
- break;
- case comparison::gt:
- dc = dependency_constraint (move (v), true, nullopt, true);
- break;
- case comparison::ge:
- dc = dependency_constraint (move (v), false, nullopt, true);
- break;
- }
- }
-
- dependency d {move (nm), move (dc)};
- da.push_back (move (d));
}
}
diff --git a/libbpkg/manifest.hxx b/libbpkg/manifest.hxx
index 81dd5f0..796db7a 100644
--- a/libbpkg/manifest.hxx
+++ b/libbpkg/manifest.hxx
@@ -273,13 +273,16 @@ namespace bpkg
// depends
//
- struct LIBBPKG_EXPORT dependency_constraint
+ class LIBBPKG_EXPORT dependency_constraint
{
+ public:
butl::optional<version> min_version;
butl::optional<version> max_version;
bool min_open;
bool max_open;
+ dependency_constraint (const std::string&);
+
dependency_constraint (butl::optional<version> min_version, bool min_open,
butl::optional<version> max_version, bool max_open);