Archive: VersionCompare result is 1


VersionCompare result is 1
Hi

In the VersionCompare help (http://nsis.sourceforge.net/VersionCompare) is the following sample:


${VersionCompare} "1.1.1.9" "1.1.1.01" $R0 ; $R0="1"


This is correct. But the following code results 1 too:

${VersionCompare} "1.1.1.1" "1.1.1.01" $R0 ; $R0="1"


This is not correct. VersionCompare must ignore zero values at the front of a version part. I think the following result was desirable:

${VersionCompare} "1.1.1.1" "1.1.1.01" $R0 ; $R0="0"


01 and 1 are the same number. Why should the comparison result be any different?


If they were the same then VersionCompare should return 0 not 1 as healy76 says? I personally don't think they are the same, but I'm not completely sure. I seem to remember when writing the function that this was based on, Instructor said that 01 is not the same as 1.

Stu


It is 'not' correct. 1 is the same as 01 but 1 is not the same as 01. *very_strange* :-)

@Afrow: For a C compiler is 010 an octal value and not a Integer. I think that is meaning by the Instructor. But here we have a Version number and not an single value. The devinition of a version is: integer dot integer [dot integer dot integer]. [] is not mandatory.

Other example: Whe you try to use a Microsoft .NET class to convert a string value to a version you can use a class named Version(). For this class the value "1.1.1" is the same as "1.01.01". This class ignore the leading zero's.

C#:
Version v1 = new Version("1.1.1");
MessageBox.Show( v1.ToString() ); // -> 1.1.1

Version v2 = new Version("1.01.01");
MessageBox.Show(v2.ToString()); // -> 1.1.1

Currently i replace the value ".0" with "." in my NSIS Script before i use the VersionCompare. It works fine but in future it was more user-friendly when the VersionCompare do this for me.

Ok thanks for the info. I'd contact Instructor by PM! So basically it depends which way around your arguments are for the call?

Stu


@Afrow: Sorry but i down't understand your last sentense/question.

So basically it depends which way around your arguments are for the call?

Do you get the same result for
${VersionCompare} "1.1.1.1" "1.1.1.01" $R0
and
${VersionCompare} "1.1.1.01" "1.1.1.1" $R0

Just so we know it is a bug and not by design.

Stu


Ah ok. I have test this in a little example. Here is the result:


${VersionCompare} "1.1.1.1" "1.1.1.01" $R0
Detailprint $R0 ;-> $R0="1"

${VersionCompare} "1.1.1.01" "1.1.1.1" $R0
Detailprint $R0 ;-> $R0="1"

${VersionCompare} "1.1.1.1" "1.1.1.01" $R0
Detailprint $R0 ;-> $R0="1"

${VersionCompare} "1.1.1.01" "1.1.1.1" $R0
Detailprint $R0 ;-> $R0="2"
It is by design.

Oh sorry. That's right. I have the value $R0="2" too. Likely a copy & past error of me. Sorry.

Of course you can say: "blue is equal to green". :-) But in the real world isn't it the same.

What is the reason behind this design? I subscribe to a view whith Microsoft. "01" or "001" is only a formating rule of version number and so not the same as "1".


I'm going to have to second the question of why this is by design; as far as I know, throughout school, in any programming language where you use decimals (which version numbers' individual parts are), and so forth on... leading zeroes can and should be ignored.

1.000000 is not the exact same as 1 if you're in a scientific field, but even there, 00000001 is the exact same as 1.

I understand that *some* programmers decide to go with a version number such as "4.2" and then release a minor update and not wanting to go to "4.3", they make it "4.25" instead; those programmers need to be hit over the head with a clue-by-four.

Right now it has potential for breaking version comparisons where it shouldn't.
For example, to check on the version of .NET Framework 3.0, I need to do the following (assume the second value is read from registry):
${VersionCompare} "3.0.04506.26" "3.0.04506.26" $1
This returns 0 as both are equal.

Personally I have a newer version installed:
${VersionCompare} "3.0.04506.26" "3.0.04506.30" $1
This returns 2, as the second is newer. All good.

But then along comes a pre-release:
${VersionCompare} "3.0.04506.26" "3.0.4506.21" $1
This returns 2; even though the second version - imho - is the lesser, not the greater, of the two.



; example:
; Push "1.2.3.4" ; versionnumber 1
; Push "1.2.4" ; versionnumber 2
; !insertmacro VersionCheck
; Pop $0
; Result is: "0" if equal, "1" if 1 is higher, "2" if 2 is higher
!macro CompareVersionnumbers
!define Index 'VersionCheck_Line${__LINE__}'
Exch $R0 ;second versionnumber
Exch
Exch $R1 ;first versionnumber
Push $R3 ;temp char
Push $R4 ;temp string for $R0
Push $R5 ;temp string for $R1
Push $R6 ;counter for $R0
Push $R7 ;counter for $R1
StrCpy $R6 "-1"
StrCpy $R7 "-1"
${Index}-Start:
StrCpy $R4 ""
${Index}-DotLoop0:
IntOp $R6 $R6 + 1
StrCpy $R3 "$R0" 1 $R6
StrCmp $R3 "" ${Index}-DotFound0
StrCmp $R3 "." ${Index}-DotFound0
StrCpy $R4 "$R4$R3"
Goto ${Index}-DotLoop0
${Index}-DotFound0:
StrCpy $R5 ""
${Index}-DotLoop1:
IntOp $R7 $R7 + 1
StrCpy $R3 "$R1" 1 $R7
StrCmp $R3 "" ${Index}-DotFound1
StrCmp $R3 "." ${Index}-DotFound1
StrCpy $R5 "$R5$R3"
Goto ${Index}-DotLoop1
${Index}-DotFound1:
StrCmp $R4 "" 0 ${Index}-4NotEmpty
StrCmp $R5 "" ${Index}-Equal
StrCpy $R4 "0"
${Index}-4NotEmpty:
StrCmp $R5 "" 0 ${Index}-CompareNumbers
StrCpy $R5 "0"
${Index}-CompareNumbers:
IntCmp $R4 $R5 ${Index}-Start ${Index}-Ver1More ${Index}-Ver2More
${Index}-Equal:
StrCpy $R0 "0"
Goto ${Index}-Finish
${Index}-Ver1More:
StrCpy $R0 "1"
Goto ${Index}-Finish
${Index}-Ver2More:
StrCpy $R0 "2"
${Index}-Finish:
Pop $R7
Pop $R6
Pop $R5
Pop $R4
Pop $R3
Pop $R1
Exch $R0
!undef Index
!macroend

Cool - might have to Function-ize it.. still beats what I had been doing, though (Strip Leading Zeroes - wiki, WordReplace'ing ".0" with "." (taking care to replace ".0." with a safeguard), then finally calling the existing versioncompare.