## 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