/* * EMS-ESP - https://github.com/emsesp/EMS-ESP * Copyright 2020-2026 emsesp.org * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef EMSESP_Version_H #define EMSESP_Version_H #include #include #include // Drop-in lightweight replacement for the subset of the semver library actually used by EMS-ESP. // The previous semver library (lib/semver) builds a std::map + std::function-based state machine on // every parse, which fragments the internal heap on the ESP32. This replacement does no heap // allocation beyond the std::string member for the prerelease tag, and matches the API surface // we consume: construction from string, major()/minor()/patch()/prerelease(), and operator>/(const EMSESP_Version & a, const EMSESP_Version & b) { return b < a; } friend bool operator==(const EMSESP_Version & a, const EMSESP_Version & b) { return a.major_ == b.major_ && a.minor_ == b.minor_ && a.patch_ == b.patch_ && a.prerelease_ == b.prerelease_; } friend bool operator!=(const EMSESP_Version & a, const EMSESP_Version & b) { return !(a == b); } friend bool operator>=(const EMSESP_Version & a, const EMSESP_Version & b) { return !(a < b); } friend bool operator<=(const EMSESP_Version & a, const EMSESP_Version & b) { return !(b < a); } private: int major_ = 0; int minor_ = 0; int patch_ = 0; std::string prerelease_; void parse(const char * s) { major_ = minor_ = patch_ = 0; prerelease_.clear(); if (s == nullptr || *s == '\0') { return; } // parse numeric major.minor.patch; accept partial ("3", "3.9", "3.9.0") sscanf(s, "%d.%d.%d", &major_, &minor_, &patch_); // capture prerelease tag after '-' if present (stop at '+' which is build metadata) const char * dash = strchr(s, '-'); if (dash != nullptr) { const char * plus = strchr(dash, '+'); if (plus != nullptr) { prerelease_.assign(dash + 1, plus - dash - 1); } else { prerelease_.assign(dash + 1); } } } }; } // namespace version #endif