mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2026-06-13 19:36:26 +03:00
fix bug when comparing dev releases
This commit is contained in:
@@ -19,6 +19,7 @@
|
|||||||
#include "firmwareVersion.h"
|
#include "firmwareVersion.h"
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
@@ -47,6 +48,66 @@ const std::string & FirmwareVersion::prerelease() const {
|
|||||||
return prerelease_;
|
return prerelease_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// semver prerelease ordering: a release (empty tag) ranks higher than any prerelease,
|
||||||
|
// and dot-separated numeric identifiers are compared numerically (so dev.9 < dev.12).
|
||||||
|
// returns <0, 0 or >0
|
||||||
|
static int compare_prerelease(const std::string & a, const std::string & b) {
|
||||||
|
if (a == b) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (a.empty()) {
|
||||||
|
return 1; // release > prerelease
|
||||||
|
}
|
||||||
|
if (b.empty()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ia = 0;
|
||||||
|
size_t ib = 0;
|
||||||
|
while (ia < a.size() && ib < b.size()) {
|
||||||
|
size_t ea = a.find('.', ia);
|
||||||
|
size_t eb = b.find('.', ib);
|
||||||
|
if (ea == std::string::npos) {
|
||||||
|
ea = a.size();
|
||||||
|
}
|
||||||
|
if (eb == std::string::npos) {
|
||||||
|
eb = b.size();
|
||||||
|
}
|
||||||
|
std::string id_a = a.substr(ia, ea - ia);
|
||||||
|
std::string id_b = b.substr(ib, eb - ib);
|
||||||
|
|
||||||
|
bool num_a = !id_a.empty() && id_a.find_first_not_of("0123456789") == std::string::npos;
|
||||||
|
bool num_b = !id_b.empty() && id_b.find_first_not_of("0123456789") == std::string::npos;
|
||||||
|
|
||||||
|
if (num_a && num_b) {
|
||||||
|
long va = atol(id_a.c_str());
|
||||||
|
long vb = atol(id_b.c_str());
|
||||||
|
if (va != vb) {
|
||||||
|
return (va < vb) ? -1 : 1;
|
||||||
|
}
|
||||||
|
} else if (num_a != num_b) {
|
||||||
|
return num_a ? -1 : 1; // numeric identifiers rank lower than alphanumeric ones
|
||||||
|
} else {
|
||||||
|
int cmp = id_a.compare(id_b);
|
||||||
|
if (cmp != 0) {
|
||||||
|
return (cmp < 0) ? -1 : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ia = ea + 1;
|
||||||
|
ib = eb + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// all shared identifiers are equal; the one with more identifiers ranks higher
|
||||||
|
if (ia < a.size()) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (ib < b.size()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool operator<(const FirmwareVersion & a, const FirmwareVersion & b) {
|
bool operator<(const FirmwareVersion & a, const FirmwareVersion & b) {
|
||||||
if (a.major_ != b.major_)
|
if (a.major_ != b.major_)
|
||||||
return a.major_ < b.major_;
|
return a.major_ < b.major_;
|
||||||
@@ -54,7 +115,7 @@ bool operator<(const FirmwareVersion & a, const FirmwareVersion & b) {
|
|||||||
return a.minor_ < b.minor_;
|
return a.minor_ < b.minor_;
|
||||||
if (a.patch_ != b.patch_)
|
if (a.patch_ != b.patch_)
|
||||||
return a.patch_ < b.patch_;
|
return a.patch_ < b.patch_;
|
||||||
return a.prerelease_ < b.prerelease_;
|
return compare_prerelease(a.prerelease_, b.prerelease_) < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator>(const FirmwareVersion & a, const FirmwareVersion & b) {
|
bool operator>(const FirmwareVersion & a, const FirmwareVersion & b) {
|
||||||
@@ -62,7 +123,7 @@ bool operator>(const FirmwareVersion & a, const FirmwareVersion & b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const FirmwareVersion & a, const FirmwareVersion & b) {
|
bool operator==(const FirmwareVersion & a, const FirmwareVersion & b) {
|
||||||
return a.major_ == b.major_ && a.minor_ == b.minor_ && a.patch_ == b.patch_ && a.prerelease_ == b.prerelease_;
|
return a.major_ == b.major_ && a.minor_ == b.minor_ && a.patch_ == b.patch_ && compare_prerelease(a.prerelease_, b.prerelease_) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const FirmwareVersion & a, const FirmwareVersion & b) {
|
bool operator!=(const FirmwareVersion & a, const FirmwareVersion & b) {
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ class FirmwareVersion {
|
|||||||
int patch() const;
|
int patch() const;
|
||||||
const std::string & prerelease() const;
|
const std::string & prerelease() const;
|
||||||
|
|
||||||
// Numeric-only comparison (major.minor.patch). Prerelease tags are ignored on purpose.
|
|
||||||
friend bool operator<(const FirmwareVersion & a, const FirmwareVersion & b);
|
friend bool operator<(const FirmwareVersion & a, const FirmwareVersion & b);
|
||||||
friend bool operator>(const FirmwareVersion & a, const FirmwareVersion & b);
|
friend bool operator>(const FirmwareVersion & a, const FirmwareVersion & b);
|
||||||
friend bool operator==(const FirmwareVersion & a, const FirmwareVersion & b);
|
friend bool operator==(const FirmwareVersion & a, const FirmwareVersion & b);
|
||||||
|
|||||||
Reference in New Issue
Block a user