[Development] Adding support for version number comparisons
André Somers
andre at familiesomers.nl
Wed May 14 15:10:07 CEST 2014
Keith Gardner schreef op 14-5-2014 14:28:
>
>
> I think that makes sense, but it would be nice if it would be easy
> for the user of the class to extend the version checking himself
> for non-numerical sections of the version string. That could be
> done in several ways I think, for instance with an API like this:
>
> QVersion
> {
> ...
> protected:
> virtual bool isNonNumericalSectionLessThan(int section,
> QStringRef sectionString) const;
> ...
> }
>
> The default implementation would simply return false and thus not
> try to do any sorting.
>
> That or another method to accomplish the same makes it easy to use
> the class for basic version numbers, while still be flexible
> enough for users to handle their own systems for pre and
> postfixes, right?
>
>
> Are you envisioning the overload to be passed as a parameter to the
> compare function or have it be stored as a static variable so it only
> needs to be set once?
Well, if you use a virtual, you'd simply subclass to handle the specific
format for your project. I would not use a static variable with a custom
compare function. What if an application has to handle more than one
version format?
>
> As for prefixes, I have not come across a project that reports its
> version with a prefix. If we were to support prefixes, I would say
> that there would have to be more restrictions on their format in order
> to support converting from a QString to a QVersion. The biggest
> restriction I can think of is to not support numbers in the prefix
> string to remove ambiguity. Also, if there are no numerical values,
> would the string be considered a prefix or suffix?
The way I look at a version number, is that it is a sequence of tokens
that are separated by some type of separator (space, dot, collon,
perhaps a change from a number to a non-number or the other way around;
whatever). What constitutes a separator between tokens should probably
be configurable, with some sane default.
Each of these tokens is compared seperately, and may or may not be
there. I'd suggest that a generic Qt solution only handles the case
where a token is purely numeric. If the token is not numeric, it is
either ignored or handed by an application specific handler (of which
the virtual function above would be an example). The order would not
really matter, IMHO. The non-numerical part may also be inbetween to
numerical parts, like in Qt "5.3.0 beta 2". In my approach, the tokens
to considder here would be 5, 3, 0, "beta", 2. The numerical ones should
be handled by QVersion, the "beta" would not and would by default be
ignored. So, by default, "5.3.0 rc 2" would compare equal to "5.3.0 beta
2".
If a token is not there, I think when comparing one should assume either
a 0 for a numerical token and an empty string for a non-numerical one.
So, Qt "5.3.0" would compare against "5.3.0 beta 2" as if it would have
been 5, 3, 0, "", 0. That would mean that the vanilla class would
compare QVersion("5.3.0") < QVersion("5.3.0 beta 2") due to the 2 being
bigger than the 0 and the "beta" being ignored. If you want to handle
this case properly, you'll have to subclass and make a version that
handles "beta", "alpha" and "rc", and makes "' compare as less than any
of these, so QtSpecificVersion("5.3.0") > QtSpecificVersion("5.3.0 beta
2"). A couple of well known, trivial versions may be provided perhaps.
An implementation of QtSpecificVersion would then perhaps look something
like this:
class QtSpecificVersion: public QVersion
{
//...
protected:
bool isNonNumericalSectionLessThan(int section, QStringRef
otherSectionString) const
{
if (section != 4) // we only expect "beta" or "rc" as the
fourth token
return false;
QStringRef thisSectionString = sectionString(section);
int value = valueForString(thisSectionString);
int otherValue = valueForString(otherSectionString);
return (otherValue < value);
}
private:
int valueForString(QStringRef string) const
{
if (string.isEmpty())
return 9;
if (string == "alpha")
return 1;
if (string == "beta")
return 2;
if (string == "rc")
return 3;
}
}
Anyone who has to deal with complex schemes where "aa" should compare as
bigger than "z" can go right ahead and reimplement
isNonNumericalSectionLessThan to their liking. I think may more people
will stick with a simpeler scheme that just uses something like "2.1.5".
If they don't want to subclass and still use beta, alpha or rc labels,
they could just include a build number into their version number and
have it always work fine: "2.1.5.1043 beta 1" compares fine by default
with "2.1.5.1051 rc 3" by default in such a system.
Anyway: just an idea to keep it simple yet usable IMHO. Feel free to
ignore ;-)
André
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/development/attachments/20140514/87bf5ac8/attachment.html>
More information about the Development
mailing list