Sync from quickmods
This commit is contained in:
		| @@ -1,6 +1,8 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <QString> | ||||
| #include <QList> | ||||
|  | ||||
| #include "libutil_config.h" | ||||
|  | ||||
| class QUrl; | ||||
| @@ -10,10 +12,12 @@ namespace Util | ||||
| struct Version | ||||
| { | ||||
| 	Version(const QString &str); | ||||
| 	Version() {} | ||||
|  | ||||
| 	bool operator<(const Version &other) const; | ||||
| 	bool operator<=(const Version &other) const; | ||||
| 	bool operator>(const Version &other) const; | ||||
| 	bool operator>=(const Version &other) const; | ||||
| 	bool operator==(const Version &other) const; | ||||
| 	bool operator!=(const Version &other) const; | ||||
|  | ||||
| @@ -24,9 +28,34 @@ struct Version | ||||
|  | ||||
| private: | ||||
| 	QString m_string; | ||||
| 	struct Section | ||||
| 	{ | ||||
| 		explicit Section(const QString &str, const int num) : numValid(true), number(num), string(str) {} | ||||
| 		explicit Section(const QString &str) : numValid(false), string(str) {} | ||||
| 		explicit Section() {} | ||||
| 		bool numValid; | ||||
| 		int number; | ||||
| 		QString string; | ||||
|  | ||||
| 		inline bool operator!=(const Section &other) const | ||||
| 		{ | ||||
| 			return (numValid && other.numValid) ? (number != other.number) : (string != other.string); | ||||
| 		} | ||||
| 		inline bool operator<(const Section &other) const | ||||
| 		{ | ||||
| 			return (numValid && other.numValid) ? (number < other.number) : (string < other.string); | ||||
| 		} | ||||
| 		inline bool operator>(const Section &other) const | ||||
| 		{ | ||||
| 			return (numValid && other.numValid) ? (number > other.number) : (string > other.string); | ||||
| 		} | ||||
| 	}; | ||||
| 	QList<Section> m_sections; | ||||
|  | ||||
| 	void parse(); | ||||
| }; | ||||
|  | ||||
| LIBUTIL_EXPORT QUrl expandQMURL(const QString &in); | ||||
| LIBUTIL_EXPORT bool versionIsInInterval(const QString &version, const QString &interval); | ||||
| LIBUTIL_EXPORT bool versionIsInInterval(const Version &version, const QString &interval); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -7,42 +7,20 @@ | ||||
|  | ||||
| Util::Version::Version(const QString &str) : m_string(str) | ||||
| { | ||||
| 	parse(); | ||||
| } | ||||
|  | ||||
| bool Util::Version::operator<(const Version &other) const | ||||
| { | ||||
| 	QStringList parts1 = m_string.split('.'); | ||||
| 	QStringList parts2 = other.m_string.split('.'); | ||||
|  | ||||
| 	while (!parts1.isEmpty() && !parts2.isEmpty()) | ||||
| 	const int size = qMax(m_sections.size(), other.m_sections.size()); | ||||
| 	for (int i = 0; i < size; ++i) | ||||
| 	{ | ||||
| 		QString part1 = parts1.isEmpty() ? "0" : parts1.takeFirst(); | ||||
| 		QString part2 = parts2.isEmpty() ? "0" : parts2.takeFirst(); | ||||
| 		bool ok1 = false; | ||||
| 		bool ok2 = false; | ||||
| 		int int1 = part1.toInt(&ok1); | ||||
| 		int int2 = part2.toInt(&ok2); | ||||
| 		if (ok1 && ok2) | ||||
| 		const Section sec1 = (i >= m_sections.size()) ? Section("0", 0) : m_sections.at(i); | ||||
| 		const Section sec2 = | ||||
| 			(i >= other.m_sections.size()) ? Section("0", 0) : other.m_sections.at(i); | ||||
| 		if (sec1 != sec2) | ||||
| 		{ | ||||
| 			if (int1 == int2) | ||||
| 			{ | ||||
| 				continue; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				return int1 < int2; | ||||
| 			} | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			if (part1 == part2) | ||||
| 			{ | ||||
| 				continue; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				return part1 < part2; | ||||
| 			} | ||||
| 			return sec1 < sec2; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @@ -54,77 +32,35 @@ bool Util::Version::operator<=(const Util::Version &other) const | ||||
| } | ||||
| bool Util::Version::operator>(const Version &other) const | ||||
| { | ||||
| 	QStringList parts1 = m_string.split('.'); | ||||
| 	QStringList parts2 = other.m_string.split('.'); | ||||
|  | ||||
| 	while (!parts1.isEmpty() && !parts2.isEmpty()) | ||||
| 	const int size = qMax(m_sections.size(), other.m_sections.size()); | ||||
| 	for (int i = 0; i < size; ++i) | ||||
| 	{ | ||||
| 		QString part1 = parts1.isEmpty() ? "0" : parts1.takeFirst(); | ||||
| 		QString part2 = parts2.isEmpty() ? "0" : parts2.takeFirst(); | ||||
| 		bool ok1 = false; | ||||
| 		bool ok2 = false; | ||||
| 		int int1 = part1.toInt(&ok1); | ||||
| 		int int2 = part2.toInt(&ok2); | ||||
| 		if (ok1 && ok2) | ||||
| 		const Section sec1 = (i >= m_sections.size()) ? Section("0", 0) : m_sections.at(i); | ||||
| 		const Section sec2 = | ||||
| 			(i >= other.m_sections.size()) ? Section("0", 0) : other.m_sections.at(i); | ||||
| 		if (sec1 != sec2) | ||||
| 		{ | ||||
| 			if (int1 == int2) | ||||
| 			{ | ||||
| 				continue; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				return int1 > int2; | ||||
| 			} | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			if (part1 == part2) | ||||
| 			{ | ||||
| 				continue; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				return part1 > part2; | ||||
| 			} | ||||
| 			return sec1 > sec2; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return false; | ||||
| } | ||||
| bool Util::Version::operator>=(const Version &other) const | ||||
| { | ||||
| 	return *this > other || *this == other; | ||||
| } | ||||
| bool Util::Version::operator==(const Version &other) const | ||||
| { | ||||
| 	QStringList parts1 = m_string.split('.'); | ||||
| 	QStringList parts2 = other.m_string.split('.'); | ||||
|  | ||||
| 	while (!parts1.isEmpty() && !parts2.isEmpty()) | ||||
| 	const int size = qMax(m_sections.size(), other.m_sections.size()); | ||||
| 	for (int i = 0; i < size; ++i) | ||||
| 	{ | ||||
| 		QString part1 = parts1.isEmpty() ? "0" : parts1.takeFirst(); | ||||
| 		QString part2 = parts2.isEmpty() ? "0" : parts2.takeFirst(); | ||||
| 		bool ok1 = false; | ||||
| 		bool ok2 = false; | ||||
| 		int int1 = part1.toInt(&ok1); | ||||
| 		int int2 = part2.toInt(&ok2); | ||||
| 		if (ok1 && ok2) | ||||
| 		const Section sec1 = (i >= m_sections.size()) ? Section("0", 0) : m_sections.at(i); | ||||
| 		const Section sec2 = | ||||
| 			(i >= other.m_sections.size()) ? Section("0", 0) : other.m_sections.at(i); | ||||
| 		if (sec1 != sec2) | ||||
| 		{ | ||||
| 			if (int1 == int2) | ||||
| 			{ | ||||
| 				continue; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				return false; | ||||
| 			} | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			if (part1 == part2) | ||||
| 			{ | ||||
| 				continue; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				return false; | ||||
| 			} | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @@ -135,45 +71,41 @@ bool Util::Version::operator!=(const Version &other) const | ||||
| 	return !operator==(other); | ||||
| } | ||||
|  | ||||
| QUrl Util::expandQMURL(const QString &in) | ||||
| void Util::Version::parse() | ||||
| { | ||||
| 	QUrl inUrl(in); | ||||
| 	if (inUrl.scheme() == "github") | ||||
| 	m_sections.clear(); | ||||
|  | ||||
| 	QStringList parts = m_string.split('.'); | ||||
|  | ||||
| 	for (const auto part : parts) | ||||
| 	{ | ||||
| 		// needed because QUrl makes the host all lower cases | ||||
| 		const QString repo = in.mid(in.indexOf(inUrl.host(), 0, Qt::CaseInsensitive), inUrl.host().size()); | ||||
| 		QUrl out; | ||||
| 		out.setScheme("https"); | ||||
| 		out.setHost("raw.github.com"); | ||||
| 		out.setPath(QString("/%1/%2/%3%4") | ||||
| 						.arg(inUrl.userInfo(), repo, | ||||
| 							 inUrl.fragment().isEmpty() ? "master" : inUrl.fragment(), inUrl.path())); | ||||
| 		return out; | ||||
| 	} | ||||
| 	else if (inUrl.scheme() == "mcf") | ||||
| 	{ | ||||
| 		QUrl out; | ||||
| 		out.setScheme("http"); | ||||
| 		out.setHost("www.minecraftforum.net"); | ||||
| 		out.setPath(QString("/topic/%1-").arg(inUrl.path())); | ||||
| 		return out; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		return in; | ||||
| 		bool ok = false; | ||||
| 		int num = part.toInt(&ok); | ||||
| 		if (ok) | ||||
| 		{ | ||||
| 			m_sections.append(Section(part, num)); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			m_sections.append(Section(part)); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| bool Util::versionIsInInterval(const QString &version, const QString &interval) | ||||
| { | ||||
| 	if (interval.isEmpty() || version == interval) | ||||
| 	return versionIsInInterval(Util::Version(version), interval); | ||||
| } | ||||
| bool Util::versionIsInInterval(const Version &version, const QString &interval) | ||||
| { | ||||
| 	if (interval.isEmpty() || version.toString() == interval) | ||||
| 	{ | ||||
| 		return true; | ||||
| 	} | ||||
|  | ||||
| 	// Interval notation is used | ||||
| 	QRegularExpression exp( | ||||
| 		"(?<start>[\\[\\]\\(\\)])(?<bottom>.*?)(,(?<top>.*?))?(?<end>[\\[\\]\\(\\)])"); | ||||
| 		"(?<start>[\\[\\]\\(\\)])(?<bottom>.*?)(,(?<top>.*?))?(?<end>[\\[\\]\\(\\)]),?"); | ||||
| 	QRegularExpressionMatch match = exp.match(interval); | ||||
| 	if (match.hasMatch()) | ||||
| 	{ | ||||
| @@ -185,11 +117,12 @@ bool Util::versionIsInInterval(const QString &version, const QString &interval) | ||||
| 		// check if in range (bottom) | ||||
| 		if (!bottom.isEmpty()) | ||||
| 		{ | ||||
| 			if ((start == '[') && !(version >= bottom)) | ||||
| 			const auto bottomVersion = Util::Version(bottom); | ||||
| 			if ((start == '[') && !(version >= bottomVersion)) | ||||
| 			{ | ||||
| 				return false; | ||||
| 			} | ||||
| 			else if ((start == '(') && !(version > bottom)) | ||||
| 			else if ((start == '(') && !(version > bottomVersion)) | ||||
| 			{ | ||||
| 				return false; | ||||
| 			} | ||||
| @@ -198,11 +131,12 @@ bool Util::versionIsInInterval(const QString &version, const QString &interval) | ||||
| 		// check if in range (top) | ||||
| 		if (!top.isEmpty()) | ||||
| 		{ | ||||
| 			if ((end == ']') && !(version <= top)) | ||||
| 			const auto topVersion = Util::Version(top); | ||||
| 			if ((end == ']') && !(version <= topVersion)) | ||||
| 			{ | ||||
| 				return false; | ||||
| 			} | ||||
| 			else if ((end == ')') && !(version < top)) | ||||
| 			else if ((end == ')') && !(version < topVersion)) | ||||
| 			{ | ||||
| 				return false; | ||||
| 			} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Petr Mrázek
					Petr Mrázek