Old 7th January 2005, 05:25   #1
Comperio
Major Dude
 
Comperio's Avatar
 
Join Date: Jan 2005
Location: Oregon Coast
Posts: 737
Lightbulb Comparing 2 versions

I was searching for a function that could compare 2 version numbers. I liked the example at http://nsis.sourceforge.net/archive/....php?page=643, but I did find a small flaw with this example in that it would see "3.1.0" and "3.10.0" as identical versions.

I was having a hard time stepping through the code, so I decided to write my own variation. I've tested every possible scenerio I could think of and could not make it fail. It will handle from 1 to up to 4 sections (ex: "1.2.3.4") as long as the version number string consists of strictly numbers (no letters).

The code is attached. It's easy to follow and contains much documentation, so it should be easy enough for anyone to follow the logic.

Any questions? Just let me know.
Enjoy!
Attached Files
File Type: zip vercomp.zip (1.3 KB, 136 views)

Last edited by Comperio; 7th January 2005 at 05:55.
Comperio is offline   Reply With Quote
Old 7th January 2005, 10:45   #2
kichik
M.I.A.
[NSIS Dev, Mod]
 
kichik's Avatar
 
Join Date: Oct 2001
Location: Israel
Posts: 11,343
Everyone can create Archive pages. You can go ahead and create one for this function too.

NSIS FAQ | NSIS Home Page | Donate $
"I hear and I forget. I see and I remember. I do and I understand." -- Confucius
kichik is offline   Reply With Quote
Old 7th January 2005, 13:05   #3
bluenet
Senior Member
 
Join Date: Mar 2004
Posts: 138
These is a VerCmp function rip from my NSIS Header File.
Use it like StrFunc.
Exsample: ${VerCmp} $0 1.0.10.3 1.0.1.9
In this case $0 = 1 (1.0.10.3 > 1.0.1.9)
${VerCmp} $0 1.0.1.15 1.0.2
This case $0 = -1 (1.0.1.15 < 1.0.2)
And return 0 if equal.
A litte difference with StrFunc: Uninstall function is ${un.VerCmp} not ${UnVerCmp}

PHP Code:
!macro DEFINE_FUNC NAME
    
!define `${NAME}` `!insertmacro INSERT_FUNC_${NAME} "${NAME}" ""`
    !
define `un.${NAME}` `!insertmacro INSERT_FUNC_${NAME} "${NAME}" "un."`
!
macroend

!macro DEFINE_CALL NAME UNFIX
    
!undef `${UNFIX}${NAME}`
    !
define `${UNFIX}${NAME}` `!insertmacro CALL_FUNC_${NAME} "${NAME}" "${UNFIX}"`
!
macroend

###############################################################
# º¯Êý: VerCmp
###############################################################
!insertmacro DEFINE_FUNC VerCmp

!macro CALL_FUNC_VerCmp NAME UNFIX ResultVar Ver1 Ver2
    Push 
`${Ver2}`
    
Push `${Ver1}`
    
Call ${UNFIX}${NAME}
    
Pop ${ResultVar}
!
macroend

!macro INSERT_FUNC_VerCmp NAME UNFIX
    
Function ${UNFIX}${NAME}
        
Exch $R0
        Exch
        Exch $R1
        Push $R2
        Push $R3
        
        
${Do}
            ${If} 
$R0 != ""
                
Push $R0
                Call 
${UNFIX}${NAME}.FindDot
                Pop $R0 
;µãºóÃæµÄ
                Pop $R2 
;µãÇ°ÃæµÄ
            
${Else}
                
StrCpy $R2 0
            
${EndIf}
            ${If} 
$R1 != ""
                
Push $R1
                Call 
${UNFIX}${NAME}.FindDot
                Pop $R1 
;µãºóÃæµÄ
                Pop $R3 
;µãÇ°ÃæµÄ
            
${Else}
                
StrCpy $R3 0
            
${EndIf}
            
            ${If} 
$R2 $R3
                StrCpy $R0 1
                
${ExitDo}
            ${ElseIf} 
$R2 $R3
                StrCpy $R0 
-1
                
${ExitDo}
            ${EndIf}
        
            ${If} 
$R0 == ""
            
${AndIf$R1 == ""
                
StrCpy $R0 0
                
${ExitDo}
            ${EndIf}
        ${
loop}
            
        
Pop $R3
        Pop $R2
        Pop $R1
        Exch $R0
    FunctionEnd
    
    
Function ${UNFIX}${NAME}.FindDot
        Exch $R0
        Push $R1
        Push $R2
        Push $R3
        StrCpy $R2 0
            
${Do}
                
StrCpy $R3 $R0 1 $R2
                
${If} $R3 == "."
                    
StrCpy $R1 $R0 $R2
                    IntOp $R2 $R2 
1
                    StrCpy $R0 $R0 
"" $R2
                    
${ExitDo}
                ${EndIf}
                ${If} 
$R3 == ""
                    
StrCpy $R1 $R0
                    StrCpy $R0 
""
                    
${ExitDo}
                ${EndIf}
                
IntOp $R2 $R2 1
            
${Loop}
        
Pop $R3
        Pop $R2
        Exch $R1
        Exch
        Exch $R0
    FunctionEnd

    
!insertmacro DEFINE_CALL `${NAME}` `${UNFIX}`
!
macroend 
bluenet is offline   Reply With Quote
Old 9th January 2005, 19:07   #4
Comperio
Major Dude
 
Comperio's Avatar
 
Join Date: Jan 2005
Location: Oregon Coast
Posts: 737
Thumbs up

I was not aware that I could post directly to the NSIS archive. (Very cool!)

I took kichik's advise and the code is now located at http://nsis.sourceforge.net/archive/...instances=0,11

I did do a little tweaking to add some POP commands to restore the contents of the stack.

(By the way, I think NSIS kicks butt!)
Comperio is offline   Reply With Quote
Old 10th January 2005, 08:14   #5
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
I have found the problem with my function. I shall fix it when I get home!

-Stu
Afrow UK is offline   Reply With Quote
Old 10th January 2005, 14:47   #6
stb
Senior Member
 
Join Date: Mar 2004
Location: Germany, Paderborn
Posts: 177
NSIS Archive contains another one:

http://nsis.sourceforge.net/archive/....php?pageid=57

Looks good to me.
stb is offline   Reply With Quote
Old 10th January 2005, 19:17   #7
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
That VersionCheck function fails on version numbers like 6 and 6.0 (it says 6 is lower than 6.0 when they are the same!)

-Stu
Afrow UK is offline   Reply With Quote
Old 10th January 2005, 21:14   #8
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
Ok, I finished the function. I re-wrote it taking a different approach from the old function...
Quote:
The previous function (VersionCheckNew) would strip the dot's, make the two numbers the same length (by adding leading 0's) then making both numbers proper integers by placing 1 in front of them.
This worked for a while until Comperio found that it would fail on e.g. 3.1.0 and 3.10.0
Here, the second version is obviously higher.
In the old function, 3.1.0 would become 13100 and 3.10.0 would become 13100. As you can see, both integers are exactly the same and thus the function would falsely report that both versions numbers are the same!
This function differs in that it compares each number between the dot's one by one, from start to finish.

There's another version string type that I never tried before... something like this:
1.01
1.10
This function doesn't break on that either.

http://nsis.sourceforge.net/archive/...ances=0,11,122

-Stu
Afrow UK is offline   Reply With Quote
Reply
Go Back   Winamp & Shoutcast Forums > Developer Center > NSIS Discussion

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump