[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: comparing version numbers
From: |
David Bateman |
Subject: |
Re: comparing version numbers |
Date: |
Fri, 24 Mar 2006 17:37:15 +0100 |
User-agent: |
Mozilla Thunderbird 1.0.6-7.5.20060mdk (X11/20050322) |
Soren Hauberg wrote:
>tor, 23 03 2006 kl. 23:34 +0100, skrev Soren Hauberg:
>
>
>>tor, 23 03 2006 kl. 17:22 -0500, skrev John W. Eaton:
>>
>>
>>>If there is a need to compare version numbers, then perhaps we should
>>>have a function to do it that can handle things like 2.9.5+ or
>>>2.9.5+SVN-serial-number (or similar).
>>>
>>>
>>There is a function for comparing version numbers in the package system I
>>sent you a while back. I don't think it supports anything else than numbers,
>>but it might provide a starting base. (I don't have the source in front
>>of me, so I can't say what should be changed)
>>
>>
>Okay, so I found the source and modified it a bit to make the function a bit
>more general than what was needed in the package system. The attached function
>supports version strings such as 2.9.5-Whatever.
>
>Two things should be noted:
> 1) It acts like strcmp in C, i.e it returns -1 if the first version
>string is "smaller" than the second, 0 if they are "equal", and 1
>otherwise. I say "equal" (and "smaller") because 2.6 == 2.6.0
> 2) The function doesn't work :-)
>I need to be able to compare strings like I can in C using strcmp. Is
>there an easy way to do this?
>
>
Why not use something like
text = !strcmp (text1, text2);
if (text)
texts = sort([text1;text2]);
if (strcmp(deblank(texts[1,:]),text1)
text = -1;
else
text = 1;
endif
endif
Though I believe you must be careful with the strsort function of
octave-forge which dispatches to sort. The fact is the 2.9.x sort
function treats strings correctly and strsort.m should probably
therefore be dropped.
D.
>/Soren
>
>
>------------------------------------------------------------------------
>
>## Copyright (C) 2006 Soren Hauberg
>##
>## This program is free software; you can redistribute it and/or modify
>## it under the terms of the GNU General Public License as published by
>## the Free Software Foundation; either version 2 of the License, or
>## (at your option) any later version.
>##
>## This program is distributed in the hope that it will be useful,
>## but WITHOUT ANY WARRANTY; without even the implied warranty of
>## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>## GNU General Public License for more details.
>##
>## You should have received a copy of the GNU General Public License
>## along with this program; if not, write to the Free Software
>## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
>
>## -*- texinfo -*-
>## @deftypefn {Function File} {} compare_version (@var{v1}, @var{v2})
>## Compares two version strings, returning 0 if they are equal, 1 if
>## @var{v1} is larger (i.e. more recent) than @var{v2}, and -1 otherwise.
>##
>## A version string is a string that describes the version of a piece of
>## software. This function supports the most common type of version strings
>## found in Free Software, i.e. "Major.Minor.Revision-Text". In this format
>## Minor, Revision and Text are optional, but for clarity it is recommended
>## to at least provide Minor and Revision. If Minor or Revision is not
>## given, they default to 0, while Text defaults to the empty string. Hence
>## the following is true,
>## @example
>## 2.6 == 2.6.0 < 2.6.0-SVN < 2.6.1
>## @end example
>## @end deftypefn
>
>function [ ret ] = compare_version (v1, v2)
> ## Both arguments must be strings
> if (!ischar(v1) || !ischar(v2))
> error("compare_version: Both input arguments must be strings.");
> endif
>
> ## Split the strings into parts X.Y.Z-TEXT
> [major1, minor1, rev1, text1] = get_parts(v1);
> [major2, minor2, rev2, text2] = get_parts(v2);
>
> ## Gentleman, start your comparing...
> major = sign(major1 - major2);
> minor = sign(minor1 - minor2);
> rev = sign(rev1 - rev2);
> text = !strcmp(text1, text2); % XXX: This is just plain wrong! (But it'll
> have to do for now!)
>
> if (major != 0)
> ret = major;
> elseif (minor != 0)
> ret = minor;
> elseif (rev != 0)
> ret = rev;
> else
> ret = text;
> endif
>endfunction
>
>## Splits a version string into Major.Minor.Revision-Text.
>## Minor and Revision defaults to 0 ,while Text defaults to the empty string.
>function [major, minor, revision, text] = get_parts(v)
> ## Default values
> minor = revision = 0;
> text = "";
>
> ## Get text
> dash = find(v == "-");
> if (length(dash) > 0)
> text = v(dash(1)+1:end);
> v = v(1:dash(1)-1);
> endif
>
> ## Get major, minor, and revision
> dots = [find(v == "."), length(v)+1];
> major = str2num( v(1:dots(1)-1) );
> if (length(dots) >= 2)
> minor = str2num( v( dots(1)+1:dots(2)-1 ) );
> endif
> if (length(dots) >= 3)
> revision = str2num( v( dots(2)+1:dots(3)-1 ) );
> endif
>
> ## Is everything okay?
> if ( isempty(major) || isempty(minor) || isempty(revision) )
> error("Input argument is not a valid version string.");
> endif
>endfunction
>
>%!test
>%! if (compare_version("2.6.1", "2.6.0") != 1)
>%! error("Test 1");
>%! endif
>
>%!test
>%! if (compare_version("2.6", "2.6.0") != 0)
>%! error("Test 2");
>%! endif
>
>%!test
>%! if (compare_version("2.6-SVN", "2.6.0") != 1)
>%! error("Test 3");
>%! endif
>
>## XXX: Is there a more easy way to test that a function returns an error?
>%!test
>%! test_failed = true;
>%! try
>%! compare_version("2.6.0", "Monkey");
>%! catch
>%! test_failed = false;
>%! end_try_catch
>%! if (test_failed)
>%! error("Test 4");
>%! endif
>
>%!test
>%! if (compare_version("2.6.0-SVN2", "2.6.0-SVN1"))
>%! error("Test 5");
>%! endif
>
>
--
David Bateman address@hidden
Motorola Labs - Paris +33 1 69 35 48 04 (Ph)
Parc Les Algorithmes, Commune de St Aubin +33 6 72 01 06 33 (Mob)
91193 Gif-Sur-Yvette FRANCE +33 1 69 35 77 01 (Fax)
The information contained in this communication has been classified as:
[x] General Business Information
[ ] Motorola Internal Use Only
[ ] Motorola Confidential Proprietary