#include "semver.h" u128 u128FromVersion(Version *self) { u128 out = 0; uint16_t pre = 0, mask = 03777; uint64_t major, minor, patch, build; int64_t ts; switch (self->vk_tag) { case Simple: out |= ((u128)self->vk_data.simple.major << (64 + 52)); break; case Rapid: major = (uint64_t)self->vk_data.rapid.major << 52; minor = (uint64_t)self->vk_data.rapid.minor << 40; out = (u128)(major | minor) << 64; break; case SemVer: major = (uint64_t)self->vk_data.semver.major << 52; minor = (uint64_t)self->vk_data.semver.minor << 40; patch = (uint64_t)self->vk_data.semver.patch << 28; out = (u128)(major | minor | patch) << 64; break; case Extended: major = (uint64_t)self->vk_data.extended.major << 52; minor = (uint64_t)self->vk_data.extended.minor << 40; patch = (uint64_t)self->vk_data.extended.patch << 28; build = (uint64_t)self->vk_data.extended.build << 16; out = (u128)(major | minor | patch | build) << 64; break; default: break; } switch (self->pr_tag) { case Alpha: out |= ((u128)010000 << 64); pre = self->pr_data.alpha & mask; out |= ((u128)pre << 64); break; case Beta: out |= ((u128)020000 << 64); pre = self->pr_data.beta & mask; out |= ((u128)pre << 64); break; case ReleaseCandidate: out |= ((u128)040000 << 64); pre = self->pr_data.rc & mask; out |= ((u128)pre << 64); break; case GitRev: out |= ((u128)01000 << 64); ts = dateTimeGetTimestamp(&self->pr_data.git->dt); out |= (u128)ts; break; case PRNone: out |= ((u128)0100000 << 64); break; default: break; } return out; } Comparison compareVersion(Version *self, Version *other) { u128 a, b; if (self->arch != other->arch) return CompNone; a = u128FromVersion(self); b = u128FromVersion(other); if (a < b) return CompLess; else if (a == b) return CompEqual; else if (a > b) return CompGreater; else return CompNone; }