|
| 1 | +// Copyright (c) Microsoft Corporation. All rights reserved. |
| 2 | +// Licensed under the MIT License. |
| 3 | + |
| 4 | +#include "core/common/semver.h" |
| 5 | + |
| 6 | +#include <regex> |
| 7 | + |
| 8 | +#include "core/common/common.h" |
| 9 | +#include "core/common/narrow.h" |
| 10 | +#include "core/common/parse_string.h" |
| 11 | + |
| 12 | +namespace onnxruntime { |
| 13 | + |
| 14 | +Status ParseSemVerVersion(std::string_view version_string, SemVerVersion* semver_version_out) { |
| 15 | + // Semantic Versioning version regex was copied from here: |
| 16 | + // https://github.com/semver/semver/blob/d58db1686379c8c6d52e32d42d3a530a964264e5/semver.md?plain=1#L357 |
| 17 | + static const std::regex semver_pattern{ |
| 18 | + R"(^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$)"}; |
| 19 | + |
| 20 | + std::cmatch match_result{}; |
| 21 | + ORT_RETURN_IF_NOT(std::regex_match(version_string.data(), version_string.data() + version_string.size(), |
| 22 | + match_result, semver_pattern), |
| 23 | + "Version string is not in semantic versioning format: '", version_string, "'"); |
| 24 | + |
| 25 | + auto sub_match_to_string_view = [](const std::csub_match& sub_match) -> std::optional<std::string_view> { |
| 26 | + if (!sub_match.matched) { |
| 27 | + return std::nullopt; |
| 28 | + } |
| 29 | + return std::string_view{sub_match.first, narrow<size_t>(sub_match.length())}; |
| 30 | + }; |
| 31 | + |
| 32 | + auto parse_version_component = |
| 33 | + [&sub_match_to_string_view](const std::csub_match& sub_match, uint32_t& component) -> Status { |
| 34 | + const auto component_str = sub_match_to_string_view(sub_match); |
| 35 | + ORT_RETURN_IF_NOT(component_str.has_value(), "sub_match does not match anything."); |
| 36 | + return ParseStringWithClassicLocale(*component_str, component); |
| 37 | + }; |
| 38 | + |
| 39 | + SemVerVersion semver_version{}; |
| 40 | + |
| 41 | + ORT_RETURN_IF_ERROR(parse_version_component(match_result[1], semver_version.major)); |
| 42 | + ORT_RETURN_IF_ERROR(parse_version_component(match_result[2], semver_version.minor)); |
| 43 | + ORT_RETURN_IF_ERROR(parse_version_component(match_result[3], semver_version.patch)); |
| 44 | + |
| 45 | + semver_version.prerelease = sub_match_to_string_view(match_result[4]); |
| 46 | + semver_version.build_metadata = sub_match_to_string_view(match_result[5]); |
| 47 | + |
| 48 | + if (semver_version_out) { |
| 49 | + *semver_version_out = std::move(semver_version); |
| 50 | + } |
| 51 | + return Status::OK(); |
| 52 | +} |
| 53 | + |
| 54 | +SemVerVersion ParseSemVerVersion(std::string_view version_string) { |
| 55 | + SemVerVersion result{}; |
| 56 | + ORT_THROW_IF_ERROR(ParseSemVerVersion(version_string, &result)); |
| 57 | + return result; |
| 58 | +} |
| 59 | + |
| 60 | +} // namespace onnxruntime |
0 commit comments