From 9d11f3aaa98ac3a8057bf535bbf51e1a1c3f005f Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Fri, 4 May 2018 15:45:09 +0300 Subject: Change version epoch syntax from '~' to '+-' --- libbpkg/manifest.cxx | 107 +++++++++++++++++-------------- tests/manifest/testscript | 4 +- tests/package-version/driver.cxx | 135 +++++++++++++++++---------------------- 3 files changed, 118 insertions(+), 128 deletions(-) diff --git a/libbpkg/manifest.cxx b/libbpkg/manifest.cxx index 35df21d..9fb68f3 100644 --- a/libbpkg/manifest.cxx +++ b/libbpkg/manifest.cxx @@ -278,10 +278,12 @@ namespace bpkg enum class mode {epoch, upstream, release, revision}; mode m (pr == parse::full - ? mode::epoch - : pr == parse::upstream - ? mode::upstream - : mode::release); + ? (v[0] == '+' + ? mode::epoch + : mode::upstream) + : (pr == parse::upstream + ? mode::upstream + : mode::release)); canonical_part canon_upstream; canonical_part canon_release; @@ -289,44 +291,23 @@ namespace bpkg canonical_part* canon_part ( pr == parse::release ? &canon_release : &canon_upstream); - const char* cb (v); // Begin of a component. - const char* ub (v); // Begin of upstream part. - const char* ue (v); // End of upstream part. - const char* rb (v); // Begin of release part. - const char* re (v); // End of release part. - const char* lnn (v - 1); // Last non numeric char. + const char* cb (m != mode::epoch ? v : v + 1); // Begin of a component. + const char* ub (cb); // Begin of upstream part. + const char* ue (cb); // End of upstream part. + const char* rb (cb); // Begin of release part. + const char* re (cb); // End of release part. + const char* lnn (cb - 1); // Last non numeric char. - const char* p (v); + const char* p (cb); for (char c; (c = *p) != '\0'; ++p) { switch (c) { - case '~': - { - if (pr != parse::full) - bad_arg ("unexpected '~' character"); - - // Process the epoch part. - // - if (m != mode::epoch || p == v) - bad_arg ("unexpected '~' character position"); - - if (lnn >= cb) // Contains non-digits. - bad_arg ("epoch should be 2-byte unsigned integer"); - - epoch = uint16 (string (cb, p), "epoch"); - - m = mode::upstream; - cb = p + 1; - ub = cb; - break; - } - case '+': case '-': case '.': { - // Process the upsteam or release part component. + // Process the epoch part or the upstream/release part component. // // Characters '+', '-' are only valid for the full version parsing. @@ -338,35 +319,58 @@ namespace bpkg // state. // if (m == mode::revision || (c == '-' && m == mode::release) || - p == cb) + (c != '-' && m == mode::epoch) || p == cb) bad_arg (string ("unexpected '") + c + "' character position"); - // Append the component to the current canonical part. + // Depending on the mode, parse epoch or append the component to the + // current canonical part. // - canon_part->add (cb, p, lnn < cb); + if (m == mode::epoch) + { + if (lnn >= cb) // Contains non-digits. + bad_arg ("epoch should be 2-byte unsigned integer"); + + epoch = uint16 (string (cb, p), "epoch"); + } + else + canon_part->add (cb, p, lnn < cb); // Update the parsing state. // + // Advance begin of a component. + // cb = p + 1; - if (m == mode::upstream || m == mode::epoch) + // Advance end of the upstream/release parts. + // + if (m == mode::upstream) ue = p; else if (m == mode::release) re = p; else - assert (false); + assert (m == mode::epoch); + // Switch the mode if the component is terminated with '+' or '-'. + // if (c == '+') m = mode::revision; else if (c == '-') { - m = mode::release; - canon_part = &canon_release; - rb = cb; - re = cb; + if (m == mode::epoch) + { + m = mode::upstream; + ub = cb; + ue = cb; + } + else + { + m = mode::release; + rb = cb; + re = cb; + + canon_part = &canon_release; + } } - else if (m == mode::epoch) - m = mode::upstream; break; } @@ -383,10 +387,13 @@ namespace bpkg assert (p >= cb); // 'p' denotes the end of the last component. - // An empty component is valid for the release part, and for the upstream - // part when constructing empty or max limit version. + // The epoch must always be followed by the upstream. + // + // An empty component is valid for the release part, and for the + // upstream part when constructing empty or max limit version. // - if (p == cb && m != mode::release && pr != parse::upstream) + if (m == mode::epoch || + (p == cb && m != mode::release && pr != parse::upstream)) bad_arg ("unexpected end"); // Parse the last component. @@ -402,7 +409,7 @@ namespace bpkg { canon_part->add (cb, p, lnn < cb); - if (m == mode::epoch || m == mode::upstream) + if (m == mode::upstream) ue = p; else if (m == mode::release) re = p; @@ -494,7 +501,9 @@ namespace bpkg if (empty ()) throw logic_error ("empty version"); - std::string v (epoch != 0 ? to_string (epoch) + "~" + upstream : upstream); + std::string v (epoch != 0 + ? '+' + to_string (epoch) + '-' + upstream + : upstream); if (release) { diff --git a/tests/manifest/testscript b/tests/manifest/testscript index 7521785..8bfe73a 100644 --- a/tests/manifest/testscript +++ b/tests/manifest/testscript @@ -66,12 +66,12 @@ sha256sum: d4b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 : name: libbaz - version: 2~3.4A.5+3 + version: +2-3.4A.5+3 summary: Modern baz system license: LGPLv2 url: http://www.example.org/projects/libbar/ email: libbaz-users@example.org - location: libbaz/libbaz-2~3.4A.5+3.tar.gz + location: libbaz/libbaz-+2-3.4A.5+3.tar.gz sha256sum: b5b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 EOF } diff --git a/tests/package-version/driver.cxx b/tests/package-version/driver.cxx index 4925711..f5397c4 100644 --- a/tests/package-version/driver.cxx +++ b/tests/package-version/driver.cxx @@ -83,32 +83,31 @@ namespace bpkg try { assert (bad_version ("")); // Empty upstream. - assert (bad_version ("1~")); // Same. - assert (bad_version ("1~+3")); // Same. - assert (bad_version ("+3")); // Same. - assert (bad_version ("1~-a")); // Same. - assert (bad_version ("1~-a+3")); // Same. + assert (bad_version ("+1-")); // Same. + assert (bad_version ("+1-+3")); // Same. + assert (bad_version ("+0-+3")); // Same. + assert (bad_version ("+1--a")); // Same. + assert (bad_version ("+1--a+3")); // Same. assert (bad_version ("-a+3")); // Same. - assert (bad_version ("~3.5")); // Empty epoch. + assert (bad_version ("+-3.5")); // Empty epoch. assert (bad_version ("a+")); // Empty revision. - assert (bad_version ("1~2~4.1+3")); // Extra epoch. + assert (bad_version ("+1-+2-4.1+3")); // Extra epoch. + assert (bad_version ("1-2-4.1")); // Missed epoch marker. assert (bad_version ("3.5+1+4")); // Extra revision. - assert (bad_version ("1~~2+3")); // Duplicated epoch separator. - assert (bad_version ("1~2++3")); // Duplicated revision separator. - assert (bad_version ("a.39485739122323231.3")); // Too long component. - assert (bad_version ("a.00000000000000000.3")); // Too many zeros. - assert (bad_version ("1-a.00000000000000000")); // Same. - assert (bad_version ("65536~q.3")); // Too big epoch. + assert (bad_version ("++1-2+3")); // Duplicated epoch marker. + assert (bad_version ("+1-2++3")); // Duplicated revision separator. + assert (bad_version ("+65536-q.3")); // Too big epoch. assert (bad_version ("1+q+65536")); // Too big revision. - assert (bad_version ("3.5~1.4")); // Components in epoch. + assert (bad_version ("+3.5-1.4")); // Components in epoch. + assert (bad_version ("+3+5-1.4")); // Plus in epoch. assert (bad_version ("3.5+1.4")); // Components in revision. assert (bad_version ("3 5+1")); // Non alpha-numeric in upstream. - assert (bad_version ("1~ +3")); // Same. + assert (bad_version ("+1- +3")); // Same. assert (bad_version ("1-3 5+1")); // Non alpha-numeric in release. - assert (bad_version ("1~1- +3")); // Same. - assert (bad_version ("3 5~4+1")); // Non alpha-numeric in epoch. - assert (bad_version ("2b~a")); // Same. - assert (bad_version ("1~34.1+3 5")); // Non numeric in revision. + assert (bad_version ("+1-1- +3")); // Same. + assert (bad_version ("+3 5-4+1")); // Non numeric in epoch. + assert (bad_version ("+2b-a")); // Same. + assert (bad_version ("+1-34.1+3 5")); // Non numeric in revision. assert (bad_version ("a+3s")); // Same. assert (bad_version ("a.")); // Not completed upstream. assert (bad_version ("a..b")); // Empty upstream component. @@ -119,13 +118,17 @@ namespace bpkg assert (bad_version ("0.0-")); // Same. assert (bad_version ("1.2.3+1#1")); // Unexpected iteration. - assert (bad_version (0, "1", "", 1)); // Revision for empty release. - assert (bad_version (1, "1~1.1", "", 2)); // Epoch in upstream. - assert (bad_version (1, "1.1-1", "", 2)); // Release in upstream. - assert (bad_version (1, "1.1+1", "", 2)); // Revision in upstream. - assert (bad_version (1, "1", "1~1.1", 2)); // Epoch in release. - assert (bad_version (1, "1", "1.1-1", 2)); // Release in release. - assert (bad_version (1, "1", "1.1+1", 2)); // Revision in release. + assert (bad_version ("a.39485739122323231.3")); // Too long component. + assert (bad_version ("a.00000000000000000.3")); // Too many zeros. + assert (bad_version ("1-a.00000000000000000")); // Same. + + assert (bad_version (0, "1", "", 1)); // Revision for empty release. + assert (bad_version (1, "+1-1.1", "", 2)); // Epoch in upstream. + assert (bad_version (1, "1.1-1", "", 2)); // Release in upstream. + assert (bad_version (1, "1.1+1", "", 2)); // Revision in upstream. + assert (bad_version (1, "1", "+1-1.1", 2)); // Epoch in release. + assert (bad_version (1, "1", "1.1-1", 2)); // Release in release. + assert (bad_version (1, "1", "1.1+1", 2)); // Revision in release. assert (bad_version (1, "", "", 0)); // Unexpected epoch. assert (bad_version (0, "", "1", 0)); // Unexpected release. @@ -145,108 +148,93 @@ namespace bpkg assert (v1 != v2); } - { - version v ("1~0.0-"); + version v ("+1-0.0-"); assert (!v.empty ()); - assert (v.string () == "1~0.0-"); + assert (v.string () == "+1-0.0-"); assert (v.canonical_upstream.empty ()); assert (v.canonical_release.empty ()); assert (test_constructor (v)); } - { version v ("a"); assert (v.string () == "a"); assert (v.canonical_upstream == "a"); assert (test_constructor (v)); } - { - version v ("65534~ab+65535"); - assert (v.string () == "65534~ab+65535"); + version v ("+65534-ab+65535"); + assert (v.string () == "+65534-ab+65535"); assert (v.canonical_upstream == "ab"); assert (test_constructor (v)); } - { version v ("1"); assert (v.string () == "1"); assert (v.canonical_upstream == "0000000000000001"); 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 == "0000000000000001"); assert (test_constructor (v)); } - { version v ("0.1.00"); assert (v.string () == "0.1.00"); assert (v.canonical_upstream == "0000000000000000.0000000000000001"); assert (test_constructor (v)); } - { version v ("0.0a.00"); assert (v.string () == "0.0a.00"); assert (v.canonical_upstream == "0000000000000000.0a"); assert (test_constructor (v)); } - { version v ("0.a00.00"); assert (v.string () == "0.a00.00"); assert (v.canonical_upstream == "0000000000000000.a00"); assert (test_constructor (v)); } - { - version v ("1~0"); - assert (v.string () == "1~0"); + version v ("+1-0"); + assert (v.string () == "+1-0"); assert (v.canonical_upstream.empty ()); assert (test_constructor (v)); } - { - version v ("0~A+1"); + 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"); + 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"); + version v ("+3-1A.31.0.4.0+7"); + assert (v.string () == "+3-1A.31.0.4.0+7"); assert (v.canonical_upstream == "1a.0000000000000031.0000000000000000.0000000000000004"); assert (test_constructor (v)); } - { version v ("1.2.3"); assert (v.string () == "1.2.3"); @@ -254,7 +242,6 @@ namespace bpkg assert (v.canonical_release == "~"); assert (test_constructor (v)); } - { version v ("1.2.3+1"); assert (v.string () == "1.2.3+1"); @@ -262,7 +249,6 @@ namespace bpkg assert (v.canonical_release == "~"); assert (test_constructor (v)); } - { version v ("1.2.3-"); assert (v.string () == "1.2.3-"); @@ -270,48 +256,43 @@ namespace bpkg assert (v.canonical_release.empty ()); assert (test_constructor (v)); } - { - version v ("1~A-1.2.3B.00+0"); - assert (v.string () == "1~A-1.2.3B.00"); + version v ("+1-A-1.2.3B.00+0"); + assert (v.string () == "+1-A-1.2.3B.00"); assert (v.release && *v.release == "1.2.3B.00"); assert (v.canonical_release == "0000000000000001.0000000000000002.3b"); assert (test_constructor (v)); } - { - version v ("65535~q.3+65535"); - assert (v.string () == "65535~q.3+65535"); + version v ("+65535-q.3+65535"); + assert (v.string () == "+65535-q.3+65535"); assert (!v.release); assert (v.canonical_release == "~"); assert (test_constructor (v)); } - { version v (1, "1", nullopt, 2, 0); - assert (v.string () == "1~1+2"); + assert (v.string () == "+1-1+2"); assert (!v.release); assert (v.canonical_release == "~"); assert (test_constructor (v)); } - { version v (1, "1", string (), 0, 0); - assert (v.string () == "1~1-"); + assert (v.string () == "+1-1-"); assert (v.release && v.release->empty ()); assert (v.canonical_release.empty ()); assert (test_constructor (v)); } - { version v (1, "2.0", nullopt, 3, 4); - assert (v.string (false, false) == "1~2.0+3#4"); - assert (v.string (true, true) == "1~2.0"); - assert (v.string (true, false) == "1~2.0"); - assert (v.string (false, true) == "1~2.0+3"); + assert (v.string (false, false) == "+1-2.0+3#4"); + assert (v.string (true, true) == "+1-2.0"); + assert (v.string (true, false) == "+1-2.0"); + assert (v.string (false, true) == "+1-2.0+3"); - assert (version (1, "2.0", nullopt, 0, 3).string () == "1~2.0#3"); - assert (version (1, "2.0", nullopt, 3, 0).string () == "1~2.0+3"); + assert (version (1, "2.0", nullopt, 0, 3).string () == "+1-2.0#3"); + assert (version (1, "2.0", nullopt, 3, 0).string () == "+1-2.0+3"); } assert (version ("a") == version ("a")); @@ -323,11 +304,11 @@ namespace bpkg assert (version ("ac") < version ("bc")); assert (version ("ab+0") == version ("ab")); assert (version ("a.1+1") > version ("a.1")); - assert (version ("0~ab") == version ("ab")); + assert (version ("+0-ab") == version ("ab")); assert (version ("1.2") > version ("1.1")); - assert (version ("1~1.0") > version ("2.0")); - assert (version ("0~ab+1") == version ("ab+1")); - assert (version ("0~ab+1").compare (version ("0~ab+2"), true) == 0); + assert (version ("+1-1.0") > version ("2.0")); + assert (version ("+0-ab+1") == version ("ab+1")); + assert (version ("+0-ab+1").compare (version ("+0-ab+2"), true) == 0); assert (version ("12") > version ("2")); assert (version ("2") < version ("12")); assert (version ("1") == version ("01")); @@ -354,8 +335,8 @@ namespace bpkg assert (version ("1.0-alpha") > version ("1.0-1")); assert (version ("1.0-alpha") == version ("1.0-alpha.0")); - assert (version (1, "2.0", nullopt, 3, 0) == version ("1~2+3")); - assert (version (1, "2.0", string (), 0, 0) == version ("1~2-")); + assert (version (1, "2.0", nullopt, 3, 0) == version ("+1-2+3")); + assert (version (1, "2.0", string (), 0, 0) == version ("+1-2-")); assert (version (0, "", string (), 0, 0) == version ()); assert (version (1, "2.0", nullopt, 3, 4).compare ( -- cgit v1.1