FlightGear next
AddonVersion.hxx
Go to the documentation of this file.
1// -*- coding: utf-8 -*-
2//
3// AddonVersion.hxx --- Version class for FlightGear add-ons
4// Copyright (C) 2017 Florent Rougon
5//
6// This program is free software; you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation; either version 2 of the License, or
9// (at your option) any later version.
10//
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15//
16// You should have received a copy of the GNU General Public License along
17// with this program; if not, write to the Free Software Foundation, Inc.,
18// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20#ifndef FG_ADDONVERSION_HXX
21#define FG_ADDONVERSION_HXX
22
23#include <ostream>
24#include <string>
25#include <tuple>
26#include <type_traits>
27
28#include <simgear/nasal/cppbind/NasalCallContext.hxx>
29#include <simgear/nasal/cppbind/NasalHash.hxx>
30#include <simgear/structure/SGReferenced.hxx>
31
32#include "addon_fwd.hxx"
33
34namespace flightgear
35{
36
37namespace addons
38{
39
40// Order matters for the sorting/comparison functions
47
48// ***************************************************************************
49// * AddonVersionSuffix *
50// ***************************************************************************
51
53{
54public:
57 int preReleaseNum = 0, bool developmental = false,
58 int devNum = 0);
59 // Construct from a string. The empty string is a valid input.
60 AddonVersionSuffix(const std::string& suffix);
61 AddonVersionSuffix(const char* suffix);
62 // Construct from a tuple
63 explicit AddonVersionSuffix(
64 const std::tuple<AddonVersionSuffixPrereleaseType, int, bool, int>& t);
65
66 // Return all components of an AddonVersionSuffix instance as a tuple.
67 // Beware, this is not suitable for sorting! cf. genSortKey() below.
68 std::tuple<AddonVersionSuffixPrereleaseType, int, bool, int> makeTuple() const;
69
70 // String representation of an AddonVersionSuffix
71 std::string str() const;
72
73private:
74 // String representation of the release type component: "a", "b", "rc" or "".
75 static std::string releaseTypeStr(AddonVersionSuffixPrereleaseType);
76
77 // If 's' starts with a non-empty release type ('a', 'b' or 'rc'), return
78 // the corresponding enum value along with the remainder of 's' (that is,
79 // everything after the release type). Otherwise, return
80 // AddonVersionSuffixPrereleaseType::none along with a copy of 's'.
81 static std::tuple<AddonVersionSuffixPrereleaseType, std::string>
82 popPrereleaseTypeFromBeginning(const std::string& s);
83
84 // Extract all components from a string representing a version suffix.
85 // The components of the return value are, in this order:
86 //
87 // preReleaseType, preReleaseNum, developmental, devNum
88 //
89 // Note: the empty string is a valid input.
90 static std::tuple<AddonVersionSuffixPrereleaseType, int, bool, int>
91 suffixStringToTuple(const std::string& suffix);
92
93 // Used to implement suffixStringToTuple() for compilers that are not
94 // C++11-compliant (gcc 4.8 pretends to support <regex> as required by C++11
95 // but doesn't, see <https://stackoverflow.com/a/12665408/4756009>).
96 //
97 // The bool in the first component of the result is true iff 'suffix' is a
98 // valid version suffix string. The bool is false when 'suffix' is invalid
99 // in such a way that the generic sg_format_exception thrown at the end of
100 // suffixStringToTuple() is appropriate. In all other cases, a specific
101 // exception is thrown.
102 static std::tuple<bool, AddonVersionSuffixPrereleaseType, int, bool, int>
103 parseVersionSuffixString_noRegexp(const std::string& suffix);
104
105 // Useful for comparisons/sorting purposes
106 std::tuple<int,
107 std::underlying_type<AddonVersionSuffixPrereleaseType>::type,
108 int, int, int> genSortKey() const;
109
110 friend bool operator==(const AddonVersionSuffix& lhs,
111 const AddonVersionSuffix& rhs);
112 friend bool operator<(const AddonVersionSuffix& lhs,
113 const AddonVersionSuffix& rhs);
114
115 AddonVersionSuffixPrereleaseType _preReleaseType;
116 int _preReleaseNum; // integer >= 1 (0 when not applicable)
117 bool _developmental; // whether the suffix ends with '.devN'
118 int _devNum; // integer >= 1 (0 when not applicable)
119};
120
121
122// operator==() and operator<() are declared above.
123bool operator!=(const AddonVersionSuffix& lhs, const AddonVersionSuffix& rhs);
124bool operator> (const AddonVersionSuffix& lhs, const AddonVersionSuffix& rhs);
125bool operator<=(const AddonVersionSuffix& lhs, const AddonVersionSuffix& rhs);
126bool operator>=(const AddonVersionSuffix& lhs, const AddonVersionSuffix& rhs);
127
128std::ostream& operator<<(std::ostream&, const AddonVersionSuffix&);
129
130// ***************************************************************************
131// * AddonVersion *
132// ***************************************************************************
133
134// I suggest to use either the year-based FlightGear-type versioning, or
135// semantic versioning (<http://semver.org/>). For the suffix, we allow things
136// like "a1" (alpha1), "b2" (beta2), "rc4" (release candidate 4), "a1.dev3"
137// (development release for "a1", which sorts before "a1"), etc. It's a subset
138// of the syntax allowed in <https://www.python.org/dev/peps/pep-0440/>.
139class AddonVersion : public SGReferenced
140{
141public:
142 AddonVersion(int major = 0, int minor = 0, int patchLevel = 0,
144 AddonVersion(const std::string& version);
145 AddonVersion(const char* version);
146 explicit AddonVersion(const std::tuple<int, int, int, AddonVersionSuffix>& t);
147
148 // Using the method names major() and minor() can lead to incomprehensible
149 // errors such as "major is not a member of flightgear::addons::AddonVersion"
150 // because of a hideous glibc bug[1]: major() and minor() are defined by
151 // standard headers as *macros*!
152 //
153 // [1] https://bugzilla.redhat.com/show_bug.cgi?id=130601
154 int majorNumber() const;
155 int minorNumber() const;
156 int patchLevel() const;
158 std::string suffixStr() const;
159
160 std::string str() const;
161
162 // For the Nasal bindings (otherwise, we have operator==(), etc.)
163 bool equal(const nasal::CallContext& ctx) const;
164 bool nonEqual(const nasal::CallContext& ctx) const;
165 bool lowerThan(const nasal::CallContext& ctx) const;
166 bool lowerThanOrEqual(const nasal::CallContext& ctx) const;
167 bool greaterThan(const nasal::CallContext& ctx) const;
168 bool greaterThanOrEqual(const nasal::CallContext& ctx) const;
169
170 static void setupGhost(nasal::Hash& addonsModule);
171
172private:
173 // Useful for comparisons/sorting purposes
174 std::tuple<int, int, int, AddonVersionSuffix> makeTuple() const;
175
176 static std::tuple<int, int, int, AddonVersionSuffix>
177 versionStringToTuple(const std::string& versionStr);
178
179 // Used to implement versionStringToTuple() for compilers that are not
180 // C++11-compliant (gcc 4.8 pretends to support <regex> as required by C++11
181 // but doesn't, see <https://stackoverflow.com/a/12665408/4756009>).
182 //
183 // The bool in the first component of the result is true iff 'versionStr' is
184 // a valid version string. The bool is false when 'versionStr' is invalid in
185 // such a way that the generic sg_format_exception thrown at the end of
186 // versionStringToTuple() is appropriate. In all other cases, a specific
187 // exception is thrown.
188 static std::tuple<bool, int, int, int, AddonVersionSuffix>
189 parseVersionString_noRegexp(const std::string& versionStr);
190
191 friend bool operator==(const AddonVersion& lhs, const AddonVersion& rhs);
192 friend bool operator<(const AddonVersion& lhs, const AddonVersion& rhs);
193
194 int _major;
195 int _minor;
196 int _patchLevel;
197 AddonVersionSuffix _suffix;
198};
199
200// operator==() and operator<() are declared above.
201bool operator!=(const AddonVersion& lhs, const AddonVersion& rhs);
202bool operator> (const AddonVersion& lhs, const AddonVersion& rhs);
203bool operator<=(const AddonVersion& lhs, const AddonVersion& rhs);
204bool operator>=(const AddonVersion& lhs, const AddonVersion& rhs);
205
206std::ostream& operator<<(std::ostream&, const AddonVersion&);
207
208} // of namespace addons
209
210} // of namespace flightgear
211
212#endif // of FG_ADDONVERSION_HXX
friend bool operator<(const AddonVersionSuffix &lhs, const AddonVersionSuffix &rhs)
AddonVersionSuffix(AddonVersionSuffixPrereleaseType _preReleaseType=AddonVersionSuffixPrereleaseType::none, int preReleaseNum=0, bool developmental=false, int devNum=0)
std::tuple< AddonVersionSuffixPrereleaseType, int, bool, int > makeTuple() const
friend bool operator==(const AddonVersionSuffix &lhs, const AddonVersionSuffix &rhs)
bool lowerThan(const nasal::CallContext &ctx) const
bool nonEqual(const nasal::CallContext &ctx) const
friend bool operator==(const AddonVersion &lhs, const AddonVersion &rhs)
bool equal(const nasal::CallContext &ctx) const
bool lowerThanOrEqual(const nasal::CallContext &ctx) const
AddonVersionSuffix suffix() const
static void setupGhost(nasal::Hash &addonsModule)
bool greaterThan(const nasal::CallContext &ctx) const
bool greaterThanOrEqual(const nasal::CallContext &ctx) const
friend bool operator<(const AddonVersion &lhs, const AddonVersion &rhs)
AddonVersion(int major=0, int minor=0, int patchLevel=0, AddonVersionSuffix suffix=AddonVersionSuffix())
bool operator>(const AddonVersionSuffix &lhs, const AddonVersionSuffix &rhs)
bool operator<=(const AddonVersionSuffix &lhs, const AddonVersionSuffix &rhs)
bool operator>=(const AddonVersionSuffix &lhs, const AddonVersionSuffix &rhs)
std::ostream & operator<<(std::ostream &os, const Addon &addon)
Definition Addon.cxx:509
bool operator!=(const AddonVersionSuffix &lhs, const AddonVersionSuffix &rhs)
FlightPlan.hxx - defines a full flight-plan object, including departure, cruise, arrival information ...
Definition Addon.cxx:53