mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-20 11:05:54 +00:00
Add SemanticVersion
This commit is contained in:
@@ -121,6 +121,7 @@
|
||||
<ClInclude Include="..\..\modules\beast_core\diagnostic\beast_FPUFlags.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\diagnostic\beast_LeakChecked.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\diagnostic\beast_SafeBool.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\diagnostic\beast_SemanticVersion.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\diagnostic\beast_Throw.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\diagnostic\beast_UnitTest.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\diagnostic\beast_UnitTestUtilities.h" />
|
||||
@@ -425,6 +426,12 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_core\diagnostic\beast_SemanticVersion.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_core\diagnostic\beast_UnitTest.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
|
||||
@@ -734,6 +734,9 @@
|
||||
<ClInclude Include="..\..\modules\beast_core\diagnostic\beast_FatalError.h">
|
||||
<Filter>beast_core\diagnostic</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_core\diagnostic\beast_SemanticVersion.h">
|
||||
<Filter>beast_core\diagnostic</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\modules\beast_core\beast_core.cpp">
|
||||
@@ -1147,6 +1150,9 @@
|
||||
<ClCompile Include="..\..\modules\beast_core\diagnostic\beast_FatalError.cpp">
|
||||
<Filter>beast_core\diagnostic</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_core\diagnostic\beast_SemanticVersion.cpp">
|
||||
<Filter>beast_core\diagnostic</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="..\..\TODO.txt" />
|
||||
|
||||
@@ -150,6 +150,7 @@ namespace beast
|
||||
#include "diagnostic/beast_FPUFlags.cpp"
|
||||
#include "diagnostic/beast_LeakChecked.cpp"
|
||||
#include "diagnostic/beast_ProtectedCall.cpp"
|
||||
#include "diagnostic/beast_SemanticVersion.cpp"
|
||||
#include "diagnostic/beast_UnitTest.cpp"
|
||||
#include "diagnostic/beast_UnitTestUtilities.cpp"
|
||||
|
||||
|
||||
@@ -307,6 +307,7 @@ namespace beast
|
||||
#include "text/beast_LocalisedStrings.h"
|
||||
#include "text/beast_NewLine.h"
|
||||
#include "text/beast_StringArray.h"
|
||||
#include "diagnostic/beast_SemanticVersion.h"
|
||||
#include "text/beast_StringPairArray.h"
|
||||
#include "text/beast_StringPool.h"
|
||||
#include "text/beast_TextDiff.h"
|
||||
|
||||
@@ -0,0 +1,519 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
SemanticVersion::SemanticVersion ()
|
||||
: majorVersion (0)
|
||||
, minorVersion (0)
|
||||
, patchVersion (0)
|
||||
{
|
||||
}
|
||||
|
||||
bool SemanticVersion::parse (String input)
|
||||
{
|
||||
// May not have leading or trailing whitespace
|
||||
if (input.trim () != input)
|
||||
return false;
|
||||
|
||||
// Must have major version number
|
||||
if (! chopUInt (&majorVersion, std::numeric_limits <int>::max (), input))
|
||||
return false;
|
||||
|
||||
if (! chop (".", input))
|
||||
return false;
|
||||
|
||||
// Must have minor version number
|
||||
if (! chopUInt (&minorVersion, std::numeric_limits <int>::max (), input))
|
||||
return false;
|
||||
|
||||
if (! chop (".", input))
|
||||
return false;
|
||||
|
||||
// Must have patch version number
|
||||
if (! chopUInt (&patchVersion, std::numeric_limits <int>::max (), input))
|
||||
return false;
|
||||
|
||||
// May have pre-release identifier list
|
||||
if (chop ("-", input))
|
||||
{
|
||||
chopIdentifiers (&preReleaseIdentifiers, false, input);
|
||||
|
||||
// Must not be empty
|
||||
if (preReleaseIdentifiers.size () <= 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
// May have metadata identifier list
|
||||
if (chop ("+", input))
|
||||
{
|
||||
chopIdentifiers (&metaData, true, input);
|
||||
|
||||
// Must not be empty
|
||||
if (metaData.size () <= 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
// May not have anything left
|
||||
if (input.length () > 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
String SemanticVersion::print () const
|
||||
{
|
||||
String s;
|
||||
|
||||
s << String (majorVersion) << "." << String (minorVersion) << "." << String (patchVersion);
|
||||
|
||||
if (preReleaseIdentifiers.size () > 0)
|
||||
s << "-" << printIdentifiers (preReleaseIdentifiers);
|
||||
|
||||
if (metaData.size () > 0)
|
||||
s << "+" << printIdentifiers (metaData);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int SemanticVersion::compare (SemanticVersion const& rhs) const noexcept
|
||||
{
|
||||
if (majorVersion > rhs.majorVersion)
|
||||
return 1;
|
||||
else if (majorVersion < rhs.majorVersion)
|
||||
return -1;
|
||||
|
||||
if (minorVersion > rhs.minorVersion)
|
||||
return 1;
|
||||
else if (minorVersion < rhs.minorVersion)
|
||||
return -1;
|
||||
|
||||
if (patchVersion > rhs.patchVersion)
|
||||
return 1;
|
||||
else if (patchVersion < rhs.patchVersion)
|
||||
return -1;
|
||||
|
||||
if (isPreRelease () || rhs.isPreRelease ())
|
||||
{
|
||||
// Pre-releases have a lower precedence
|
||||
if (isRelease () && rhs.isPreRelease ())
|
||||
return 1;
|
||||
else if (isPreRelease () && rhs.isRelease ())
|
||||
return -1;
|
||||
|
||||
// Compare pre-release identifiers
|
||||
for (int i = 0; i < bmax (preReleaseIdentifiers.size (), rhs.preReleaseIdentifiers.size ()); ++i)
|
||||
{
|
||||
// A larger list of identifiers has a higher precedence
|
||||
if (i >= rhs.preReleaseIdentifiers.size ())
|
||||
return 1;
|
||||
else if (i >= preReleaseIdentifiers.size ())
|
||||
return -1;
|
||||
|
||||
String const& left (preReleaseIdentifiers [i]);
|
||||
String const& right (rhs.preReleaseIdentifiers [i]);
|
||||
|
||||
// Numeric identifiers have lower precedence
|
||||
if (! isNumeric (left) && isNumeric (right))
|
||||
return 1;
|
||||
else if (isNumeric (left) && ! isNumeric (right))
|
||||
return -1;
|
||||
|
||||
if (isNumeric (left))
|
||||
{
|
||||
bassert (isNumeric (right));
|
||||
|
||||
int const iLeft (left.getIntValue ());
|
||||
int const iRight (right.getIntValue ());
|
||||
|
||||
if (iLeft > iRight)
|
||||
return 1;
|
||||
else if (iLeft < iRight)
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
bassert (! isNumeric (right));
|
||||
|
||||
int result = left.compareLexicographically (right);
|
||||
|
||||
if (result != 0)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// metadata is ignored
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool SemanticVersion::isNumeric (String const& s)
|
||||
{
|
||||
return String (s.getIntValue ()) == s;
|
||||
}
|
||||
|
||||
bool SemanticVersion::chop (String const& what, String& input)
|
||||
{
|
||||
if (input.startsWith (what))
|
||||
{
|
||||
input = input.substring (what.length ());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
String SemanticVersion::printIdentifiers (StringArray const& list)
|
||||
{
|
||||
String s;
|
||||
|
||||
if (list.size () > 0)
|
||||
{
|
||||
s << list [0];
|
||||
|
||||
for (int i = 1; i < list.size (); ++i)
|
||||
s << "." << list [i];
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
bool SemanticVersion::chopUInt (int* value, int limit, String& input)
|
||||
{
|
||||
// Must not be empty
|
||||
if (input.length () <= 0)
|
||||
return false;
|
||||
|
||||
int firstNonDigit = 0;
|
||||
for (; firstNonDigit < input.length (); ++firstNonDigit)
|
||||
{
|
||||
if (! CharacterFunctions::isDigit (input [firstNonDigit]))
|
||||
break;
|
||||
}
|
||||
|
||||
String const s = input.substring (0, firstNonDigit);
|
||||
|
||||
// Must not be empty
|
||||
if (s.length () <= 0)
|
||||
return false;
|
||||
|
||||
int const n = s.getIntValue ();
|
||||
|
||||
// Must not have leading zeroes
|
||||
if (String (n) != s)
|
||||
return false;
|
||||
|
||||
// Must not be out of range
|
||||
if (n < 0 || n > limit)
|
||||
return false;
|
||||
|
||||
input = input.substring (s.length ());
|
||||
|
||||
*value = n;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SemanticVersion::chopIdentifier (String* value, bool allowLeadingZeroes, String& input)
|
||||
{
|
||||
// Must not be empty
|
||||
if (input.length () <= 0)
|
||||
return false;
|
||||
|
||||
// Must not have a leading 0
|
||||
if (! allowLeadingZeroes && input [0] == '0')
|
||||
return false;
|
||||
|
||||
// Find the first character that cannot be part of an identifier
|
||||
int i;
|
||||
for (i = 0; i < input.length (); ++i)
|
||||
{
|
||||
static char const* validSet =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-";
|
||||
|
||||
if (! String (validSet).contains (String::charToString (input [i])))
|
||||
break;
|
||||
}
|
||||
|
||||
// Must not be empty
|
||||
if (i <= 0)
|
||||
return false;
|
||||
|
||||
*value = input.substring (0, i);
|
||||
|
||||
input = input.substring (i);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SemanticVersion::chopIdentifiers (StringArray* value, bool allowLeadingZeroes, String& input)
|
||||
{
|
||||
if (input.length () <= 0)
|
||||
return false;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
String s;
|
||||
|
||||
if (! chopIdentifier (&s, allowLeadingZeroes, input))
|
||||
return false;
|
||||
|
||||
value->add (s);
|
||||
|
||||
if (! chop (".", input))
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class SemanticVersionTests : public UnitTest
|
||||
{
|
||||
public:
|
||||
SemanticVersionTests () : UnitTest ("SemanticVersion", "beast")
|
||||
{
|
||||
}
|
||||
|
||||
void checkPass (String const& input, bool shouldPass = true)
|
||||
{
|
||||
SemanticVersion v;
|
||||
|
||||
if (shouldPass )
|
||||
{
|
||||
expect (v.parse (input));
|
||||
expect (v.print () == input);
|
||||
}
|
||||
else
|
||||
{
|
||||
expect (! v.parse (input));
|
||||
}
|
||||
}
|
||||
|
||||
void checkFail (String const& input)
|
||||
{
|
||||
checkPass (input, false);
|
||||
}
|
||||
|
||||
// check input and input with appended metadata
|
||||
void checkMeta (String const& input, bool shouldPass)
|
||||
{
|
||||
checkPass (input, shouldPass);
|
||||
|
||||
checkPass (input + "+a", shouldPass);
|
||||
checkPass (input + "+1", shouldPass);
|
||||
checkPass (input + "+a.b", shouldPass);
|
||||
checkPass (input + "+ab.cd", shouldPass);
|
||||
|
||||
checkFail (input + "!");
|
||||
checkFail (input + "+");
|
||||
checkFail (input + "++");
|
||||
checkFail (input + "+!");
|
||||
checkFail (input + "+.");
|
||||
checkFail (input + "+a.!");
|
||||
}
|
||||
|
||||
void checkMetaFail (String const& input)
|
||||
{
|
||||
checkMeta (input, false);
|
||||
}
|
||||
|
||||
// check input, input with appended release data,
|
||||
// input with appended metadata, and input with both
|
||||
// appended release data and appended metadata
|
||||
//
|
||||
void checkRelease (String const& input, bool shouldPass = true)
|
||||
{
|
||||
checkMeta (input, shouldPass);
|
||||
|
||||
checkMeta (input + "-1", shouldPass);
|
||||
checkMeta (input + "-a", shouldPass);
|
||||
checkMeta (input + "-a1", shouldPass);
|
||||
checkMeta (input + "-a1.b1", shouldPass);
|
||||
checkMeta (input + "-ab.cd", shouldPass);
|
||||
checkMeta (input + "--", shouldPass);
|
||||
|
||||
checkMetaFail (input + "+");
|
||||
checkMetaFail (input + "!");
|
||||
checkMetaFail (input + "-");
|
||||
checkMetaFail (input + "-!");
|
||||
checkMetaFail (input + "-.");
|
||||
checkMetaFail (input + "-a.!");
|
||||
checkMetaFail (input + "-0.a");
|
||||
}
|
||||
|
||||
// Checks the major.minor.version string alone and with all
|
||||
// possible combinations of release identifiers and metadata.
|
||||
//
|
||||
void check (String const& input, bool shouldPass = true)
|
||||
{
|
||||
checkRelease (input, shouldPass);
|
||||
}
|
||||
|
||||
void ncheck (String const& input)
|
||||
{
|
||||
check (input, false);
|
||||
}
|
||||
|
||||
void testParse ()
|
||||
{
|
||||
beginTestCase ("parse");
|
||||
|
||||
check ("0.0.0");
|
||||
check ("1.2.3");
|
||||
check ("2147483647.2147483647.2147483647"); // max int
|
||||
|
||||
// negative values
|
||||
ncheck ("-1.2.3");
|
||||
ncheck ("1.-2.3");
|
||||
ncheck ("1.2.-3");
|
||||
|
||||
// missing parts
|
||||
ncheck ("");
|
||||
ncheck ("1");
|
||||
ncheck ("1.");
|
||||
ncheck ("1.2");
|
||||
ncheck ("1.2.");
|
||||
ncheck (".2.3");
|
||||
|
||||
// whitespace
|
||||
ncheck (" 1.2.3");
|
||||
ncheck ("1 .2.3");
|
||||
ncheck ("1.2 .3");
|
||||
ncheck ("1.2.3 ");
|
||||
|
||||
// leading zeroes
|
||||
ncheck ("01.2.3");
|
||||
ncheck ("1.02.3");
|
||||
ncheck ("1.2.03");
|
||||
}
|
||||
|
||||
static StringArray ids ()
|
||||
{
|
||||
return StringArray ();
|
||||
}
|
||||
|
||||
static StringArray ids (String const& s1)
|
||||
{
|
||||
StringArray v;
|
||||
v.add (s1);
|
||||
return v;
|
||||
}
|
||||
|
||||
static StringArray ids (String const& s1, String const& s2)
|
||||
{
|
||||
StringArray v;
|
||||
v.add (s1);
|
||||
v.add (s2);
|
||||
return v;
|
||||
}
|
||||
|
||||
static StringArray ids (String const& s1, String const& s2, String const& s3)
|
||||
{
|
||||
StringArray v;
|
||||
v.add (s1);
|
||||
v.add (s2);
|
||||
v.add (s3);
|
||||
return v;
|
||||
}
|
||||
|
||||
// Checks the decomposition of the input into appropriate values
|
||||
void checkValues (String const& input,
|
||||
int majorVersion,
|
||||
int minorVersion,
|
||||
int patchVersion,
|
||||
StringArray const& preReleaseIdentifiers = StringArray (),
|
||||
StringArray const& metaData = StringArray ())
|
||||
{
|
||||
SemanticVersion v;
|
||||
|
||||
expect (v.parse (input));
|
||||
|
||||
expect (v.majorVersion == majorVersion);
|
||||
expect (v.minorVersion == minorVersion);
|
||||
expect (v.patchVersion == patchVersion);
|
||||
|
||||
expect (v.preReleaseIdentifiers == preReleaseIdentifiers);
|
||||
expect (v.metaData == metaData);
|
||||
}
|
||||
|
||||
void testValues ()
|
||||
{
|
||||
checkValues ("0.1.2", 0, 1, 2);
|
||||
checkValues ("1.2.3", 1, 2, 3);
|
||||
checkValues ("1.2.3-rc1", 1, 2, 3, ids ("rc1"));
|
||||
checkValues ("1.2.3-rc1.debug", 1, 2, 3, ids ("rc1", "debug"));
|
||||
checkValues ("1.2.3-rc1.debug.asm", 1, 2, 3, ids ("rc1", "debug", "asm"));
|
||||
checkValues ("1.2.3+full", 1, 2, 3, ids (), ids ("full"));
|
||||
checkValues ("1.2.3+full.prod", 1, 2, 3, ids (), ids ("full", "prod"));
|
||||
checkValues ("1.2.3+full.prod.x86", 1, 2, 3, ids (), ids ("full", "prod", "x86"));
|
||||
checkValues ("1.2.3-rc1.debug.asm+full.prod.x86", 1, 2, 3,
|
||||
ids ("rc1", "debug", "asm"), ids ("full", "prod", "x86"));
|
||||
}
|
||||
|
||||
// makes sure the left version is less than the right
|
||||
void checkLessInternal (String const& lhs, String const& rhs)
|
||||
{
|
||||
SemanticVersion left;
|
||||
SemanticVersion right;
|
||||
|
||||
expect (left.parse (lhs));
|
||||
expect (right.parse (rhs));
|
||||
|
||||
expect (left.compare (left) == 0);
|
||||
expect (right.compare (right) == 0);
|
||||
expect (left.compare (right) < 0);
|
||||
expect (right.compare (left) > 0);
|
||||
|
||||
expect (left < right);
|
||||
expect (right > left);
|
||||
expect (left == left);
|
||||
expect (right == right);
|
||||
}
|
||||
|
||||
void checkLess (String const& lhs, String const& rhs)
|
||||
{
|
||||
checkLessInternal (lhs, rhs);
|
||||
checkLessInternal (lhs + "+meta", rhs);
|
||||
checkLessInternal (lhs, rhs + "+meta");
|
||||
checkLessInternal (lhs + "+meta", rhs + "+meta");
|
||||
}
|
||||
|
||||
void testCompare ()
|
||||
{
|
||||
checkLess ("1.0.0-alpha", "1.0.0-alpha.1");
|
||||
checkLess ("1.0.0-alpha.1", "1.0.0-alpha.beta");
|
||||
checkLess ("1.0.0-alpha.beta", "1.0.0-beta");
|
||||
checkLess ("1.0.0-beta", "1.0.0-beta.2");
|
||||
checkLess ("1.0.0-beta.2", "1.0.0-beta.11");
|
||||
checkLess ("1.0.0-beta.11", "1.0.0-rc.1");
|
||||
checkLess ("1.0.0-rc.1", "1.0.0");
|
||||
checkLess ("0.9.9", "1.0.0");
|
||||
}
|
||||
|
||||
void runTest ()
|
||||
{
|
||||
testParse ();
|
||||
testValues ();
|
||||
testCompare ();
|
||||
}
|
||||
};
|
||||
|
||||
static SemanticVersionTests semanticVersionTests;
|
||||
@@ -0,0 +1,74 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_SEMANTICVERSION_H_INCLUDED
|
||||
#define BEAST_SEMANTICVERSION_H_INCLUDED
|
||||
|
||||
/** A Semantic Version number.
|
||||
|
||||
Identifies the build of a particular version of software using
|
||||
the Semantic Versioning Specification described here:
|
||||
|
||||
http://semver.org/
|
||||
*/
|
||||
class BEAST_API SemanticVersion
|
||||
{
|
||||
public:
|
||||
int majorVersion;
|
||||
int minorVersion;
|
||||
int patchVersion;
|
||||
StringArray preReleaseIdentifiers;
|
||||
StringArray metaData;
|
||||
|
||||
SemanticVersion ();
|
||||
|
||||
/** Parse a semantic version string.
|
||||
The parsing is as strict as possible.
|
||||
@return `true` if the string was parsed.
|
||||
*/
|
||||
bool parse (String input);
|
||||
|
||||
/** Produce a string from semantic version components. */
|
||||
String print () const;
|
||||
|
||||
inline bool isRelease () const noexcept { return preReleaseIdentifiers.size () <= 0; }
|
||||
inline bool isPreRelease () const noexcept { return ! isRelease (); }
|
||||
|
||||
/** Compare this against another version.
|
||||
The comparison follows the rules as per the specification.
|
||||
*/
|
||||
int compare (SemanticVersion const& rhs) const noexcept;
|
||||
|
||||
inline bool operator== (SemanticVersion const& other) const noexcept { return compare (other) == 0; }
|
||||
inline bool operator!= (SemanticVersion const& other) const noexcept { return compare (other) != 0; }
|
||||
inline bool operator>= (SemanticVersion const& other) const noexcept { return compare (other) >= 0; }
|
||||
inline bool operator<= (SemanticVersion const& other) const noexcept { return compare (other) <= 0; }
|
||||
inline bool operator> (SemanticVersion const& other) const noexcept { return compare (other) > 0; }
|
||||
inline bool operator< (SemanticVersion const& other) const noexcept { return compare (other) < 0; }
|
||||
|
||||
private:
|
||||
static bool isNumeric (String const& s);
|
||||
static String printIdentifiers (StringArray const& list);
|
||||
static bool chop (String const& what, String& input);
|
||||
static bool chopUInt (int* value, int limit, String& input);
|
||||
static bool chopIdentifier (String* value, bool allowLeadingZeroes, String& input);
|
||||
static bool chopIdentifiers (StringArray* value, bool preRelease, String& input);
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user