| 64 | } |
| 65 | |
| 66 | static bool validate_version_string(std::string_view str, bool& has_label) { |
| 67 | std::array<size_t, 2> period_indices; |
| 68 | size_t num_periods = 0; |
| 69 | size_t cur_pos = 0; |
| 70 | uint16_t major; |
| 71 | uint16_t minor; |
| 72 | uint16_t patch; |
| 73 | |
| 74 | // Find the 2 required periods. |
| 75 | cur_pos = str.find('.', cur_pos); |
| 76 | period_indices[0] = cur_pos; |
| 77 | cur_pos = str.find('.', cur_pos + 1); |
| 78 | period_indices[1] = cur_pos; |
| 79 | |
| 80 | // Check that both were found. |
| 81 | if (period_indices[0] == std::string::npos || period_indices[1] == std::string::npos) { |
| 82 | return false; |
| 83 | } |
| 84 | |
| 85 | // Parse the 3 numbers formed by splitting the string via the periods. |
| 86 | std::array<std::from_chars_result, 3> parse_results; |
| 87 | std::array<size_t, 3> parse_starts { 0, period_indices[0] + 1, period_indices[1] + 1 }; |
| 88 | std::array<size_t, 3> parse_ends { period_indices[0], period_indices[1], str.size() }; |
| 89 | parse_results[0] = std::from_chars(str.data() + parse_starts[0], str.data() + parse_ends[0], major); |
| 90 | parse_results[1] = std::from_chars(str.data() + parse_starts[1], str.data() + parse_ends[1], minor); |
| 91 | parse_results[2] = std::from_chars(str.data() + parse_starts[2], str.data() + parse_ends[2], patch); |
| 92 | |
| 93 | // Check that the first two parsed correctly. |
| 94 | auto did_parse = [&](size_t i) { |
| 95 | return parse_results[i].ec == std::errc{} && parse_results[i].ptr == str.data() + parse_ends[i]; |
| 96 | }; |
| 97 | |
| 98 | if (!did_parse(0) || !did_parse(1)) { |
| 99 | return false; |
| 100 | } |
| 101 | |
| 102 | // Check that the third had a successful parse, but not necessarily read all the characters. |
| 103 | if (parse_results[2].ec != std::errc{}) { |
| 104 | return false; |
| 105 | } |
| 106 | |
| 107 | // Allow a plus or minus directly after the third number. |
| 108 | if (parse_results[2].ptr != str.data() + parse_ends[2]) { |
| 109 | has_label = true; |
| 110 | if (*parse_results[2].ptr != '+' && *parse_results[2].ptr != '-') { |
| 111 | // Failed to parse, as nothing is allowed directly after the last number besides a plus or minus. |
| 112 | return false; |
| 113 | } |
| 114 | } |
| 115 | else { |
| 116 | has_label = false; |
| 117 | } |
| 118 | |
| 119 | return true; |
| 120 | } |
| 121 | |
| 122 | static bool validate_dependency_string(const std::string& val, size_t& name_length, bool& has_label) { |
| 123 | std::string ret; |
no outgoing calls
no test coverage detected