1 /* 2 This file is part of solidity. 3 4 solidity is free software: you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation, either version 3 of the License, or 7 (at your option) any later version. 8 9 solidity is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with solidity. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 // SPDX-License-Identifier: GPL-3.0 18 /** 19 * @author Christian <chris@ethereum.org> 20 * @date 2016 21 * Utilities to handle semantic versioning. 22 */ 23 24 #pragma once 25 26 #include <liblangutil/Token.h> 27 #include <libsolutil/Assertions.h> 28 29 #include <string> 30 #include <optional> 31 #include <utility> 32 #include <vector> 33 34 namespace solidity::langutil 35 { 36 37 class SemVerError: public util::Exception 38 { 39 }; 40 41 #undef major 42 #undef minor 43 44 struct SemVerVersion 45 { 46 unsigned numbers[3]; 47 std::string prerelease; 48 std::string build; 49 majorSemVerVersion50 unsigned major() const { return numbers[0]; } minorSemVerVersion51 unsigned minor() const { return numbers[1]; } patchSemVerVersion52 unsigned patch() const { return numbers[2]; } 53 isPrereleaseSemVerVersion54 bool isPrerelease() const { return !prerelease.empty(); } 55 56 explicit SemVerVersion(std::string const& _versionString = "0.0.0"); 57 }; 58 59 struct SemVerMatchExpression 60 { 61 bool matches(SemVerVersion const& _version) const; 62 isValidSemVerMatchExpression63 bool isValid() const { return !m_disjunction.empty(); } 64 65 struct MatchComponent 66 { 67 /// Prefix from < > <= >= ~ ^ 68 Token prefix = Token::Illegal; 69 /// Version, where unsigned(-1) in major, minor or patch denotes '*', 'x' or 'X' 70 SemVerVersion version; 71 /// Whether we have 1, 1.2 or 1.2.4 72 unsigned levelsPresent = 1; 73 bool matches(SemVerVersion const& _version) const; 74 }; 75 76 struct Conjunction 77 { 78 std::vector<MatchComponent> components; 79 bool matches(SemVerVersion const& _version) const; 80 }; 81 82 std::vector<Conjunction> m_disjunction; 83 }; 84 85 class SemVerMatchExpressionParser 86 { 87 public: 88 SemVerMatchExpressionParser(std::vector<Token> _tokens, std::vector<std::string> _literals); 89 90 /// Returns an expression if it was parseable, or nothing otherwise. 91 std::optional<SemVerMatchExpression> parse(); 92 93 private: 94 void reset(); 95 96 void parseMatchExpression(); 97 SemVerMatchExpression::MatchComponent parseMatchComponent(); 98 unsigned parseVersionPart(); 99 100 char currentChar() const; 101 char nextChar(); 102 Token currentToken() const; 103 void nextToken(); 104 105 std::vector<Token> m_tokens; 106 std::vector<std::string> m_literals; 107 108 unsigned m_pos = 0; 109 unsigned m_posInside = 0; 110 111 SemVerMatchExpression m_expression; 112 }; 113 114 } 115